Removed CldAvgLoad declaration (not using it anymore).
[charm.git] / src / conv-ldb / cldb.c
1 #include "converse.h"
2
3 /*
4  * CldSwitchHandler takes a message and a new handler number.  It
5  * changes the handler number to the new handler number and move the
6  * old to the Xhandler part of the header.  When the message gets
7  * handled, the handler should call CldRestoreHandler to put the old
8  * handler back.
9  *
10  * CldPutToken puts a message in the scheduler queue in such a way
11  * that it can be retreived from the queue.  Once the message gets
12  * handled, it can no longer be retreived.  CldGetToken removes a
13  * message that was placed in the scheduler queue in this way.
14  * CldCountTokens tells you how many tokens are currently retreivable.
15  */
16
17 int CldRegisterInfoFn(CldInfoFn fn)
18 {
19   return CmiRegisterHandler((CmiHandler)fn);
20 }
21
22 int CldRegisterPackFn(CldPackFn fn)
23 {
24   return CmiRegisterHandler((CmiHandler)fn);
25 }
26
27 void CldSwitchHandler(char *cmsg, int handler)
28 {
29   CmiSetXHandler(cmsg, CmiGetHandler(cmsg));
30   CmiSetHandler(cmsg, handler);
31 }
32
33 void CldRestoreHandler(char *cmsg)
34 {
35   CmiSetHandler(cmsg, CmiGetXHandler(cmsg));
36 }
37
38 void Cldhandler(void *);
39  
40 typedef struct CldToken_s {
41   char msg_header[CmiMsgHeaderSizeBytes];
42   void *msg;  /* if null, message already removed */
43   struct CldToken_s *pred;
44   struct CldToken_s *succ;
45 } *CldToken;
46
47 typedef struct CldProcInfo_s {
48   int tokenhandleridx;
49   int load; /* number of items in doubly-linked circle besides sentinel */
50   CldToken sentinel;
51 } *CldProcInfo;
52
53 CpvDeclare(CldProcInfo, CldProc);
54 extern void CldNotify(int);
55
56 static void CldTokenHandler(CldToken tok)
57 {
58   CldProcInfo proc = CpvAccess(CldProc);
59   CldToken pred, succ;
60   if (tok->msg) {
61     tok->pred->succ = tok->succ;
62     tok->succ->pred = tok->pred;
63     proc->load --;
64     CmiHandleMessage(tok->msg);
65     CldNotify(proc->load);
66   }
67 }
68
69 int CldCountTokens()
70 {
71   CldProcInfo proc = CpvAccess(CldProc);
72   return proc->load;
73 }
74
75 void CldPutToken(void *msg)
76 {
77   CldProcInfo proc = CpvAccess(CldProc);
78   CldInfoFn ifn = (CldInfoFn)CmiHandlerToFunction(CmiGetInfo(msg));
79   CldToken tok = (CldToken)CmiAlloc(sizeof(struct CldToken_s));
80   int len, queueing, priobits; unsigned int *prioptr;
81   CldPackFn pfn;
82
83   tok->msg = msg;
84
85   /* add token to the doubly-linked circle */
86   tok->pred = proc->sentinel->pred;
87   tok->succ = proc->sentinel;
88   tok->pred->succ = tok;
89   tok->succ->pred = tok;
90   proc->load ++;
91   
92   /* add token to the scheduler */
93   CmiSetHandler(tok, proc->tokenhandleridx);
94   ifn(msg, &pfn, &len, &queueing, &priobits, &prioptr);
95
96   queueing = CQS_QUEUEING_LIFO; 
97   CsdEnqueueGeneral(tok, queueing, priobits, prioptr);
98 }
99
100 void CldGetToken(void **msg)
101 {
102   CldProcInfo proc = CpvAccess(CldProc);
103   CldToken tok;
104   tok = proc->sentinel->succ;
105   if (tok == proc->sentinel) {
106     *msg = 0; return;
107   }
108   tok->pred->succ = tok->succ;
109   tok->succ->pred = tok->pred;
110   proc->load --;
111   *msg = tok->msg;
112   tok->msg = 0;
113 }
114
115 void CldModuleGeneralInit()
116 {
117   CldToken sentinel = (CldToken)CmiAlloc(sizeof(struct CldToken_s));
118   CldProcInfo proc;
119
120   CpvInitialize(CldProcInfo, CldProc);
121   CpvAccess(CldProc) = (CldProcInfo)CmiAlloc(sizeof(struct CldProcInfo_s));
122   proc = CpvAccess(CldProc);
123   proc->load = 0;
124   proc->tokenhandleridx = CmiRegisterHandler((CmiHandler)CldTokenHandler);
125   proc->sentinel = sentinel;
126   sentinel->succ = sentinel;
127   sentinel->pred = sentinel;
128 }