]> git.pond.sub.org Git - empserver/commitdiff
Redesign interface to machine-dependent code to cleanse lwp.c of
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 10 Dec 2005 19:28:24 +0000 (19:28 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 10 Dec 2005 19:28:24 +0000 (19:28 +0000)
machine-dependencies:
(lwpNewContext): New, factored out of lwpCreate().
(lwpSwitchContext): New, factored out of lwpReschedule().
(LWP_EXTRASTACK, STKALIGN, lwpInitContext, lwpSave, lwpRestore): Move
to arch.c.  Remove for UCONTEXT, else static linkage unless macro or
AIX32.

(lwpReschedule): Skip lwpStatus() when not actually switching.

(LwpStackGrowsDown): New.
(lwpInitSystem): Initialize it.
(lwpStackCheck, lwpStackCheckUsed): Use it.

src/lib/lwp/arch.c
src/lib/lwp/lwp.c
src/lib/lwp/lwpint.h

index 18810b36cf2c22b157eda49cc9577fd7e106c6e9..8be384d3ae8648058b08eee53fb87d8cf8684d58 100644 (file)
  *     Steve McClure, 1994-2000
  */
 
+#include <stdlib.h>
 #include "lwp.h"
 #include "lwpint.h"
 
 #if defined(_EMPTH_LWP)
 
 /*
- * Implement machine-dependent functions lwpInitContext(), lwpSave(),
- * lwpRestore().
- *
- * If lwpSave() and lwpRestore() are #def'd to setjmp() and longjmp(),
- * then lwpInitContext() needs to set up the jmp_buf for a longjmp(),
- * similar to setjmp().  To figure that out for another machine, check
- * their source or reverse engineer.
+ * Implement machine-dependent functions lwpNewContext(),
+ * lwpSwitchContext().
  */
 
 
 #if defined UCONTEXT
+
 /*
- * Alternate aproach using setcontext and getcontext instead of setjmp and
- * longjump. This should work on any SVr4 machine independant of
- * architecture.  Unfortunately some changes are still nessesary in lwp.c.
- * Tested on IRIX 5.3
+ * Alternate aproach using setcontext and getcontext instead of setjmp
+ * and longjump.  This should work on any SVr4 machine independant of
+ * architecture.
  */
 
-void
-lwpInitContext(struct lwpProc *newp, stack_t *spp)
+int
+lwpNewContext(struct lwpProc *newp, int stacksz)
 {
-    getcontext(&newp->context);
-    newp->context.uc_stack = *spp;
+    char *s;
+    int size, redsize;
+
+    /* Make size a multiple of sizeof(long) to keep things aligned */
+    stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
+    /* Add a red zone on each side of the stack for LWP_STACKCHECK */
+    redsize = newp->flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
+    size = stacksz + 2 * redsize;
+
+    s = malloc(size);
+    if (!s)
+       return -1;
+
+    newp->sbtm = s;
+    newp->size = size;
+    newp->ustack = s + redsize;
+    newp->usize = stacksz;
+
+    if (getcontext(&newp->context) < 0)
+       return -1;
+    newp->context.uc_stack.ss_sp = newp->ustack;
+    newp->context.uc_stack.ss_size = newp->usize;
+    newp->context.uc_stack.ss_flags = 0;
     newp->context.uc_link = NULL;
     makecontext(&newp->context, lwpEntryPoint, 0);
+    return 0;
 }
 
-#elif defined(hpc)
+void
+lwpSwitchContext(struct lwpProc *oldp, struct lwpProc *nextp)
+{
+    if (!oldp) {
+       setcontext(&nextp->context);
+       abort();
+    } else {
+       if (swapcontext(&oldp->context, &nextp->context) < 0)
+           abort();
+    }
+}
+
+#else  /* !UCONTEXT */
+
+/*
+ * If lwpSave() and lwpRestore() are #def'd to setjmp() and longjmp(),
+ * then lwpInitContext() needs to set up the jmp_buf for a longjmp(),
+ * similar to setjmp().  To figure that out for another machine, check
+ * their source or reverse engineer.
+ */
+
+#if defined(hpc)
+
+#define STKALIGN 64
 
 static struct lwpProc *tempcontext;
 static struct lwpProc *initcontext = NULL;
@@ -87,7 +128,7 @@ startcontext(void)
     lwpEntryPoint();
 }
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
     struct lwpProc holder;
