mutex and spinlock problem in shared memory

Hallo all,

i am developing a resource manager application, and i use a shared memory also between the resource manager and the clients.

I want to use either mutex or spinlock for my shared memory, but somehow it always fails.

I initialize my mutex with the following code:

  /* init the shared memory spinlock */
  ret = pthread_mutexattr_init(&(p_shrd_mem->mutexattr));
  ret = pthread_mutexattr_setpshared(&(p_shrd_mem->mutexattr), PTHREAD_PROCESS_SHARED );
  ret = pthread_mutex_init(&(p_shrd_mem->mutex), 
                           &(p_shrd_mem->mutexattr));

note that both mutexattr and mutex variable lie in the shared memory area.

but then as i want to lock the mutex:

  ret = pthread_mutex_lock(&(p_shrd_mem->mutex));

it always fails. i can not even debug it, on debugging the system completely stops, and i cant see the return value of the function.

the locking function don’t work either from server (resource manager) and client process, even tough both has already succesfully mmap the shared memory in their virtual memory

so does anyone have an idea what is the mistake i’ve made?

thanks,

You may have missed the steps where you actually create the mutex in shared memory with shm_open/shm_ctl/mmap.

Hi,

thanks for the reply. I have indeed created the shared memory. So i use for example the following data structure for my shared memory:

typedef struct
{
  uint32_t   data1;
  uint32_t   data2;
  uint32_t   data3;
  ...........
  pthread_mutex_t     daq_mem_mutex;     /* shared memory mutex */
  pthread_mutexattr_t daq_mem_mutexattr; /* attribute of shared memory mutex */
} t_MyShrdMem;

then i cast the pointer i get from the mmap function to this data type:

t_MyShrdMem * p_shrd_mem;
p_shrd_mem  = (t_MyShrdMem*) mmap(......)

can i basically do this?

thanks

Hi all,

i found the reason for this problem.

in my header file where i put the data structure, i use:


#pragma pack(push, 1) 
......
#pragma pack(pop) 

to pack my structure,

then actually my structure look like this:

typedef struct
{
  uint32_t   data1;

  uint16_t   value1;
  uint16_t   value2;
  uint16_t   value3;

  pthread_mutex_t       mutex;     /* shared memory mutex */
  pthread_mutexattr_t  mutexattr; /* attribute of shared memory mutex */
} t_MyShrdMem; 

so the mutex variable may start in an address which is not 4 byte alligned.
i solved the problem by either putting a 16 bit dummy variable between the value3 and mutex, or declare the structure in other header file without this pragma.

but last question is: which is more time consumable in QNX? a mutex or a spinlock? because i think in QNX the spinlock is also made up from mutex, then for time processing consideration, mutex is preferred, isnt?

thanks,

A spin lock is (as the name implies) a simple spin on the contents of a memory address. It is not intended to be used for any application where the lock is expect to be held for more than a handful of CPU cycles.

So the bottom line is, you are probably right that you should use a mutex, but not because a spin lock is composed of a mutex (it isn’t), but because holding a spin lock for any appreciable length of time is very bad for overall system performance.

Hey Rennie, I didn’t answer this one cause I wasn’t sure what was the right answer.

At first I said to myself hey spinlock are for interrupts only, so I checked the doc cause that didn’t seem to be what the OP was talking about. There are two “type” of spinlock, first one is type used by InterruptLock (that’s what first came to mind), and then there is the pthread stuff that got me all confuse. I read the doc and I couldn’t see any difference between mutex and these spinlock. In the caveat section it is mention that spinlock uses mutex.

Do you think the OP was referring to pthread_spinlock()? I didn’t see any mention of pthread_spinlock. The pthread_spinlock doc has a big warning in it that says “pthread_spinlock is not a spinlock”, I thought the OP was talking about real spinlocks :slight_smile:

Hi,

yes i was referring actually to the pthread_spinlock() :slight_smile:
because as i tried to debug it, it shows that i calls the phtread_mutex() functions too. So which one is better to be used for performance? pthread_mutex() or pthread_spinlock()?

i am a really beginner in QNX actually. then what is actually the “real” spinlock in QNX?

Lbdgwgt,

A “real” spinlock looks like from a coding standpoint as:

int a = 1;
while (a)
{
}

In other words an infinite loop until a is 0 (another thread/process is meant to change the a value). Of course it’s not a variable you spin lock on but a mutex.

As you can guess, this chews up 100% of the CPU so that anything running at a lower priority is starved out. Even same priority processes/threads can be starved too depending on which scheduling algorithms you are using.

This is why it’s not recommended.

Tim

But the QNX pthread_spin are not implemented like that, they are based on mutexes.

pthread_spinlock is kind of useless, as it is neither a spinlock nor a mutex. It is there because Posix says it should be there, and it allows the latitude to implement it as a useless function (i.e. someone on the posix committee really wanted it, everyone else thought it was stupid, and they agreed to include it to placate the hold-out as long as it had no defined behavior).

Spinlocks are far too machine dependent (think of all the variant of SMP or NUMA systems) to pretend that they are simple enough to have a pair of posix calls for.