Adding optional support for critical path detection(currently disabled by default...
[charm.git] / src / ck-core / msgalloc.C
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 #include "ck.h"
9 #include "queueing.h"
10
11 extern "C"
12 void *CkAllocSysMsg(void)
13 {
14   return CkpvAccess(_msgPool)->get();
15 }
16
17 extern "C"
18 void CkFreeSysMsg(void *m)
19 {
20   CkpvAccess(_msgPool)->put(m);
21 }
22
23 extern "C"
24 void* CkAllocMsg(int msgIdx, int msgBytes, int prioBits)
25 {
26   register envelope* env;
27   env = _allocEnv(ForChareMsg, msgBytes, prioBits);
28   setMemoryTypeMessage(env);
29
30   env->setQueueing(_defaultQueueing);
31   env->setMsgIdx(msgIdx);
32
33 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
34   env->setEpIdxHistory();
35 #endif
36
37   return EnvToUsr(env);
38 }
39
40 extern "C"
41 void* CkAllocBuffer(void *msg, int bufsize)
42 {
43   bufsize = CkMsgAlignLength(bufsize);
44   register envelope *env = UsrToEnv(msg);
45   register envelope *packbuf;
46   packbuf = _allocEnv(env->getMsgtype(), bufsize, 
47                       env->getPriobits());
48   
49   register int size = packbuf->getTotalsize();
50   CmiMemcpy(packbuf, env, sizeof(envelope));
51   packbuf->setTotalsize(size);
52   packbuf->setPacked(!env->isPacked());
53   CmiMemcpy(packbuf->getPrioPtr(), env->getPrioPtr(), packbuf->getPrioBytes());
54
55 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
56   env->setEpIdxHistory();
57 #endif
58
59   return EnvToUsr(packbuf);;
60 }
61
62 extern "C"
63 void  CkFreeMsg(void *msg)
64 {
65   if (msg!=NULL) {
66       CmiFree(UsrToEnv(msg));
67   }
68 }
69
70
71 extern "C"
72 void* CkCopyMsg(void **pMsg)
73 {// cannot simply memcpy, because srcMsg could be varsize msg
74   register void *srcMsg = *pMsg;
75   register envelope *env = UsrToEnv(srcMsg);
76   register unsigned char msgidx = env->getMsgIdx();
77   if(!env->isPacked() && _msgTable[msgidx]->pack) {
78     srcMsg = _msgTable[msgidx]->pack(srcMsg);
79     UsrToEnv(srcMsg)->setPacked(1);
80   }
81   register int size = UsrToEnv(srcMsg)->getTotalsize();
82   register envelope *newenv = (envelope *) CmiAlloc(size);
83   CmiMemcpy(newenv, UsrToEnv(srcMsg), size);
84   if(UsrToEnv(srcMsg)->isPacked() && _msgTable[msgidx]->unpack) {
85     srcMsg = _msgTable[msgidx]->unpack(srcMsg);
86     UsrToEnv(srcMsg)->setPacked(0);
87   }
88   *pMsg = srcMsg;
89   if(newenv->isPacked() && _msgTable[msgidx]->unpack) {
90     srcMsg = _msgTable[msgidx]->unpack(EnvToUsr(newenv));
91     UsrToEnv(srcMsg)->setPacked(0);
92   } else srcMsg = EnvToUsr(newenv);
93
94   setMemoryTypeMessage(newenv);
95   return srcMsg;
96 }
97
98 extern "C"
99 void  CkSetQueueing(void *msg, int strategy)
100 {
101   UsrToEnv(msg)->setQueueing((unsigned char) strategy);
102 }
103
104
105 extern "C"
106 void* CkPriorityPtr(void *msg)
107 {
108   return UsrToEnv(msg)->getPrioPtr();
109 }
110
111 CkMarshallMsg *CkAllocateMarshallMsgNoninline(int size,const CkEntryOptions *opts)
112 {
113         //Allocate the message
114         CkMarshallMsg *m=new (size,opts->getPriorityBits())CkMarshallMsg;
115         //Copy the user's priority data into the message
116         envelope *env=UsrToEnv(m);
117         setMemoryTypeMessage(env);
118         CmiMemcpy(env->getPrioPtr(),opts->getPriorityPtr(),env->getPrioBytes());
119         //Set the message's queueing type
120         env->setQueueing((unsigned char)opts->getQueueing());
121 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
122         env->setEpIdxHistory();
123 #endif
124         return m;
125 }
126