@@ -115,7 +156,7 @@ lwpInitContext(struct lwpProc *newp, void *sp)
     }
 }
 
-int
+static int
 lwpSave(jmp_buf jb)
 {
     int endpoint;
@@ -136,13 +177,15 @@ lwpSave(jmp_buf jb)
 
 #elif defined(hpux)
 
-void
+#define STKALIGN 64
+
+static void
 lwpInitContext(volatile struct lwpProc *volatile newp, void *sp)
 {
     static jmp_buf *cpp;
 
     if (!lwpSave(LwpCurrent->context)) {
-       cpp = (jmp_buf *) & newp->context;
+       cpp = (jmp_buf *)&newp->context;
        asm volatile ("ldw      %0, %%sp"::"o" (sp));
        if (!lwpSave(*cpp))
            lwpRestore(LwpCurrent->context);
@@ -150,7 +193,7 @@ lwpInitContext(volatile struct lwpProc *volatile newp, void *sp)
     }
 }
 
-int
+static int
 lwpSave(jmp_buf jb)
 {
     /* save stack pointer and return program counter */
@@ -185,7 +228,7 @@ lwpSave(jmp_buf jb)
     asm(".LABEL _comefrom_");
 }
 
-void
+static void
 lwpRestore(jmp_buf jb)
 {
     /* restore stack pointer and program counter */
@@ -221,7 +264,7 @@ lwpRestore(jmp_buf jb)
 
 #elif defined(FBSD)
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
     setjmp(newp->context);
@@ -232,7 +275,7 @@ lwpInitContext(struct lwpProc *newp, void *sp)
 
 #elif defined(__linux__)
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
 #if defined(__GLIBC__) && (__GLIBC__ >= 2)
@@ -253,7 +296,7 @@ lwpInitContext(struct lwpProc *newp, void *sp)
 
 #elif defined(SUN3)
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
     newp->context[2] = (int)sp;
@@ -262,7 +305,7 @@ lwpInitContext(struct lwpProc *newp, void *sp)
 
 #elif defined(SUN4)
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
     static jmp_buf *cpp;
@@ -287,11 +330,14 @@ lwpInitContext(struct lwpProc *newp, void *sp)
     }
 }
 
+#define        lwpSave(x)      _setjmp(x)
+#define lwpRestore(x)  _longjmp(x, 1)
+
 #elif defined(ALPHA)
 
 #include <c_asm.h>
 
-void
+static void
 lwpInitContext(struct lwpProc *newp, void *sp)
 {
     extern long *_gp;
@@ -304,13 +350,13 @@ lwpInitContext(struct lwpProc *newp, void *sp)
     newp->context[34] = (long)sp;      /* stack pointer */
 }
 
-int
+static int
 lwpSave(jmp_buf jb)
 {
     return _setjmp(jb);
 }
 
-void
+static void
 lwpRestore(jmp_buf jb)
 {
     /* resume, but get the pv from the jmp_buf */
@@ -321,7 +367,94 @@ lwpRestore(jmp_buf jb)
 }
 
 #elif defined(AIX32)
+
+#define        LWP_EXTRASTACK 12
+
 /* Code is in .s files, as compiler doesn't grok asm */
+extern int lwpSave(jmp_buf);
+extern void lwpRestore(jmp_buf);
+extern void lwpInitContext(struct lwpProc *);
+
 #endif
 
