1 | /*
|
---|
2 | =============================================================================
|
---|
3 | mbinit.c -- Multi-Tasker -- Mailbox support
|
---|
4 | Version 7 -- 1988-03-29 -- D.N. Lynx Crowe
|
---|
5 | (c) Copyright 1988 -- D.N. LYnx Crowe
|
---|
6 | =============================================================================
|
---|
7 | */
|
---|
8 |
|
---|
9 | #include "stddefs.h"
|
---|
10 | #include "mtdefs.h"
|
---|
11 |
|
---|
12 | extern short setipl(); /* set processor IPL function */
|
---|
13 | extern short SMStat(); /* semaphore check function */
|
---|
14 |
|
---|
15 | /*
|
---|
16 | =============================================================================
|
---|
17 | MBInit() -- initialize a mailbox
|
---|
18 | =============================================================================
|
---|
19 | */
|
---|
20 |
|
---|
21 | MBInit(pmbox)
|
---|
22 | register MBOX *pmbox;
|
---|
23 | {
|
---|
24 | register short oldipl;
|
---|
25 |
|
---|
26 | oldipl = setipl(7); /* DISABLE INTERRUPTS */
|
---|
27 |
|
---|
28 | pmbox->mail = (SEM)1L; /* reset the mail semaphore */
|
---|
29 | pmbox->mutex = (SEM)3L; /* reset the mutex semaphore */
|
---|
30 | pmbox->head = (MSG *)NIL; /* clear the MSG queue head pointer */
|
---|
31 | pmbox->tail = (MSG *)NIL; /* clear the MSG queue tail pointer */
|
---|
32 |
|
---|
33 | setipl(oldipl); /* RESTORE INTERRUPTS */
|
---|
34 | }
|
---|
35 |
|
---|
36 | /* |
---|
37 |
|
---|
38 | */
|
---|
39 |
|
---|
40 | /*
|
---|
41 | =============================================================================
|
---|
42 | MBSend() -- send a message to a mailbox
|
---|
43 | =============================================================================
|
---|
44 | */
|
---|
45 |
|
---|
46 | MBSend(pmbox, pmsg)
|
---|
47 | register MBOX *pmbox;
|
---|
48 | register MSG *pmsg;
|
---|
49 | {
|
---|
50 | SMWait(&pmbox->mutex); /* ACQUIRE THE MAILBOX */
|
---|
51 |
|
---|
52 | if (pmbox->head) /* is anything in the queue ? */
|
---|
53 | (pmbox->tail)->next = pmsg; /* set next of tail message */
|
---|
54 | else /* ... queue was empty */
|
---|
55 | pmbox->head = pmsg; /* set the head pointer */
|
---|
56 |
|
---|
57 | pmbox->tail = pmsg; /* set the tail pointer */
|
---|
58 | pmsg->next = (MSG *)NIL; /* set next of new message */
|
---|
59 |
|
---|
60 | SMSig(&pmbox->mail); /* signal that there's mail */
|
---|
61 |
|
---|
62 | SMSig(&pmbox->mutex); /* RELEASE THE MAILBOX */
|
---|
63 | }
|
---|
64 |
|
---|
65 | /* |
---|
66 |
|
---|
67 | */
|
---|
68 |
|
---|
69 | /*
|
---|
70 | =============================================================================
|
---|
71 | MBRecv() -- receive a message from a mailbox
|
---|
72 | =============================================================================
|
---|
73 | */
|
---|
74 |
|
---|
75 | MSG *
|
---|
76 | MBRecv(pmbox)
|
---|
77 | register MBOX *pmbox;
|
---|
78 | {
|
---|
79 | register MSG *pmsg;
|
---|
80 |
|
---|
81 | SMWait(&pmbox->mail); /* WAIT FOR SOME MAIL */
|
---|
82 |
|
---|
83 | SMWait(&pmbox->mutex); /* ACQUIRE THE MAILBOX */
|
---|
84 |
|
---|
85 | pmsg = pmbox->head; /* get the first message in the queue */
|
---|
86 |
|
---|
87 | if (pmbox->head EQ pmbox->tail) { /* only message ? */
|
---|
88 |
|
---|
89 | pmbox->head = (MSG *)NIL; /* clear queue head pointer */
|
---|
90 | pmbox->tail = (MSG *)NIL; /* clear queue tail pointer */
|
---|
91 |
|
---|
92 | } else {
|
---|
93 |
|
---|
94 | pmbox->head = pmsg->next; /* update queue head pointer */
|
---|
95 | }
|
---|
96 |
|
---|
97 | pmsg->next = (MSG *)NIL; /* clear next message pointer */
|
---|
98 |
|
---|
99 | SMSig(&pmbox->mutex); /* RELEASE THE MAILBOX */
|
---|
100 |
|
---|
101 | return(pmsg); /* return the address of the message */
|
---|
102 | }
|
---|
103 |
|
---|
104 | /* |
---|
105 |
|
---|
106 | */
|
---|
107 |
|
---|
108 | /*
|
---|
109 | =============================================================================
|
---|
110 | MBChek() -- check for and conditionally receive a message from a mailbox
|
---|
111 |
|
---|
112 | returns NIL if no messages were in the mailbox, or the
|
---|
113 | address of the first (oldest) message in the mailbox,
|
---|
114 | which will be dequeued from the mailbox as if by MBRecv().
|
---|
115 | =============================================================================
|
---|
116 | */
|
---|
117 |
|
---|
118 | MSG *
|
---|
119 | MBChek(pmbox)
|
---|
120 | register MBOX *pmbox;
|
---|
121 | {
|
---|
122 | register MSG *pmsg;
|
---|
123 |
|
---|
124 | if (SMCWait(&pmbox->mail)) { /* try for some mail */
|
---|
125 |
|
---|
126 | SMWait(&pmbox->mutex); /* ACQUIRE THE MAILBOX */
|
---|
127 |
|
---|
128 | pmsg = pmbox->head; /* get the first message in the queue */
|
---|
129 |
|
---|
130 | if (pmbox->head EQ pmbox->tail) { /* only message ? */
|
---|
131 |
|
---|
132 | pmbox->head = (MSG *)NIL; /* clear queue head pointer */
|
---|
133 | pmbox->tail = (MSG *)NIL; /* clear queue tail pointer */
|
---|
134 |
|
---|
135 | } else {
|
---|
136 |
|
---|
137 | pmbox->head = pmsg->next; /* update queue head pointer */
|
---|
138 | }
|
---|
139 |
|
---|
140 | pmsg->next = (MSG *)NIL; /* clear next message pointer */
|
---|
141 |
|
---|
142 | SMSig(&pmbox->mutex); /* RELEASE THE MAILBOX */
|
---|
143 |
|
---|
144 | return(pmsg); /* return the message pointer */
|
---|
145 |
|
---|
146 | } else {
|
---|
147 |
|
---|
148 | return((MSG *)NIL); /* return -- no mail */
|
---|
149 | }
|
---|
150 | }
|
---|
151 |
|
---|
152 | /* |
---|
153 |
|
---|
154 | */
|
---|
155 |
|
---|
156 | /*
|
---|
157 | =============================================================================
|
---|
158 | MBDel() -- delete (cancel) a message from a mailbox
|
---|
159 |
|
---|
160 | FAILURE unable to find the message
|
---|
161 | SUCCESS message found and deleted from mailbox
|
---|
162 | =============================================================================
|
---|
163 | */
|
---|
164 |
|
---|
165 | short
|
---|
166 | MBDel(pmbox, pmsg)
|
---|
167 | register MBOX *pmbox;
|
---|
168 | register MSG *pmsg;
|
---|
169 | {
|
---|
170 | register MSG *mprv, *mcur;
|
---|
171 |
|
---|
172 | if (SMStat(&pmbox->mail) EQ 1) { /* anything in the mailbox ? */
|
---|
173 |
|
---|
174 | SMWait(&pmbox->mutex); /* ACQUIRE THE MAILBOX */
|
---|
175 |
|
---|
176 | mcur = pmbox->head; /* point at the first message */
|
---|
177 |
|
---|
178 | while (TRUE) {
|
---|
179 |
|
---|
180 | mprv = mcur; /* previous MSG = current MSG */
|
---|
181 | mcur = mprv->next; /* current MSG = next MSG */
|
---|
182 |
|
---|
183 | if (mcur EQ (MSG *)NIL) { /* end of queue ? */
|
---|
184 |
|
---|
185 | SMSig(&pmbox->mutex); /* RELEASE MAILBOX */
|
---|
186 |
|
---|
187 | return(FAILURE); /* return -- not found */
|
---|
188 | }
|
---|
189 |
|
---|
190 | if (mcur EQ pmsg) { /* message we want ? */
|
---|
191 |
|
---|
192 | mprv->next = mcur->next; /* dequeue it */
|
---|
193 | mcur->next = (MSG *)NIL; /* ... */
|
---|
194 |
|
---|
195 | SMSig(&pmbox->mutex); /* RELEASE MAILBOX */
|
---|
196 |
|
---|
197 | return(SUCCESS); /* return -- deleted */
|
---|
198 | }
|
---|
199 | }
|
---|
200 |
|
---|
201 | } else {
|
---|
202 |
|
---|
203 | return(FAILURE); /* return -- mailbox emtpy */
|
---|
204 | }
|
---|
205 | }
|
---|