From: Mark Hobley on
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
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
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
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
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