Re: Locking Primitives
- From: Hugo gleaves@xxxxxxxxxxx> <hugh<underbar>
- Date: Wed, 13 May 2009 10:31:01 -0700
Hi Chris
I've been away, I will try to answer your question, but may have to be brief.
No attempt is made to "repair" any shared memory or do any recovery.
The motivation was to distinguish between failing to get a lock because it
is in use by some thread/process and failing to get a lock because the
process terminated, there is obvioulsy no point in waiting or spinning on a
lock that can never be released.
The shared spinlock data structure contains the PID and TID of the locker,
as well as the date-time-started of the process itself, this handles the fact
that Windows recylces process IDs, the combination of the three values is
unique.
As for the nesting, the spinlock we have allows any function to aquire a
lock, even if some call earlier up the stack has already aquired it. The
spinlock we have support this for read or write mode locks.
These spinlock are ONLY ever aquired by other functions in our library,
never held by caller code (managed code in this case). A managed app will at
some stage call some unmanaged function, that function may set of a sequence
of activities that lock/unlock shared structures, but by the time this
returns to the managed caller, nothing is locked.
This is the intended setting for our spinlock code.
I have dreamt for years of a termination handler, I recall working on VOS
(Stratus' proprietary OS, a derivative of Multics) in which code could (if it
wanted) get an exception raised when the process was stopped, this handler
could then try to cleanup and make a hasty exit before the process stopped, I
dont think Windows offers this, perhaps Server 2008 might, but not checked.
H
"Chris M. Thomasson" wrote:
"Hugo gleaves@xxxxxxxxxxx>" <hugh<underbar> wrote in message.
news:694C9DF0-5311-482C-920F-B5583645D468@xxxxxxxxxxxxxxxx
Thank you Chris
Let me peruse your code and see what I find.
I know these issues are not trivial, and we have had great success with
our
(internal use only) spinlock which supports nesting,
What do you mean by nesting? Are you writing about recursive reads and
writes?
read/write and dead locker handling.
Do you mind if I ask how your doing that? ;^)
This is hard to do with custom locks. One time, a long time ago, I created a
scheme in which a client process would mark itself as being within a
critical section. A watchdog process monitored said client process. If the
watchdog noticed that the client died, it would check if was in a critical
section. If it was, it set a piece of state owned by the critical section to
abandoned and forcefully unlocked it. The actual lock structure was based on
a fast-path semaphore. Something like this:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/6f2a5ca67aa4447
The next locker that came around would notice the abandoned state and
attempt to repair the shared data-structure and revert it back into a
coherent state. If a process dies while it has write access, all bets are
off and you need a robust recover strategy.
I am interested in reading about how you accomplish this.
FWIW, check this read/write strict FIFO spinlock out, it uses atomic
fetch-and-add (e.g., InterlockedExchangeAdd()), in pseudo-code w/ membars
ommited for clarity:
____________________________________________________________
class rwspinlock {
enum constant {
WRITE = 1,
READ = 0x10000
};
atomic_word m_next; // = 0
atomic_word m_cur; // = 0
public:
void rdlock() {
atomic_word ticket = ATOMIC_FAA(&m_next, READ) % READ;
while (ticket != (ATOMIC_LOAD(&m_current) % READ))) backoff();
}
void rdunlock() {
ATOMIC_FAA(&m_current, READ);
}
public:
void wrlock() {
atomic_word ticket = ATOMIC_FAA(&m_next, WRITE);
while (ticket != ATOMIC_LOAD(&m_current)) backoff();
}
void wrunlock() {
ATOMIC_FAA(&m_current, WRITE);
}
};
____________________________________________________________
This AWESOME algorithm was invented by Joe Seigh who can be contacted here:
http://atomic-ptr-plus.sourceforge.net
I believe its the smallest FIFO rw-spinlock in the world. It even works with
wrap and carry out from the writer field into the reader field. Caveat,
number of waiting threads has to be less than field size.
- Follow-Ups:
- Re: Locking Primitives
- From: Chris M. Thomasson
- Re: Locking Primitives
- From: Jakob Bohm
- Re: Locking Primitives
- Prev by Date: file cache addresses
- Next by Date: Re: Locking Primitives
- Previous by thread: Re: Locking Primitives
- Next by thread: Re: Locking Primitives
- Index(es):
Relevant Pages
|
Loading