Rename the majority of remaining C files in the RTS to C++
[charm.git] / src / arch / util / immediate.C
blob5209ed80391aed8fed59755fb2b7fc46caf347f6
1 /** @file
2  * \brief Immediate message implementation
3  * \ingroup Machine
4  */
6 /**
7  * \addtogroup Machine
8 */
9 /*@{*/
12   support immediate message in Converse
15 int _immediateReady = 0;
17 int _immRunning=0; /* if set, somebody's inside an immediate message */
19 /* _immediateLock and _immediateFlag declared in convcore.C
20    for machine layers with CMK_IMMEDIATE_MSG=0   */ 
22 #if CMK_IMMEDIATE_MSG
24 /* SMP: These variables are protected by immRecvLock. */
25 static void *currentImmediateMsg=NULL; /* immediate message currently being executed */
27 /*  push immediate messages into imm queue. Immediate messages can be pushed
28     from both processor threads or comm. thread.
29     
30     The actual user handler is in Xhandler; the converse handler
31     is still marked as the immediate message "handler".
33 SMP:  This routine does its own locking.
35 CMI_EXTERNC
36 void CmiPushImmediateMsg(void *msg)
38   MACHSTATE(4,"pushing immediate message {");
39   /* This lock check needs portable access to comm_flag, which is tough:
40      MACHLOCK_ASSERT(_immRunning||comm_flag,"CmiPushImmediateMsg");
41   */
42   
43   CmiLock(CsvAccess(NodeState).immSendLock);
44   CMIQueuePush(CsvAccess(NodeState).immQ, (char *)msg);
45   CmiUnlock(CsvAccess(NodeState).immSendLock);
46   MACHSTATE(4,"} pushing immediate message");
49 /* In user's immediate handler, if the immediate message cannot be processed
50    due to failure to acquire locks, etc, user program can call this function
51    to postpone the immediate message. The immediate message will eventually
52    be re-inserted into the imm queue.
54 SMP: This routine must be called holding immRecvLock
56 void CmiDelayImmediate(void)
58   MACHLOCK_ASSERT(_immRunning,"CmiDelayImmediate");
60 #if CMI_QD
61   CQdCreate(CpvAccess(cQdState),1);
62 #endif
63   MACHSTATE(5,"Actually delaying an immediate message");
64   CMIQueuePush(CsvAccess(NodeState).delayedImmQ, (char *)currentImmediateMsg);
69   Handle an immediate message, using the handler table of
70   processor rank 0.  We can't call CmiHandleMessage for 
71   immediate messages, because of CpvAccess and tracing.
73 SMP: This routine must be called holding immRecvLock
74  */
75 void CmiHandleImmediateMessage(void *msg) {
76 /*  int handlerNo=CmiGetXHandler(msg); */
77   int handlerNo=CmiImmediateHandler(msg);
78   CmiHandlerInfo *h;
79 #if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
80         CmiAssert(0);
81 #endif
82   MACHSTATE2(4,"immediate message handler %d %d", CmiGetHandler(msg), handlerNo)
83 /*  CmiHandlerInfo *h=&CpvAccessOther(CmiHandlerTable,0)[handlerNo]; */
84   h = &CpvAccess(CmiHandlerTable)[handlerNo];
85   CmiAssert(h && h->hdlr);
87   MACHLOCK_ASSERT(_immRunning,"CmiHandleImmediateMessage");
88 #if CMI_QD
89   CQdProcess(CpvAccess(cQdState),1);
90 #endif
91   (h->hdlr)(msg,h->userPtr);
95    Check for queued immediate messages and handle them.
96    
97    It is safe to call this routine from multiple threads, or from SIGIO.
99 SMP: This routine must be called holding no locks, not even the comm. lock.
100  */
101 void CmiHandleImmediate(void)
103    void *msg;
105    /* converse init hasn't finish */
106    if (!_immediateReady) return;
107   
108    /* If somebody else is checking the queue, we don't need to */
109    if (CmiTryLock(CsvAccess(NodeState).immRecvLock)!=0) return;
111    /* Make sure only one thread is running immediate messages:
112    CmiLock(CsvAccess(NodeState).immRecvLock);
113    */
115    MACHLOCK_ASSERT(!_immRunning,"CmiHandleImmediate");
116    _immRunning=1; /* prevents SIGIO reentrancy, and allows different send */
117    MACHSTATE(2,"Entered handleImmediate {")
119    /* Handle all pending immediate messages */
120    while (NULL!=(msg=CMIQueuePop(CsvAccess(NodeState).immQ)))
121    {
122      currentImmediateMsg = msg;
123      MACHSTATE(4,"calling immediate message handler {");
124      CmiHandleImmediateMessage(msg);
125      MACHSTATE(4,"} calling immediate message handler");
126    }
127    
128    /* Take care of delayed immediate messages, which we have to handle next time */
129    while (NULL!=(msg=CMIQueuePop(CsvAccess(NodeState).delayedImmQ)))
130         CmiPushImmediateMsg(msg);
131    
132    MACHSTATE(2,"} exiting handleImmediate")
133    _immRunning = 0;
134    
135    CmiUnlock(CsvAccess(NodeState).immRecvLock);
137    CmiClearImmediateFlag();
140 #endif
142 /*@}*/