| /* |
| * Proc structure hash table indexed by proctabid() (usually getpid()). |
| * No lock is necessary for lookups (important when called from signal |
| * handlers). |
| * |
| * To be included from other files (e.g., Linux-clone.c). |
| */ |
| |
| #define T ((void*)-1) |
| |
| enum |
| { |
| PTABHASH = 1031, |
| }; |
| |
| static Lock ptablock; |
| static Proc *proctab[PTABHASH]; |
| static Proc *theproc; |
| static int multi; |
| |
| void |
| _threadmultiproc(void) |
| { |
| if(multi == 0){ |
| multi = 1; |
| _threadsetproc(theproc); |
| } |
| } |
| |
| void |
| _threadsetproc(Proc *p) |
| { |
| int i, h; |
| Proc **t; |
| |
| if(!multi){ |
| theproc = p; |
| return; |
| } |
| lock(&ptablock); |
| p->procid = procid(); |
| h = p->procid%PTABHASH; |
| for(i=0; i<PTABHASH; i++){ |
| t = &proctab[(h+i)%PTABHASH]; |
| if(*t==nil || *t==T){ |
| *t = p; |
| break; |
| } |
| } |
| unlock(&ptablock); |
| if(i == PTABHASH) |
| sysfatal("too many procs - proctab is full"); |
| } |
| |
| static Proc** |
| _threadfindproc(int id) |
| { |
| int i, h; |
| Proc **t; |
| |
| if(!multi) |
| return &theproc; |
| |
| h = id%PTABHASH; |
| for(i=0; i<PTABHASH; i++){ |
| t = &proctab[(h+i)%PTABHASH]; |
| if(*t != nil && *t != T && (*t)->procid == id){ |
| unlock(&ptablock); |
| return t; |
| } |
| } |
| return nil; |
| } |
| |
| Proc* |
| _threadgetproc(void) |
| { |
| Proc **t; |
| |
| t = _threadfindproc(procid()); |
| if(t == nil) |
| return nil; |
| return *t; |
| } |
| |
| Proc* |
| _threaddelproc(void) |
| { |
| Proc **t, *p; |
| |
| t = _threadfindproc(procid()); |
| if(t == nil) |
| return nil; |
| p = *t; |
| *t = T; |
| return p; |
| } |