00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "charm++.h"
00018 #include "envelope.h"
00019 #include "queueing.h"
00020 #include "ckobjQ.h"
00021
00022 CkpvDeclare(TokenPool*, _tokenPool);
00023
00024 extern int index_tokenHandler;
00025
00026 extern CkMigratable * CkArrayMessageObjectPtr(envelope *env);
00027
00028 #define OBJQ_FIFO 1
00029
00030
00031 void CkObjectMsgQ::create() {
00032 if (!objQ)
00033 #if OBJQ_FIFO
00034 objQ = (void *)CdsFifo_Create();
00035 #else
00036 objQ = CqsCreate();
00037 #endif
00038 }
00039
00040 int CkObjectMsgQ::length() const {
00041 #if OBJQ_FIFO
00042 return objQ?CdsFifo_Length((CdsFifo)objQ):0;
00043 #else
00044 return objQ?CqsLength((Queue)objQ):0;
00045 #endif
00046 }
00047
00048 CkObjectMsgQ::~CkObjectMsgQ()
00049 {
00050 if (objQ) {
00051 process();
00052
00053 #if OBJQ_FIFO
00054 CdsFifo_Destroy(objQ);
00055 #else
00056 CqsDelete((Queue)objQ);
00057 #endif
00058 }
00059 }
00060
00061
00062 void CkObjectMsgQ::process()
00063 {
00064 #if CMK_OBJECT_QUEUE_AVAILABLE
00065 if (objQ == NULL) return;
00066
00067 int mlen = length();
00068 if (mlen == 0) return;
00069
00070 ObjectToken *tok;
00071 #if OBJQ_FIFO
00072 tok = (ObjectToken*)CdsFifo_Dequeue(objQ);
00073 #else
00074 CqsDequeue((Queue)objQ, (void **)&tok);
00075 #endif
00076 while (tok != NULL) {
00077 envelope *env = (envelope *)tok->message;
00078 if (env) {
00079
00080 tok->message = NULL;
00081
00082
00083
00084
00085
00086
00087 CdsFifo_Enqueue(CpvAccess(CsdObjQueue), env);
00088 }
00089 else
00090 CkpvAccess(_tokenPool)->put(tok);
00091 #if OBJQ_FIFO
00092 tok = (ObjectToken*)CdsFifo_Dequeue(objQ);
00093 #else
00094 CqsDequeue((Queue)objQ, (void **)&tok);
00095 #endif
00096 }
00097 #endif
00098 }
00099
00100
00101 Chare * CkFindObjectPtr(envelope *env)
00102 {
00103 Chare *obj = NULL;
00104 switch(env->getMsgtype()) {
00105 case BocInitMsg:
00106 case NodeBocInitMsg:
00107 case ArrayEltInitMsg:
00108 case NewChareMsg:
00109 case NewVChareMsg:
00110 case ForVidMsg:
00111 case FillVidMsg:
00112 break;
00113 case ForArrayEltMsg:
00114 obj = CkArrayMessageObjectPtr(env);
00115 break;
00116 case ForChareMsg : {
00117
00118 obj = (Chare*)env->getObjPtr();
00119 break;
00120 }
00121 case ForBocMsg : {
00122 obj = _localBranch(env->getGroupNum());
00123 break;
00124 }
00125 case ForNodeBocMsg : {
00126 obj = (Chare*)(CksvAccess(_nodeGroupTable)->find(env->getGroupNum()).getObj());
00127 break;
00128 }
00129 default:
00130 CmiAbort("Fatal Charm++ Error> Unknown msg-type in CkFindObjectPtr.\n");
00131 }
00132 return obj;
00133 }
00134
00135 #if CMK_OBJECT_QUEUE_AVAILABLE
00136
00137 void _enqObjQueue(Chare *obj, envelope *env)
00138 {
00139 ObjectToken *token = CkpvAccess(_tokenPool)->get();
00140 CmiAssert(token);
00141 token->message = env;
00142 token->objPtr = obj;
00143
00144 CmiSetHandler(token, index_tokenHandler);
00145
00146 CqsEnqueueGeneral((Queue)CpvAccess(CsdSchedQueue),
00147 token, env->getQueueing(),env->getPriobits(),
00148 (unsigned int *)env->getPrioPtr());
00149
00150 #if OBJQ_FIFO
00151 CdsFifo_Enqueue(obj->CkGetObjQueue().queue(), token);
00152 #else
00153 CqsEnqueueGeneral((Queue)(obj->CkGetObjQueue().queue()),
00154 token, env->getQueueing(),env->getPriobits(),
00155 (unsigned int *)env->getPrioPtr());
00156 #endif
00157 }
00158 #endif
00159
00160
00161
00162 void _ObjectQHandler(void *converseMsg)
00163 {
00164 #if CMK_OBJECT_QUEUE_AVAILABLE
00165 envelope *env = (envelope *)(converseMsg);
00166 Chare *obj = CkFindObjectPtr(env);
00167
00168
00169
00170 CmiSetHandler(env, _charmHandlerIdx);
00171 if (obj && obj->CkGetObjQueue().queue()) {
00172 _enqObjQueue(obj, env);
00173 }
00174 else {
00175 CqsEnqueueGeneral((Queue)CpvAccess(CsdSchedQueue),
00176 env, env->getQueueing(),env->getPriobits(),
00177 (unsigned int *)env->getPrioPtr());
00178 }
00179 #else
00180 CmiAbort("Invalide _ObjectQHandler called!");
00181 #endif
00182 }
00183
00184
00185 void _TokenHandler(void *tokenMsg)
00186 {
00187 #if CMK_OBJECT_QUEUE_AVAILABLE
00188 ObjectToken *token = (ObjectToken*)tokenMsg;
00189 Chare *obj = token->objPtr;
00190 void *message = token->message;
00191
00192 CkpvAccess(_tokenPool)->put(token);
00193 if (message == NULL) {
00194 return;
00195 }
00196 CkObjectMsgQ &objQ = obj->CkGetObjQueue();
00197 objQ.process();
00198 #else
00199 CmiAbort("Invalide _TokenHandler called!");
00200 #endif
00201 }