|
Boost : |
From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2004-07-19 04:33:10
< This is a "reply" to a couple of "off-band" emails >
Alexander Terekhov wrote:
[...]
> > Note that this illustration/example doesn't provide "posix safety"
> > with respect to mutex destruction if you use try/timed operations
> ^^^^^^^^^^^^^^^^^^^^
>
> Err. This CAS/TID-less thing is not safe at all with respect to
> "posix safety" for mutex destruction.
It can be made safe. The simplest way is to "pimpl" it and never
destroy the "impl" thing (reusing it is OK). Other (more space
and performance efficient) solutions to it are also possible, but
they are kind of tricky. Ideally, MS should patch their OSes and
provide a "thread queue" (Linux folks reinvented "half-or-less" of
this thing and proudly called it "a futex") parking interface that
would allow fast sync. For mutexes, (high order waiters bit shall
be maintained by the kernel)
mutex_lock:
WHILE
atomic_bit_test_set_ddacq(&lock, 1)
lock_queue_wait(&lock, 1) // wait if locked bit is set
mutex_unlock:
uintptr_t lock_queue;
IF atomic_decrement_rel(lock_queue = &lock)
THEN lock_queue_wake(lock_queue, 1)
For semas,
sema_lock:
WHILE // CAS/LL-SC
!atomic_decrement_if_binand_7FFFFFFF_is_not_zero_ddacq(&lock)
lock_queue_wait(&lock, 0) // wait if sem.value is zero
sema_unlock:
uintptr_t lock_queue;
IF atomic_increment_rel(lock_queue = &lock) > 0x80000000
THEN lock_queue_wake(lock_queue, 1)
(try/timed operations omitted for brevity)
There shall be no requirement to "open/close" that parking
mechanism (physical address shall be used as "queue-id"/"wait
token"). And it shall be safe to pass an "invalid" (even
unmapped/nonexistent) queue-id/virtual address to a wake call...
in worse case it would result in spurious wakes but spurious
wakes shall be allowed anyway.
>
> > on it. "posix safety" is needed for things like lock-protected ref
> > counting when mutex is "part of" managed object (i.e. you destroy
> > the mutex when the count drops to zero). Another thing to watch is
> > MS event's behavior for timedout waits. Reportedly, on some windows
> > version(s), *timedout* waiter on an event/sema may still consume a
> > signal (such behavior is OK and even desirable for condvars because
> > timedout status there is just an indication of an independent event,
> > but it's NOT OK for events/semas because they have state). If/when
> > this is the case, the timedout waiter on a "retry_event" must try
> > to acquire the mutex (with "-1") and, if succeeded, either unlock
> > it and report failure (which makes little sense given "watchdog
> > nature" of mutex.timedwait) or just ignore timedout status and
> > report success.
regards,
alexander.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk