panic() cleanup.
[minix.git] / lib / libsys / asynsend.c
blob7c942edb0b6c9114cb2da6667b2b917c260240dc
2 #define _MINIX 1
3 #define _SYSTEM 1
5 #include <minix/config.h>
6 #include <ansi.h>
7 #include <assert.h>
8 #include <sys/types.h>
9 #include <minix/const.h>
10 #include <minix/type.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <minix/syslib.h>
15 #include <minix/sysutil.h>
17 #include <limits.h>
18 #include <errno.h>
20 #define ASYN_NR 100
21 PRIVATE asynmsg_t msgtable[ASYN_NR];
22 PRIVATE int first_slot= 0, next_slot= 0;
24 PUBLIC int asynsend3(dst, mp, fl)
25 endpoint_t dst;
26 message *mp;
27 int fl;
29 int r, src_ind, dst_ind;
30 unsigned flags;
31 static int first = 1;
32 static int inside = 0;
33 int len;
35 /* printf() causes asynsend? */
36 if(inside) {
37 exit(1);
40 inside = 1;
42 if(first) {
43 int i;
44 for(i = 0; i < ASYN_NR; i++) {
45 msgtable[i].flags = AMF_EMPTY;
47 first = 0;
50 /* Update first_slot */
51 for (; first_slot < next_slot; first_slot++)
53 flags= msgtable[first_slot].flags;
54 if ((flags & (AMF_VALID|AMF_DONE)) == (AMF_VALID|AMF_DONE))
56 if (msgtable[first_slot].result != OK)
58 #if 0
59 printf(
60 "asynsend: found completed entry %d with error %d\n",
61 first_slot,
62 msgtable[first_slot].result);
63 #endif
65 continue;
67 if (flags != AMF_EMPTY)
68 break;
71 if (first_slot >= next_slot)
73 /* Reset first_slot and next_slot */
74 next_slot= first_slot= 0;
77 if (next_slot >= ASYN_NR)
79 /* Tell the kernel to stop processing */
80 r= senda(NULL, 0);
81 if (r != OK)
82 panic("asynsend: senda failed: %d", r);
84 dst_ind= 0;
85 for (src_ind= first_slot; src_ind<next_slot; src_ind++)
87 flags= msgtable[src_ind].flags;
88 if ((flags & (AMF_VALID|AMF_DONE)) ==
89 (AMF_VALID|AMF_DONE))
91 if (msgtable[src_ind].result != OK)
93 #if 0
94 printf(
95 "asynsend: found completed entry %d with error %d\n",
96 src_ind,
97 msgtable[src_ind].result);
98 #endif
100 continue;
102 if (flags == AMF_EMPTY)
103 continue;
104 #if 0
105 printf("asynsend: copying entry %d to %d\n",
106 src_ind, dst_ind);
107 #endif
108 if (src_ind != dst_ind)
109 msgtable[dst_ind]= msgtable[src_ind];
110 dst_ind++;
112 first_slot= 0;
113 next_slot= dst_ind;
114 if (next_slot >= ASYN_NR)
115 panic("asynsend: msgtable full");
118 fl |= AMF_VALID;
119 msgtable[next_slot].dst= dst;
120 msgtable[next_slot].msg= *mp;
121 msgtable[next_slot].flags= fl; /* Has to be last. The kernel
122 * scans this table while we
123 * are sleeping.
125 next_slot++;
127 assert(first_slot < ASYN_NR);
128 assert(next_slot >= first_slot);
129 len = next_slot-first_slot;
130 assert(first_slot + len <= ASYN_NR);
132 /* Tell the kernel to rescan the table */
133 r = senda(msgtable+first_slot, len);
135 inside = 0;
137 return r;