summaryrefslogtreecommitdiffstats
path: root/src/libthread/proctab.ch
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-11-08 16:03:42 +0000
committerrsc <devnull@localhost>2004-11-08 16:03:42 +0000
commitcf4f3eafc6016ccdb57773215dcdd5ebac95c07d (patch)
tree8ec61fb34fb6a0fe9d7bd79c65487b9a1ec4bb81 /src/libthread/proctab.ch
parent195645536743aeb99eb336726823c38716cec02d (diff)
downloadplan9port-cf4f3eafc6016ccdb57773215dcdd5ebac95c07d.tar.gz
plan9port-cf4f3eafc6016ccdb57773215dcdd5ebac95c07d.zip
extra files
Diffstat (limited to 'src/libthread/proctab.ch')
-rw-r--r--src/libthread/proctab.ch97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/libthread/proctab.ch b/src/libthread/proctab.ch
new file mode 100644
index 00000000..d51543f9
--- /dev/null
+++ b/src/libthread/proctab.ch
@@ -0,0 +1,97 @@
+/*
+ * 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;
+}