1 /* ==================================================================== */
2 /* Implement a library to handle reflective memory Shmem back end. */
3 /* This device emulates reflective memory via the symp driver. */
4 /* Julian Lewis 14th Jan 2008 */
5 /* ==================================================================== */
7 /* Simple synchronization driver */
12 static SympDrvrIoBuf iob
;
13 static XmemCallbackStruct
*cbs
= (XmemCallbackStruct
*) &(iob
.IoBuf
);
14 static XmemTableId tmsk
= 0;
16 /* ==================================================================== */
17 /* Try to initialize the specified device */
19 XmemError
ShmemInitialize() { /* Initialize hardware/software */
25 for (i
= 1; i
<= SympDrvrCLIENT_CONTEXTS
; i
++) {
26 sprintf(fnm
,"/dev/symp.%1d",i
);
27 if ((fn
= open(fnm
,O_RDWR
,0)) > 0) {
31 return XmemErrorSUCCESS
;
34 XmemErrorCallback(XmemErrorNOT_INITIALIZED
,0);
36 return XmemErrorSUCCESS
;
39 /* ==================================================================== */
40 /* Get all currently up and running nodes. */
41 /* The set of up and running nodes is determined dynamically through a */
42 /* handshake protocol between nodes. */
44 XmemNodeId
ShmemGetAllNodeIds() {
49 /* ==================================================================== */
50 /* Register your call back to handle Xmem Events. */
52 XmemError
ShmemRegisterCallback(void (*cb
)(XmemCallbackStruct
*cbs
),
55 callmask
= (unsigned long) mask
;
56 if (ioctl(symp
,SympDrvrCONNECT
,&callmask
) < 0)
57 return XmemErrorCallback(XmemErrorSYSTEM
,errno
);
60 return XmemErrorSUCCESS
;
63 /* ==================================================================== */
64 /* Wait for an Xmem Event with time out, an incomming event will call */
65 /* any registered callback. */
67 XmemEventMask
ShmemWait(int timeout
) {
71 if (callmask
== 0) return 0;
73 if (ioctl(symp
,SympDrvrSET_TIMEOUT
,&timeout
) < 0)
74 return XmemErrorCallback(XmemErrorSYSTEM
,errno
);
76 cc
= read(symp
,&iob
,sizeof(SympDrvrIoBuf
));
78 bzero((void *) cbs
, sizeof(XmemCallbackStruct
));
79 cbs
->Mask
= XmemEventMaskTIMEOUT
;
80 if (callmask
& XmemEventMaskTIMEOUT
) callback(cbs
);
81 return XmemEventMaskTIMEOUT
;
83 if (cbs
->Mask
& XmemEventMaskTABLE_UPDATE
) {
84 tmsk
|= (1 << (cbs
->Table
-1));
89 return (XmemEventMask
) iob
.Mask
;
92 /* ==================================================================== */
93 /* Poll for any Xmem Events, an incomming event will call any callback */
94 /* that is registered for that event. */
96 XmemEventMask
ShmemPoll() {
100 if (ioctl(symp
,SympDrvrGET_QUEUE_SIZE
,&qsize
) < 0) {
101 XmemErrorCallback(XmemErrorSYSTEM
,errno
);
104 if (qsize
) return ShmemWait(0);
108 /* ==================================================================== */
109 /* Send a message to other nodes. If the node parameter is zero, then */
110 /* nothing happens, if its equal to 0xFFFFFFFF the message is sent via */
111 /* broadcast, else multicast or unicast is used. */
113 XmemError
ShmemSendMessage(XmemNodeId nodes
, XmemMessage
*mess
) {
119 switch (mess
->MessageType
) {
121 case XmemMessageTypeSEND_TABLE
:
122 cbs
->Table
= mess
->Data
;
123 cbs
->Mask
= XmemEventMaskSEND_TABLE
;
126 case XmemMessageTypeUSER
:
127 cbs
->Data
= mess
->Data
;
128 cbs
->Mask
= XmemEventMaskUSER
;
131 case XmemMessageTypeTABLE_UPDATE
:
132 cbs
->Table
= mess
->Data
;
133 cbs
->Mask
= XmemEventMaskTABLE_UPDATE
;
136 case XmemMessageTypeINITIALIZE_ME
:
137 cbs
->Data
= mess
->Data
;
138 cbs
->Mask
= XmemEventMaskINITIALIZED
;
141 case XmemMessageTypeKILL
:
142 cbs
->Mask
= XmemEventMaskKILL
;
146 return XmemErrorCallback(XmemErrorNO_SUCH_MESSAGE
,0);
148 iob
.Mask
= cbs
->Mask
;
149 cc
= write(symp
,&iob
,sizeof(SympDrvrIoBuf
));
150 return XmemErrorSUCCESS
;
153 /* ==================================================================== */
154 /* Send your buffer to a reflective memory table. A table update event */
155 /* is broadcast automatically. */
157 XmemError
ShmemSendTable(XmemTableId tid
, /* Table to be written to */
158 void *buf
, /* Buffer containing table */
159 int elems
, /* Nr of double words to transfer */
160 int offset
, /* Offset of transfer */
161 int upflag
) { /* Update message flag */
166 mess
.MessageType
= XmemMessageTypeTABLE_UPDATE
;
168 return ShmemSendMessage(my_nid
,&mess
);
170 return XmemErrorSUCCESS
;
173 /* ==================================================================== */
174 /* Update your buffer from a reflective memory table. */
176 XmemError
ShmemRecvTable(XmemTableId table
, void *buf
) {
178 return XmemErrorSUCCESS
;
181 /* ==================================================================== */
182 /* Check which tables were updated. */
184 XmemTableId
ShmemCheckTables() {
192 XmemError
ShmemSendSoftWakeup(uint32_t nodeid
, uint32_t data
)