Walter is right about transitive readonly - here's the alternative
Sean Kelly
sean at f4.ca
Thu Sep 13 13:53:27 PDT 2007
Janice Caron wrote:
> On 9/13/07, Steven Schveighoffer <schveiguy at yahoo.com> wrote:
>>> My C++ implementation used an atomic counter for read locks, an atomic
>>> counter for (pending) write locks, and an OS mutex.
>> Using atomic counters, how do you read the write counter, then increment the
>> read counter atomically without using the mutex?
>
> You don't have to make the entire process atomic, just the increments
> and decrements.
>
> getWriteLock()
> {
> atomicIncrement(wcount);
> obtainMutex();
> }
>
> releaseWriteLock()
> {
> releaseMutex();
> atomicDecrement(wcount);
> }
>
> getReadLock()
> {
> while (wcount != 0)
> {
> obtainMutex();
> releaseMutex();
> }
> if (atomicIncrement(rcount) == 1)
> {
> obtainMutex();
> }
> }
>
> releaseReadLock()
> {
> if (atomicDecrement(rcount) == 0)
> {
> releaseMutex();
> }
> }
>
> I think that's right. That's from memory. If it's wrong, I can't check
> until tomorrow. It looks right to me though.
To pick a nit, I think the above code may have some problems.
Scenario 1:
* Thread A acquires a write lock, mutates the protected data, and
releases the lock.
* Thread B acquires a read lock and stalls.
* Thread C acquires a read lock.
Here, because wcount is 0, thread C will never call obtainMutex and
therefore may view bad data.
Scenario 2:
* Thread A acquires a read lock and stalls.
* Thread B attempts to acquire a write lock, increments wcount, and
blocks on obtainMutex.
* Thread C attempts to acquire a read lock, sees wcount is nonzero and
blocks on obtainMutex.
Here, thread C should be allowed to proceed and read the protected
data but blocks instead.
There may be others as well, but I think the above is sufficient to
illustrate that multithreaded programming at the typical level (manual
locking, etc) is really quite difficult and therefore probably not an
ideal goal for future language development. I'll admit I do like the
idea of a programmer declaring intent to read/write data, but I do
wonder if additional integrated locking is the best way to go about
solving this particular issue. Perhaps the basic concept could be
applied another way?
Sean
More information about the Digitalmars-d
mailing list