<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>