Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / lwp / process.c
1 /* Copyright Transarc Corporation 1998 - All Rights Reserved */
2
3 /* process.c - manage lwp context switches be means of setjmp/longjmp. */
4
5 #include <stdio.h>
6 #include <assert.h>
7 #include "lwp.h"
8
9 #ifdef  AFS_OSF_ENV
10 extern int PRE_Block;              /* used in lwp.c and process.s */
11 #else
12 extern char PRE_Block;             /* used in lwp.c and process.s */
13 #endif
14
15 /*
16  * Magic stack pointer
17  */
18 #if     defined(AFS_SGI64_ENV)
19 # ifdef _BSD_COMPAT
20 #  define LWP_SP 34
21 # else
22 #  define LWP_SP JB_SP
23 # endif
24 #elif   defined(AFS_HPUX_ENV)
25 #define LWP_SP  1
26 #elif   defined(AFS_LINUX20_ENV)
27 #define LWP_SP 4
28 #else
29      Need offset to SP in jmp_buf for this platform.
30 #endif
31
32 /**
33   * On SGIs the type of the elements of the array passed to setjmp
34   * differs based on the ISA chosen. It is int for mips1 and mips2 and
35   * __uint64_t for mips3 and mips4
36   */
37    
38 #ifdef AFS_SGI64_ENV
39 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
40 typedef __uint64_t jmp_buf_type;
41 #endif
42 #else
43 typedef int jmp_buf_type;
44 #endif
45
46 static jmp_buf  jmp_tmp;
47 static char     (*EP)();
48 static int      rc;
49 static jmp_buf_type  *jmpBuffer;
50 static int      code;
51
52 savecontext(ep, savearea, sp)
53 char    (*ep)();
54 struct lwp_context *savearea;
55 char*   sp;
56 {
57         int code;
58
59         PRE_Block = 1;
60         EP = ep;
61
62         code =  setjmp(savearea->setjmp_buffer);
63         jmpBuffer = (jmp_buf_type *)savearea->setjmp_buffer;
64         savearea->topstack = (char*)jmpBuffer[LWP_SP];
65
66 #if     defined(DEBUG)
67         {
68             int i, *ptr = (int*)savearea->setjmp_buffer;
69             printf("savecontext\n");
70             for ( i=0; i < 5; i++)
71                 printf("(%d) 0x%x   ",i, ptr[i]);
72             printf("\n");
73             for ( i=5; i < 10; i++)
74                 printf("(%d) 0x%x   ",i, ptr[i]);
75             printf("\n");
76         }
77 #endif
78         switch ( code )
79         {
80                 case 0: if ( !sp )
81                         (*EP)();
82                         else
83                         {
84                                 rc = setjmp(jmp_tmp);
85                                 switch ( rc )
86                                 {
87                                 case 0: jmpBuffer = (jmp_buf_type *)jmp_tmp;
88                                         jmpBuffer[LWP_SP] = (jmp_buf_type)sp; 
89                                         longjmp(jmp_tmp,1);
90                                         break;
91                                 case 1: (*EP)();
92                                         assert(0); /* never returns */
93                                         break;
94                                 default:
95                                         perror("Error in setjmp1\n");
96                                         exit(2);
97                                 }
98                         }
99                         break; 
100                case 2: /* restoring frame */
101                         break;
102         
103                default:
104                         perror("Error in setjmp2 : restoring\n");
105                         exit(3);
106         }
107 }
108
109 returnto(savearea)
110 struct lwp_context *savearea;
111 {
112 #if     defined(DEBUG)
113         int i, *ptr = savearea->setjmp_buffer;
114
115         printf("Returning to \n");
116         for ( i=0; i < 5; i++)
117                 printf("(%d) 0x%x   ",i, ptr[i]);
118         printf("\n");
119         for ( i=5; i < 10; i++)
120                 printf("(%d) 0x%x   ",i, ptr[i]);
121         printf("\n");
122 #endif
123         PRE_Block = 0;
124         longjmp(savearea->setjmp_buffer, 2);
125 }
126