#define _MINIX 1 #define _SYSTEM 1 #include #include #include #include #include #include #include #include #include #include #include #include #define ASYN_NR 100 PRIVATE asynmsg_t msgtable[ASYN_NR]; PRIVATE int first_slot= 0, next_slot= 0; PUBLIC int asynsend3(dst, mp, fl) endpoint_t dst; message *mp; int fl; { int r, src_ind, dst_ind; unsigned flags; static int first = 1; static int inside = 0; int len; /* printf() causes asynsend? */ if(inside) { exit(1); } inside = 1; if(first) { int i; for(i = 0; i < ASYN_NR; i++) { msgtable[i].flags = AMF_EMPTY; } first = 0; } /* Update first_slot */ for (; first_slot < next_slot; first_slot++) { flags= msgtable[first_slot].flags; if ((flags & (AMF_VALID|AMF_DONE)) == (AMF_VALID|AMF_DONE)) { if (msgtable[first_slot].result != OK) { #if 0 printf( "asynsend: found completed entry %d with error %d\n", first_slot, msgtable[first_slot].result); #endif } continue; } if (flags != AMF_EMPTY) break; } if (first_slot >= next_slot) { /* Reset first_slot and next_slot */ next_slot= first_slot= 0; } if (next_slot >= ASYN_NR) { /* Tell the kernel to stop processing */ r= senda(NULL, 0); if (r != OK) panic("asynsend: senda failed: %d", r); dst_ind= 0; for (src_ind= first_slot; src_ind= ASYN_NR) panic("asynsend: msgtable full"); } fl |= AMF_VALID; msgtable[next_slot].dst= dst; msgtable[next_slot].msg= *mp; msgtable[next_slot].flags= fl; /* Has to be last. The kernel * scans this table while we * are sleeping. */ next_slot++; assert(first_slot < ASYN_NR); assert(next_slot >= first_slot); len = next_slot-first_slot; assert(first_slot + len <= ASYN_NR); /* Tell the kernel to rescan the table */ r = senda(msgtable+first_slot, len); inside = 0; return r; }