/* * This needs to be callable from a signal handler, so it has been * written to avoid locks. The only lock is the one used to acquire * an entry in the table, and we make sure that acquiring is done * when not in a handler. Lookup and delete do not need locks. * It's a scan-forward hash table. To avoid breaking chains, * T ((void*)-1) is used as a non-breaking nil. */ #include #include #include "9proc.h" enum { PIDHASH = 1021 }; #define T ((void*)-1) static Uproc *alluproc[PIDHASH]; static int allupid[PIDHASH]; static Lock uproclock; Uproc* _p9uproc(int inhandler) { int i, h, pid; Uproc *up; /* for now, assume getpid is fast or cached */ pid = getpid(); /* * this part - the lookup - needs to run without locks * so that it can safely be called from within the notify handler. * notify calls _p9uproc, and fork and rfork call _p9uproc * in both parent and child, so if we're in a signal handler, * we should find something in the table. */ h = pid%PIDHASH; for(i=0; ipid = pid; lock(&uproclock); h = pid%PIDHASH; for(i=0; i