[3ae31e9] | 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 | }
|
---|