2 implements per object message queue - every object maintains its own
6 1. load balancer to know the number of pending messages waiting in its queue;
7 2. improve cache performance by executing all messages belonging to one obj.
9 There are two ways to use it:
10 1. by default, no queue is created for any object. Using "+objq" runtime
11 option will create queue for every object
12 2. in a Chare's constructor, call CkUsesObjQ() to turn on the object queue
13 for that calling Chare.
15 created by Gengbin Zheng, gzheng@uiucedu on 12/29/2003
22 CkpvDeclare(TokenPool*, _tokenPool);
24 extern int index_tokenHandler;
26 extern CkMigratable * CkArrayMessageObjectPtr(envelope *env);
30 // turn on object queue
31 void CkObjectMsgQ::create() {
34 objQ = (void *)CdsFifo_Create();
36 objQ = (void *)CqsCreate();
40 int CkObjectMsgQ::length() const {
42 return objQ?CdsFifo_Length((CdsFifo)objQ):0;
44 return objQ?CqsLength((Queue)objQ):0;
48 CkObjectMsgQ::~CkObjectMsgQ()
54 CdsFifo_Destroy(objQ);
56 CqsDelete((Queue)objQ);
62 void CkObjectMsgQ::process()
64 #if CMK_OBJECT_QUEUE_AVAILABLE
65 if (objQ == NULL) return;
66 // if (inprocessing) return;
68 if (mlen == 0) return;
72 tok = (ObjectToken*)CdsFifo_Dequeue(objQ);
74 CqsDequeue((Queue)objQ, (void **)&tok);
77 envelope *env = (envelope *)tok->message;
79 // release messages in the queue
82 CqsEnqueueGeneral((Queue)CpvAccess(CsdSchedQueue),
83 env, env->getQueueing(),env->getPriobits(),
84 (unsigned int *)env->getPrioPtr());
86 // not be able to call inline, enqueue to the obj msg queue
87 CdsFifo_Enqueue(CpvAccess(CsdObjQueue), env);
90 CkpvAccess(_tokenPool)->put(tok);
92 tok = (ObjectToken*)CdsFifo_Dequeue(objQ);
94 CqsDequeue((Queue)objQ, (void **)&tok);
100 // find out the object pointer from a charm message envelope
101 Chare * CkFindObjectPtr(envelope *env)
104 switch(env->getMsgtype()) {
107 case ArrayEltInitMsg:
114 obj = CkArrayMessageObjectPtr(env);
117 // FIXME, chare calls CldEnqueue which bypass the object queue
118 obj = (Chare*)env->getObjPtr();
122 obj = _localBranch(env->getGroupNum());
125 case ForNodeBocMsg : {
126 obj = (Chare*)(CksvAccess(_nodeGroupTable)->find(env->getGroupNum()).getObj());
130 CmiAbort("Fatal Charm++ Error> Unknown msg-type in CkFindObjectPtr.\n");
135 #if CMK_OBJECT_QUEUE_AVAILABLE
136 // insert an envelope msg into object queue
137 void _enqObjQueue(Chare *obj, envelope *env)
139 ObjectToken *token = CkpvAccess(_tokenPool)->get();
141 token->message = env;
144 CmiSetHandler(token, index_tokenHandler);
145 // enq to charm sched queue
146 CqsEnqueueGeneral((Queue)CpvAccess(CsdSchedQueue),
147 token, env->getQueueing(),env->getPriobits(),
148 (unsigned int *)env->getPrioPtr());
149 // also enq to object queue
151 CdsFifo_Enqueue(obj->CkGetObjQueue().queue(), token);
153 CqsEnqueueGeneral((Queue)(obj->CkGetObjQueue().queue()),
154 token, env->getQueueing(),env->getPriobits(),
155 (unsigned int *)env->getPrioPtr());
161 // converseMsg is a real message
162 void _ObjectQHandler(void *converseMsg)
164 #if CMK_OBJECT_QUEUE_AVAILABLE
165 register envelope *env = (envelope *)(converseMsg);
166 Chare *obj = CkFindObjectPtr(env);
168 // CmiSetHandler(env, CmiGetXHandler(env));
169 // I can do this because this message is always a charm+ message
170 CmiSetHandler(env, _charmHandlerIdx);
171 if (obj && obj->CkGetObjQueue().queue()) { // queue enabled
172 _enqObjQueue(obj, env);
174 else { // obj queue not enabled
175 CqsEnqueueGeneral((Queue)CpvAccess(CsdSchedQueue),
176 env, env->getQueueing(),env->getPriobits(),
177 (unsigned int *)env->getPrioPtr());
180 CmiAbort("Invalide _ObjectQHandler called!");
184 // normally from sched queue
185 void _TokenHandler(void *tokenMsg)
187 #if CMK_OBJECT_QUEUE_AVAILABLE
188 ObjectToken *token = (ObjectToken*)tokenMsg;
189 Chare *obj = token->objPtr;
190 void *message = token->message;
191 // we are done with this token out of sched queue
192 CkpvAccess(_tokenPool)->put(token);
193 if (message == NULL) { // message already consumed
196 CkObjectMsgQ &objQ = obj->CkGetObjQueue();
199 CmiAbort("Invalide _TokenHandler called!");