tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Improved implementation of *env(3) functions in "libc"

On 19 Nov 2010, at 01:56 , Matthias Scheler wrote:
> On Thu, Nov 18, 2010 at 04:36:44PM +0000, Andrew Doran wrote:
>> A simple unsorted array can be an interesting basis for doing things
>> locklessly provided you constrain some of its properties. :-)
> Yes, it could. But unfortunately the array can also be change location
> if we have to grow it in the middle of a call to setenv(3). And that
> would cause massive problem if another thread is currently examing
> the array in getenv_r(3).

Even that isn't a big problem.  The array itself is pointed to by
a single pointer, environ.  Declare that volatile.  When you need
to grow the array allocate memory for the new array, fill it
in including the change you are making, call membar_producer(),
then write environ to point at the new array.  If you then change
getenv_r() to do a

    my_environ = environ;

at the start and then replace all subsequent references to environ
with references to my_environ, getenv_r() will do all its work on
either the old, unchanged array or the new, changed array and all
is well as long as you keep the old array around until all readers
are done with it.

The complexity with lockless reader data structures is seldom the data
structure itself, it is that last bit: figuring out when all concurrent
readers are done with the old data structure so you can free it.  This
can take a long time if the thread reading it is interrupted in the
middle of the operation and scheduled out.  Given this complexity and the
fact that we're talking about getenv(), which is extremely unlikely to be
a big CPU consumer for anyone, I think the r/w lock is perfectly
appropriate in this case.

Dennis Ferguson

Home | Main Index | Thread Index | Old Index