svn commit: r214915 - user/davidxu/libthr/lib/libthr/thread

David Xu davidxu at freebsd.org
Sun Nov 14 06:18:55 UTC 2010


Jilles Tjoelker wrote:
> On Sun, Nov 07, 2010 at 01:49:08PM +0000, David Xu wrote:
>   
>> Author: davidxu
>> Date: Sun Nov  7 13:49:08 2010
>> New Revision: 214915
>> URL: http://svn.freebsd.org/changeset/base/214915
>>     
>
>   
>> Log:
>>   Implement robust mutex, the pthread_mutex locking and
>>   unlocking code are reworked to support robust mutex and
>>   other mutex must be locked and unlocked by kernel.
>>     
>
> The glibc+linux implementation avoids the system call for each robust
> mutex lock/unlock by maintaining the list in userland and providing a
> pointer to the kernel. Although this is somewhat less reliable in case a
> process scribbles over this list, it has better performance.
>
> There are various ways this list could be maintained, but the glibc way
> uses an "in progress" field per thread and a linked list using a field
> in the pthread_mutex_t, so if we want that we should make sure we have
> the space in the pthread_mutex_t. Alternatively, a simple array could be
> used if the number of owned robust mutexes can be limited to a fairly
> low value.
>
> Solaris robust mutexes used to work by entering the kernel for every
> lock/unlock, but no longer, see
> http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6296770
> Someone complained about that implementation being too slow.
>
>   
I don't like the glibc's idea that reading or writing the mutex after 
unlocked it,
why do you think the memory is still valid and being used for the mutex
after you unlocked it?

There is a use-case that glibc will mysteriously fail:
Thread  A at userland unlocked the mutex, then another thread B at
userland locked it, and thread B reuses the memory area for other purpose,
before thread A enters kernel, thread B used it for memory-mapped file 
buffer,
than write some data into the buffer which will be saved into disk file
by kernel, but before A runs, the memory happens to contains thread A's
thread id, then the thread A enters kernel, and thinks the userland
still hasn't unlocked the mutex, and it tries to write some data into mutex,
it thinks it unlocked it, but the memory is no longer for mutex now, it just
simply corrupted the data thread B saved. This implementation is racy and
dangerous.

I also know that they have link-entry embedded in mutex,
if the mutex is being shared by multiple processes,then I can write a
specific value into the link entry and corrupt the owner's link list,
even worse, I can write a specific address into the link entry, when
the owner unlocks it and unlinks it from its list, he will be happy to
write to any address I specified,  this may be a security problem
or causes very difficult debugging problem if the mutex memory
is corrupted.

I think if you want robust mutex, //for whatever you do, there is a price,
the robust mutex is expensive but reliable. Until you can prove that
the glibc's write-mutex-memory-after-unlock is  not a problem,
I would not follow their idea. Based on the research, I think
Solaris must have a reason to not do it in this way, I would not laugh
at them that their robust mutex is slow.





More information about the svn-src-user mailing list