+#ifndef LWP_EXTRASTACK
+#define LWP_EXTRASTACK 0
+#endif
+#ifndef STKALIGN
+#define STKALIGN sizeof(double)
+#endif
+#ifndef lwpSave
+#define lwpSave(x)     setjmp(x)
+#endif
+#ifndef lwpRestore
+#define lwpRestore(x)  longjmp(x, 1)
+#endif
+
+int
+lwpNewContext(struct lwpProc *newp, int stacksz)
+{
+    char *s, *sp;
+    int size, redsize;
+
+    if (CANT_HAPPEN(STKALIGN == 0|| (STKALIGN & (STKALIGN - 1))))
+       return -1;              /* STKALIGN not power of 2 */
+
+    /* Make size a multiple of sizeof(long) to keep things aligned */
+    stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
+    /* Add a red zone on each side of the stack for LWP_STACKCHECK */
+    redsize = newp->flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
+    size = stacksz + 2 * redsize + LWP_EXTRASTACK + STKALIGN - 1;
+
+    s = malloc(size);
+    if (!s)
+       return -1;
+
+    if (LwpStackGrowsDown) {
+       /*
+        * Stack layout for stack growing downward:
+        *     ptr        block      size
+        *     --------------------------------------
+        *                red zone   LWP_REDZONE
+        *     sp      -> extra      LWP_EXTRASTACK
+        *     ustack  -> stack      stacksz
+        *                red zone   LWP_REDZONE
+        *                waste      STKALIGN - 1 - x
+        * sp is aligned to a multiple of STKALIGN.
+        */
+       sp = s + redsize + stacksz;
+       sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
+       newp->ustack = sp - stacksz;
+    } else {
+       /*
+        * Stack layout for stack growing upward:
+        *     ptr        block      size
+        *     --------------------------------------
+        *                waste      x
+        *                red zone   LWP_REDZONE
+        *     sp      -> stack      stacksz
+        *     ustack  -> extra      LWP_EXTRASTACK
+        *                red zone   LWP_REDZONE
+        *                waste      STKALIGN - 1 - x
+        * sp is aligned to a multiple of STKALIGN.
+        */
+       sp = s + redsize + LWP_EXTRASTACK;
+       sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
+       newp->ustack = sp - LWP_EXTRASTACK;
+    }
+    newp->sbtm = s;
+    newp->size = size;
+    newp->usize = stacksz + LWP_EXTRASTACK;
+    lwpInitContext(newp, sp);
+    return 0;
+}
+
+void
+lwpSwitchContext(struct lwpProc *oldp, struct lwpProc *nextp)
+{
+    if (!(oldp && lwpSave(oldp->context)))
+       lwpRestore(nextp->context);
+}
+
+#endif /* !UCONTEXT */
+
 #endif
index 0a802e69e18b6e4bec67ec2d420577ef82b44f98..1288a28534bd37710b4280e2353c526f6d05f4cb 100644 (file)
@@ -36,6 +36,7 @@ struct lwpQueue LwpSchedQ[LWP_MAX_PRIO], LwpDeadQ;
 struct lwpProc *LwpCurrent = NULL;
 char **LwpContextPtr;
 int LwpMaxpri = 0;             /* maximum priority so far */
+int LwpStackGrowsDown;
 
 static sigset_t oldmask;
 
@@ -107,16 +108,14 @@ lwpReschedule(void)
        fprintf(stderr, "No processes to run!\n");
        exit(1);
     }
-    if (LwpCurrent)
-       lwpStatus(LwpCurrent, "switch out");
-    /* do context switch */
-    i = LwpCurrent && lwpSave(LwpCurrent->context);
-    if (LwpCurrent != nextp && !i) {
-       /* restore previous context */
-       lwpStatus(nextp, "switch in %d", nextp->pri);
+    if (LwpCurrent != nextp) {
+       struct lwpProc *oldp = LwpCurrent;
+       if (oldp)
+           lwpStatus(oldp, "switch out");
        LwpCurrent = nextp;
-       *LwpContextPtr = LwpCurrent->ud;
-       lwpRestore(LwpCurrent->context);
+       *LwpContextPtr = nextp->ud;
+       lwpSwitchContext(oldp, nextp);
+       lwpStatus(nextp, "switch in %d", nextp->pri);
     }
 }
 
