From: Mark Hobley on 15 Apr 2010 16:34 I have some data structures that I want to protect using a mutex for the purpose of making thread safe code. Is it ok, to include the mutex datatype within the data structure that I wish to protect? For example: struct buffertable { struct buffer *addr; int sz; unsigned int currentdefault; unsigned int chunksize; unsigned int tablechunk; pthread_mutex_t buffertablemx; <--- Can I put the mutex here? }; extern struct buffertable buffertable; In the above case I want to protect the values of the buffertable using the buffertablemx mutex. Can I also protect dynamically created structured arrays by having a mutex as part of the array definition? struct buffer { char *addr; unsigned int sz; unsigned int ptr; unsigned int tail; pthread_mutex_t buffermx; <--- Can I put the mutex here? }; buffertable.addr = malloc(tablesize * sizeof(struct buffer)); ^ | I plan to have a mutex for dynamically allocated structures. This will enable me to apply a mutex to just one particular element of the array without affecting other elements. In this case, it is convenient to be able to bundle the mutex record in with the data structure, because sometimes the tablesize will be increased via a realloc call, and this would mean that new mutexes are required to work with the new elements. I am using C89, if that matters. -- Mark Hobley Linux User: #370818 http://markhobley.yi.org/
From: Rainer Weikusat on 15 Apr 2010 17:16 markhobley(a)hotpop.donottypethisbit.com (Mark Hobley) writes: > I have some data structures that I want to protect using a mutex for the > purpose of making thread safe code. > > Is it ok, to include the mutex datatype within the data structure that I wish > to protect? For example: > > struct buffertable { > struct buffer *addr; > int sz; > unsigned int currentdefault; > unsigned int chunksize; > unsigned int tablechunk; > pthread_mutex_t buffertablemx; <--- Can I put the mutex here? > }; Eh ... "why not"?
From: Eric Sosman on 15 Apr 2010 17:42 On 4/15/2010 4:34 PM, Mark Hobley wrote: > I have some data structures that I want to protect using a mutex for the > purpose of making thread safe code. > > Is it ok, to include the mutex datatype within the data structure that I wish > to protect? For example: > > struct buffertable { > struct buffer *addr; > int sz; > unsigned int currentdefault; > unsigned int chunksize; > unsigned int tablechunk; > pthread_mutex_t buffertablemx;<--- Can I put the mutex here? > }; > > extern struct buffertable buffertable; > > In the above case I want to protect the values of the buffertable using the > buffertablemx mutex. > > Can I also protect dynamically created structured arrays by having a mutex > as part of the array definition? > > struct buffer { > char *addr; > unsigned int sz; > unsigned int ptr; > unsigned int tail; > pthread_mutex_t buffermx;<--- Can I put the mutex here? > }; Sure. Good place for it, I'd say. > buffertable.addr = malloc(tablesize * sizeof(struct buffer)); > ^ > | > I plan to have a mutex for dynamically allocated structures. This will enable > me to apply a mutex to just one particular element of the array without > affecting other elements. In this case, it is convenient to be able to bundle > the mutex record in with the data structure, because sometimes the tablesize > will be increased via a realloc call, and this would mean that new mutexes > are required to work with the new elements. No, don't do that. If realloc() relocates the memory area by copying its contents, you'll wind up with copies of the original mutexes. Copying a mutex doesn't give you a usable mutex, but a piece of useless junk. Also, any thread that now tries to lock or unlock a mutex in the freed area is in deep trouble ... To make it work, you would need to do something awful like - make sure all the mutexes in the region are unlocked, and that no other thread will try to lock any of them, - pthread_mutex_destroy() all the mutexes, - realloc(), - pthread_mutex_init() all the mutexes in the region (and any new ones, too), - allow the rest of the program to start using the newly- initialized mutexes. So: If you must move your data structures around in memory, don't put mutexes (or semaphores, or condition variables) in them even though that would ordinarily be a good spot. Personally, I'd take a second look at why you want to move things around; maybe it's not really necessary. -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Jens Thoms Toerring on 15 Apr 2010 17:54 In comp.unix.programmer Mark Hobley <markhobley(a)hotpop.donottypethisbit.com> wrote: > I have some data structures that I want to protect using a mutex for the > purpose of making thread safe code. > Is it ok, to include the mutex datatype within the data structure that I wish > to protect? For example: > struct buffertable { > struct buffer *addr; > int sz; > unsigned int currentdefault; > unsigned int chunksize; > unsigned int tablechunk; > pthread_mutex_t buffertablemx; <--- Can I put the mutex here? > }; That's completely legal. 'pthread_mutex_t' is just another type, just with a fancy name. You can put basically everything into a structure that the compiler can figure out how much space (and what alignment) it needs. > extern struct buffertable buffertable; > In the above case I want to protect the values of the buffertable using the > buffertablemx mutex. > Can I also protect dynamically created structured arrays by having a mutex > as part of the array definition? > struct buffer { > char *addr; > unsigned int sz; > unsigned int ptr; > unsigned int tail; > pthread_mutex_t buffermx; <--- Can I put the mutex here? > }; > buffertable.addr = malloc(tablesize * sizeof(struct buffer)); > ^ > | > I plan to have a mutex for dynamically allocated structures. This > will enable me to apply a mutex to just one particular element of > the array without affecting other elements. In this case, it is > convenient to be able to bundle the mutex record in with the data > structure, because sometimes the tablesize will be increased via a > realloc call, and this would mean that new mutexes are required to > work with the new elements. Also that is legal - if you can put a 'pthread_mutex_t' in a structure you can put it into an array of structures, be it allocated statically or dynamically. What I don't like is your lying to the compiler about the type the 'addr' member is obviously going to point to. What keeps you from using the real type, i.e 'struct buffer *', as the type of the 'addr' member? Using a 'char *' (or 'void *' which would look a bit more natural since at least shows it's not about a char array but some opaque data type) only will force you to use ugly casts all over the place. It's completely ok to write struct buffer { struct buffer *addr; unsigned int sz; unsigned int ptr; unsigned int tail; pthread_mutex_t buffermx; <--- Can I put the mutex here? }; The compiler sees that enough room for a pointer to astructure is required, the exact layout of the structure pointed to is not needed at this point. And then you also could write buffertable.addr = malloc(tablesize * sizeof *buffertable.addr); which avoids having to rewrite anything here if you decide to change the name of 'struct buffer' sometime later. > I am using C89, if that matters. Not really. Regards, Jens -- \ Jens Thoms Toerring ___ jt(a)toerring.de \__________________________ http://toerring.de
From: Jens Thoms Toerring on 15 Apr 2010 17:59
In comp.os.linux.development.apps Jens Thoms Toerring <jt(a)toerring.de> wrote: > In comp.unix.programmer Mark Hobley <markhobley(a)hotpop.donottypethisbit.com> wrote: > > Can I also protect dynamically created structured arrays by having a mutex > > as part of the array definition? > > struct buffer { > > char *addr; > > unsigned int sz; > > unsigned int ptr; > > unsigned int tail; > > pthread_mutex_t buffermx; <--- Can I put the mutex here? > > }; > > buffertable.addr = malloc(tablesize * sizeof(struct buffer)); > > ^ > > | > > I plan to have a mutex for dynamically allocated structures. This > > will enable me to apply a mutex to just one particular element of > > the array without affecting other elements. In this case, it is > > convenient to be able to bundle the mutex record in with the data > > structure, because sometimes the tablesize will be increased via a > > realloc call, and this would mean that new mutexes are required to > > work with the new elements. > Also that is legal - if you can put a 'pthread_mutex_t' in a > structure you can put it into an array of structures, be it > allocated statically or dynamically. Please don't listen to me but to Eric Sosman, I missed the bit with the reallocation and only considered a dynamically allo- cated array of such structures! Regards, Jens -- \ Jens Thoms Toerring ___ jt(a)toerring.de \__________________________ http://toerring.de |