<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
e.g. does this help:<BR>
<BR>
PROCEDURE Alert(t: T) =<BR> VAR prev, next: T;<BR> BEGIN<BR> IF t = NIL THEN Die(ThisLine(), "Alert called from non-Modula-3 thread") END;<BR>(* remove this *) EnterCriticalSection_giant(); <BR>
(* make next two lines one interlocked *)<BR> t.alerted := TRUE;<BR> IF t.alertable THEN<BR>(* add this *) EnterCriticalSection_giant();<BR>
(* Dequeue from any CV and unblock from the semaphore *)<BR> IF t.waitingOn # NIL THEN<BR> next := t.waitingOn.waiters; prev := NIL;<BR> WHILE next # t DO<BR> <* ASSERT(next#NIL) *><BR> prev := next; next := next.nextWaiter;<BR> END;<BR> IF prev = NIL THEN<BR> t.waitingOn.waiters := t.nextWaiter<BR> ELSE<BR> prev.nextWaiter := t.nextWaiter;<BR> END;<BR> t.nextWaiter := NIL;<BR> t.waitingOn := NIL;<BR> END;<BR> t.alertable := FALSE;<BR> IF ReleaseSemaphore(t.waitSema, 1, NIL) = 0 THEN<BR> Choke(ThisLine());<BR> END;<BR> END;<BR> LeaveCriticalSection_giant(); (* this moves up obviously *)<BR> END Alert;<BR><BR>
<BR> <BR>
<HR id=stopSpelling>
From: jay.krell@cornell.edu<BR>To: hosking@cs.purdue.edu; m3devel@elegosoft.com<BR>Subject: win32 threads/alert/race<BR>Date: Mon, 5 Oct 2009 14:27:14 +0000<BR><BR>
<STYLE>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Tony can you clarify/confirm where you think the race is?<BR> <BR> <BR>Is it here:<BR> <BR> <BR>PROCEDURE InnerWait(m: Mutex; c: Condition; self: T) =<BR> (* LL = giant+m on entry; LL = m on exit *)<BR> BEGIN<BR> <* ASSERT( (self.waitingOn=NIL) AND (self.nextWaiter=NIL) ) *><BR> self.waitingOn := c;<BR> self.nextWaiter := c.waiters;<BR> c.waiters := self;<BR> m.release();<BR> LeaveCriticalSection_giant();<BR> <BR> ** here ** ?<BR><BR> IF perfOn THEN PerfChanged(State.waiting) END;<BR> IF WaitForSingleObject(self.waitSema, INFINITE) # 0 THEN<BR> Choke(ThisLine());<BR> END;<BR> m.acquire();<BR> END InnerWait;<BR><BR>Btw..just in case.. alerted and alertable could be "interlocked", even share bits in the same long.<BR>If that helps.<BR> <BR>Another thing to consider is that Win32 reserves the lower two bits of handles for users.<BR>So you can imagine something even like where waitSema is in two places.<BR>One place where it isn't used, always there.<BR>Another place where if it is non-null it is going to be waited on.<BR>You could merge setting of that copy of waitSema with the two bits alerted and alertable.<BR>And set all three in one fell interlocked swoop.<BR>Does that help?<BR> <BR> <BR>I'm just mentioning random tricks, without understanding where the race is.<BR> <BR> <BR>I'm just hoping you don't need a lock free manipulation of the waiters list.<BR>That I have no good ideas on.<BR>There is the slist stuff but I'm not keen on it, and I don't think it buys anything.<BR> <BR> <BR> - Jay<BR><BR><BR><BR><BR><BR> <BR> </body>
</html>