@@ -145,23 +144,9 @@ struct lwpProc *
 lwpCreate(int priority, void (*entry)(void *), int stacksz, int flags, char *name, char *desc, int argc, char **argv, void *ud)
 {
     struct lwpProc *newp;
-    char *s, *sp;
-    int size, redsize, x;
-#ifdef UCONTEXT
-    stack_t usp;
-#endif /* UCONTEXT */
-
-    if (CANT_HAPPEN(STKALIGN == 0|| (STKALIGN & (STKALIGN - 1))))
-       return NULL;            /* STKALIGN not power of 2 */
+
     if (!(newp = malloc(sizeof(struct lwpProc))))
        return 0;
-    /* Make size a multiple of sizeof(long) to keep things aligned */
-    stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
-    /* Add a red zone on each side of the stack for LWP_STACKCHECK */
-    redsize = flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
-    size = stacksz + 2 * redsize + LWP_EXTRASTACK + STKALIGN - 1;
-    if (!(s = malloc(size)))
-       return 0;
     newp->flags = flags;
     newp->name = strdup(name);
     newp->desc = strdup(desc);
@@ -169,61 +154,18 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz, int flags, char *nam
     newp->argc = argc;
     newp->argv = argv;
     newp->ud = ud;
-    if (growsdown(&x)) {
-       /*
-        * Stack layout for stack growing downward:
-        *     ptr        block      size
-        *     --------------------------------------
-        *                waste      x
-        *                red zone   LWP_REDZONE
-        *     sp      -> extra      LWP_EXTRASTACK
-        *     ustack  -> stack      stacksz
-        *                red zone   LWP_REDZONE
-        *                waste      STKALIGN - 1 - x
-        * sp is aligned to a multiple of STKALIGN.
-        */
-       sp = s + redsize + stacksz;
-       sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
-       newp->ustack = sp - stacksz;
-    } else {
-       /*
-        * Stack layout for stack growing upward:
-        *     ptr        block      size
-        *     --------------------------------------
-        *                waste      x
-        *                red zone   LWP_REDZONE
-        *     sp      -> stack      stacksz
-        *     ustack  -> extra      LWP_EXTRASTACK
-        *                red zone   LWP_REDZONE
-        *                waste      STKALIGN - 1 - x
-        * sp is aligned to a multiple of STKALIGN.
-        */
-       sp = s + redsize + LWP_EXTRASTACK;
-       sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
-       newp->ustack = sp - LWP_EXTRASTACK;
-    }
-    newp->usize = stacksz + LWP_EXTRASTACK;
+    newp->dead = 0;
     if (LWP_MAX_PRIO <= priority)
        priority = LWP_MAX_PRIO - 1;
     if (LwpMaxpri < (newp->pri = priority))
        LwpMaxpri = priority;
-    newp->sbtm = s;
-    newp->size = size;
-    newp->dead = 0;
-    if (flags & LWP_STACKCHECK)
-       lwpStackCheckInit(newp);
+    lwpNewContext(newp, stacksz);
     lwpStatus(newp, "creating process structure %p (sbtm %p)",
              newp, newp->sbtm);
+    if (flags & LWP_STACKCHECK)
+       lwpStackCheckInit(newp);
     lwpReady(newp);
     lwpReady(LwpCurrent);
-#ifdef UCONTEXT
-    usp.ss_sp = s + redsize;
-    usp.ss_size = stacksz;
-    usp.ss_flags = 0;
-    lwpInitContext(newp, &usp);        /* architecture-dependent: from arch.c */
-#else  /* UCONTEXT */
-    lwpInitContext(newp, sp);  /* architecture-dependent: from arch.c */
-#endif /* UCONTEXT */
     lwpReschedule();
     return newp;
 }
