Subject: Re: [Fwd: Threading questions, very detailed.] - DN [1]
Brent Welch <welch@ajubasolutions.com> - 11 Jul 2000 - comp.lang.tcl
>>>Jeffrey Hobbs said:
> You might want to answer this...
I'll put my two cents in and cc' Jim Davidson at AOL, my thread guru.
I'd slam in a mutex and not worry about it. I worry that the alternative is too
complex. As soon as you start doing double-checking of pointers, etc. etc. you
are eating away at the small savings of not using a mutex. If the data
is heavily shared and the mutex becomes a bottleneck, then you make copies
(caches)
in thread-local storage. At that point you have to deal with cache
management during updates, which also costs in complexity, so only do it
if you really measure a bottleneck.
> -------- Original Message --------
> Subject: Threading questions, very detailed.
> Date: Fri, 07 Jul 2000 11:26:37 +0100
> From: Paul Duffin <pduffin@hursley.ibm.com>
> Reply-To: pduffin@hursley.ibm.com
> Organization: IBM UK Laboratories Ltd.
> Newsgroups: comp.lang.tcl
>
> What is the overhead of getting an uncontested mutex say compared to getting
> some thread data ?
>
> Are pointer assignments atomic, if one thread is writing to a pointer and on
e
> thread is reading from a pointer is there anyway that the two can get
> interleaved in such a way that the reader ends up with an invalid pointer ?
>
> The reason that I am asking this is that I have a dynamic array, consisting
of
> a length and a pointer which can be expanded by one thread while another
> thread is reading it. It is protected against multiple writers by a mutex
> because writing is a very infrequent operation but reading is very frequent.
> e.g.
>
> typedef struct DynArray {
> VOID **contents; /* This probably needs to be volatile
> * to prevent the compiler caching the
> * the result. */
> int length;
> };
>
> The writer is using.
>
> void expand (DynArray *array, int newlength)
> {
> VOID *newcontents = alloc (newlength);
> VOID *oldcontents = array->contents;
> memcpy (newcontents, oldcontents, array->length);
> array->contents = newcontents;
> array->length = newlength;
> free (oldcontents);
> }
>
> The reader is using.
>
> ptr = array->contents [index]
>
> which is not atomic and breaks down into.
>
> contents = array->contents;
> ptr = contents [index];
>
> Once the reader has the ptr it is safe as the structure it refers to will
> not be deleted and the fields of the structure which it uses are
> not changed.
>
> The problem is that if the writer deletes the array contents after the
> reader has read the contents pointer but before it has read the pointer
> out of the array then it may fail.
>
> I could fix this by using a mutex, making the array static, or using
> per thread data but I don't really want to do any of them.
>
> The writing will mostly (not always) happen at initialisation and
> termination and the reading will happen the rest of the time so the
> chances of collision are small but I don't want to introduce some
> really intermittent bug.
>
> I did think that I could change the expand function so that rather then
> free up the old contents immediately it simply stores it in a backup
> pointer in the structure to be freed later. This would further reduce
> the chances of collision by increasing the amount of time that the
> reader has to index the array.
>
> Additionally as the memory for the array may still be readable (so I would
> not get a segmentation fault) I could check that the contents pointer was
> still the same after I read the ptr and if it was not try again.
>
> Am I being too paranoid, is there anything I have overlooked about this,
> such as an easier solution ?
-- Brent Welch <welch@ajubasolutions.com>
http://www.ajubasolutions.com
Scriptics changes to Ajuba Solutions
scriptics.com => ajubasolutions.com
Last modified
2000-07-20
2000-07-20
(195.108.246.52)
Note: you are looking at
the snapshot of an old wiki
- much of this information
is likely to be very outdated
