Hi
I’m porting a driver from Unix to W2K. Under Unix, the
driver uses sleep/wakeup pair extensively. For
starters, a thread can call sleep to wait on a
arbitrary address and wakeup can be used to wakeup a
thread sleeping on a particular address.
The code looks like this:
spinlock();
// do something here
…
get_sleep_lock(addr);
spinunlock();
sleep(addr);
The pecularity of this code is, once you acquire
spinlock, until the sleep gets into shape, nobody else
can call a wakeup. The sleep call by itself releases
the sleep lock, which is also required by wakeup.
Hence even if a context switch happens after a
spinunlock, other threads can’t call a wakeup, since
the sleeplock is held by this thread. So this code
make sure that, sleep never misses its wakeup.
I wonder, any synchronization primitive provided by NT
can achieve this.
I’m sure that it’s possible to write a whole bunch of
code to lock/unlock using interlocked functions and
can do this. But I would prefer to use/build over the
existing primitives.
Thanks,
Sajeev.
For Stock Quotes, Finance News, Insurance, Tax Planners, Mutual Funds…
Visit http://in.finance.yahoo.com/
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
— sajeev sas wrote:
> Hi
> I’m porting a driver from Unix to W2K. Under Unix, the
> driver uses sleep/wakeup pair extensively. For
> starters, a thread can call sleep to wait on a
> arbitrary address and wakeup can be used to wakeup a
> thread sleeping on a particular address.
>
> The code looks like this:
>
> spinlock();
> // do something here
> …
> get_sleep_lock(addr);
> spinunlock();
> sleep(addr);
>
> The pecularity of this code is, once you acquire
> spinlock, until the sleep gets into shape, nobody else
> can call a wakeup. The sleep call by itself releases
> the sleep lock, which is also required by wakeup.
>
> Hence even if a context switch happens after a
> spinunlock, other threads can’t call a wakeup, since
> the sleeplock is held by this thread. So this code
> make sure that, sleep never misses its wakeup.
>
> I wonder, any synchronization primitive provided by NT
> can achieve this.
>
> I’m sure that it’s possible to write a whole bunch of
> code to lock/unlock using interlocked functions and
> can do this. But I would prefer to use/build over the
> existing primitives.
To me, it looks like KEVENT may be what you need. When you
call KeInitializeEvent you mark it as not signalled. Then
you can call KeWaitForSingleObject for this KEVENT at any
time - if it has been signalled before your call, the
function will return immediately. You pay for this convenience
by having to allocate KEVENT.
__________________________________________________
Do You Yahoo!?
Check out Yahoo! Shopping and Yahoo! Auctions for all of
your unique holiday gifts! Buy at http://shopping.yahoo.com
or bid at http://auctions.yahoo.com
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
> the sleeplock is held by this thread. So this code
make sure that, sleep never misses its wakeup.
I wonder, any synchronization primitive provided by NT
can achieve this.
Sorry.
The sleep/wakeup pair is an obsolete design of original AT&T UNIX of early 70ies.
I believe that now even Linux (possible the simplest of modern well-known UNIXen) do not use it.
The puny side of this design is that - as you mentioned - sleep() can miss its wakeup(), and you must take some measures to deal
with this.
Having a full-fashioned event object gets rid of this. In this case, sleep() checks the event state and just continues if the event
is set. If the event is clear - then the task is added to the event’s list of waiters and slept.
wakeup() sets the event state to set, and then, if the waiter’s list is not empty - it passes the waiter’s list and awakens all
these tasks (or the first task only - depending on event kind).
In this case, there cannot be such thing as missing wakeup(). Surely it has some costs - you cannot wait on any address or value,
you must have an event structure (4 ULONGs on NT) at the address you waiting on.
NT is free from the problem you mentioned since it uses only the full-fashioned events, and has no obsolete sleep()/wakeup() at all.
Linux also has full-fashioned events - they are called “waitqueue” in Linux.
NT also has functions to wait on many events at all - either for all of them to be signaled or for any of them. Linux has no such -
the only place Linux needs it is select()/poll(), and it is implemented via nasty hacks which breaks the scheduler’s encapsulation.
Max
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com