@@ -352,13 +294,14 @@ struct lwpProc *
 lwpInitSystem(int pri, char **ctxptr, int flags)
 {
     struct lwpQueue *q;
-    int i, *stack;
+    int i, *stack, marker;
     struct lwpProc *sel;
 
     LwpContextPtr = ctxptr;
     if (pri < 1)
        pri = 1;
     /* *LwpContextPtr = 0; */
+    LwpStackGrowsDown = growsdown(&marker);
     if (!(LwpCurrent = calloc(1, sizeof(struct lwpProc))))
        return 0;
     if (!(stack = malloc(64)))
@@ -410,7 +353,7 @@ lwpStackCheck(struct lwpProc *newp)
     int *btm = (int *)(newp->ustack - LWP_REDZONE);
     int *top = (int *)(newp->ustack + newp->usize + LWP_REDZONE);
     int n = LWP_REDZONE / sizeof(int);
-    int i, lo_clean, hi_clean, marker, overflow, underflow;
+    int i, lo_clean, hi_clean, overflow, underflow;
 
     for (i = 0; i < n && btm[i] == LWP_CHECKMARK; i++) ;
     lo_clean = i;
@@ -418,7 +361,7 @@ lwpStackCheck(struct lwpProc *newp)
     for (i = 1; i <= n && top[-i] == LWP_CHECKMARK; i++) ;
     hi_clean = i - 1;
 
-    if (growsdown(&marker)) {
+    if (LwpStackGrowsDown) {
        overflow = n - lo_clean;
        underflow = n - hi_clean;
     } else {
@@ -445,9 +388,9 @@ lwpStackCheckUsed(struct lwpProc *newp)
     int *base = (int *)newp->ustack;
     int *lim = (int *)(newp->ustack + newp->usize);
     int total = (lim + 1 - base) * sizeof(int);
-    int marker, used, *p;
+    int used, *p;
 
-    if (growsdown(&marker)) {
+    if (LwpStackGrowsDown) {
        for (p = base; p < lim && *p == LWP_CHECKMARK; ++p) ;
        used = (lim - p) * sizeof(int);
     } else {
index 3786699f3a5d5c7f024fdce1d6bbc3b0589af033..5991f211e19e8da4aa67b2a60f79728fab321330 100644 (file)
@@ -73,50 +73,15 @@ struct lwpSem {
     char *name;
 };
 
-#ifdef UCONTEXT
-void lwpInitContext(struct lwpProc *, stack_t *);
-#define lwpSave(x)    getcontext(&(x))
-#define lwpRestore(x) setcontext(&(x))
-#else  /* !UCONTEXT */
-#if defined(hpux) && !defined(hpc)
-void lwpInitContext(volatile struct lwpProc * volatile, void *);
-#else
-void lwpInitContext(struct lwpProc *, void *);
-#endif
-#if defined(hpc)
-int lwpSave(jmp_buf);
-#define lwpRestore(x)  longjmp(x, 1)
-#elif defined(hpux) || defined(AIX32) || defined(ALPHA)
-int lwpSave(jmp_buf);
-void lwpRestore(jmp_buf);
-#elif defined(SUN4)
-#define        lwpSave(x)      _setjmp(x)
-#define lwpRestore(x)  _longjmp(x, 1)
-#else
-#define        lwpSave(x)      setjmp(x)
-#define lwpRestore(x)  longjmp(x, 1)
-#endif
-#endif /* !UCONTEXT */
-
-#ifdef AIX32
-/* AIX needs 12 extra bytes above the stack; we add it here */
-#define        LWP_EXTRASTACK  3*sizeof(long)
-#else
-#define LWP_EXTRASTACK 0
-#endif
-
 #define LWP_REDZONE    1024    /* make this a multiple of 1024 */
 
 /* XXX Note that this assumes sizeof(long) == 4 */
 #define LWP_CHECKMARK  0x5a5a5a5aL
 
-#ifdef hpux
-#define STKALIGN 64
-#else
-#define STKALIGN sizeof(double)
-#endif
+extern int LwpStackGrowsDown;
 
-/* internal routines */
+int lwpNewContext(struct lwpProc *, int);
+void lwpSwitchContext(struct lwpProc *, struct lwpProc *);
 void lwpAddTail(struct lwpQueue *, struct lwpProc *);
 struct lwpProc *lwpGetFirst(struct lwpQueue *);
 void lwpReady(struct lwpProc *);