*** empty log message ***
[charm.git] / src / conv-ldb / cldb.c
1 #include "converse.h"
2 /*
3  * How to write a load-balancer:
4  *
5  * 1. Every load-balancer must contain a definition of struct CldField.
6  *    This structure describes what kind of data will be piggybacked on
7  *    the messages that go through the load balancer.  The structure
8  *    must include certain predefined fields.  Put the word
9  *    CLD_STANDARD_FIELD_STUFF at the front of the struct definition
10  *    to include these predefined fields.
11  *
12  * 2. Every load-balancer must contain a definition of the global variable
13  *    Cld_fieldsize.  You must initialize this to sizeof(struct CldField).
14  *    This is not a CPV or CSV variable, it's a plain old C global.
15  *
16  * 3. When you send a message, you'll probably want to temporarily
17  *    switch the handler.  The following function will switch the handler
18  *    while saving the old one:
19  *
20  *       CldSwitchHandler(msg, field, newhandler);
21  *
22  *    Field must be a pointer to the gap in the message where the CldField
23  *    is to be stored.  The switch routine will use this region to store
24  *    the old handler, as well as some other stuff.  When the message
25  *    gets handled, you can switch the handler back like this:
26  *    
27  *       CldRestoreHandler(msg, &field);
28  *
29  *    This will not only restore the handler, it will also tell you
30  *    where in the message the CldField was stored.
31  *
32  * 4. Don't forget that CldEnqueue must support directed transmission of
33  *    messages as well as undirected, and broadcasts too.
34  *
35  */
36
37 int CldRegisterInfoFn(CldInfoFn fn)
38 {
39   return CmiRegisterHandler((CmiHandler)fn);
40 }
41
42 int CldRegisterPackFn(CldPackFn fn)
43 {
44   return CmiRegisterHandler((CmiHandler)fn);
45 }
46
47 /*
48  * These next subroutines are balanced on a thin wire.  They're
49  * correct, but the slightest disturbance in the offsets could break them.
50  *
51  */
52
53 void CldSwitchHandler(char *cmsg, int *field, int handler)
54 {
55   int *data = (int*)(cmsg+CmiMsgHeaderSizeBytes);
56   field[1] = CmiGetHandler(cmsg);
57   field[0] = data[0];
58   data[0] = ((char*)field)-cmsg;
59   CmiSetHandler(cmsg, handler);
60 }
61
62 void CldRestoreHandler(char *cmsg, void *hfield)
63 {
64   int *data = (int*)(cmsg+CmiMsgHeaderSizeBytes);
65   int offs = data[0];
66   int *field = (int*)(cmsg+offs);
67   data[0] = field[0];
68   CmiSetHandler(cmsg, field[1]);
69   *(int**)hfield = field;
70 }
71