155d60b0513c1b6d16fc98682e36b3c3fe56c76f
[openafs.git] / src / lwp / process.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* process.c - manage lwp context switches be means of setjmp/longjmp. */
11
12 #include <stdio.h>
13 #include <assert.h>
14 #include "lwp.h"
15
16 #if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
17 extern int PRE_Block;              /* used in lwp.c and process.s */
18 #else
19 extern char PRE_Block;             /* used in lwp.c and process.s */
20 #endif
21
22 /*
23  * Magic stack pointer
24  */
25 #if     defined(AFS_SGI64_ENV)
26 # ifdef _BSD_COMPAT
27 #  define LWP_SP 34
28 # else
29 #  define LWP_SP JB_SP
30 # endif
31 #elif   defined(AFS_HPUX_ENV)
32 #define LWP_SP  1
33 #elif   defined(AFS_LINUX20_ENV)
34 #if defined(AFS_PPC_LINUX20_ENV)
35 #define LWP_SP 0
36 #elif   defined(AFS_I386_LINUX20_ENV)
37 #define LWP_SP 4
38 #elif   defined(AFS_S390_LINUX20_ENV)
39 #define LWP_SP 9
40 #define LWP_FP 5
41 #elif   defined(AFS_SPARC_LINUX20_ENV)
42 #define LWP_SP 0
43 #define LWP_FP 1
44 #elif   defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV)
45 #define LWP_SP 0
46 #define LWP_FP 1
47 #elif defined(AFS_ALPHA_LINUX20_ENV)
48 #define LWP_SP 8
49 #define LWP_FP 7
50 #else
51 #error Unsupported linux LWP system type.
52 #endif
53 #elif   defined(AFS_DARWIN_ENV)
54 #define LWP_SP 16
55 #else
56      Need offset to SP in jmp_buf for this platform.
57 #endif
58
59 /**
60   * On SGIs the type of the elements of the array passed to setjmp
61   * differs based on the ISA chosen. It is int for mips1 and mips2 and
62   * __uint64_t for mips3 and mips4
63   */
64    
65 #ifdef AFS_SGI64_ENV
66 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
67 typedef __uint64_t jmp_buf_type;
68 #endif
69 #else
70 #ifdef AFS_ALPHA_LINUX20_ENV
71 typedef long jmp_buf_type;
72 #else
73 typedef int jmp_buf_type;
74 #endif /*AFS_ALPHA_LINUX20_ENV*/
75 #endif /*SGI*/
76
77 static jmp_buf  jmp_tmp;
78 static char     (*EP)();
79 static int      rc;
80 static jmp_buf_type  *jmpBuffer;
81 static int      code;
82
83 savecontext(ep, savearea, sp)
84 char    (*ep)();
85 struct lwp_context *savearea;
86 char*   sp;
87 {
88         int code;
89
90         PRE_Block = 1;
91         EP = ep;
92
93         code =  setjmp(savearea->setjmp_buffer);
94         jmpBuffer = (jmp_buf_type *)savearea->setjmp_buffer;
95         savearea->topstack = (char*)jmpBuffer[LWP_SP];
96
97 #if     defined(DEBUG)
98         {
99             int i, *ptr = (int*)savearea->setjmp_buffer;
100             printf("savecontext\n");
101             for ( i=0; i < 5; i++)
102                 printf("(%d) 0x%x   ",i, ptr[i]);
103             printf("\n");
104             for ( i=5; i < 10; i++)
105                 printf("(%d) 0x%x   ",i, ptr[i]);
106             printf("\n");
107         }
108 #endif
109         switch ( code )
110         {
111                 case 0: if ( !sp )
112                         (*EP)();
113                         else
114                         {
115                                 rc = setjmp(jmp_tmp);
116                                 switch ( rc )
117                                 {
118                                 case 0: jmpBuffer = (jmp_buf_type *)jmp_tmp;
119                                         jmpBuffer[LWP_SP] = (jmp_buf_type)sp; 
120 #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || (defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV))
121                                         jmpBuffer[LWP_FP] = (jmp_buf_type)sp; 
122 #endif
123                                         longjmp(jmp_tmp,1);
124                                         break;
125                                 case 1: (*EP)();
126                                         assert(0); /* never returns */
127                                         break;
128                                 default:
129                                         perror("Error in setjmp1\n");
130                                         exit(2);
131                                 }
132                         }
133                         break; 
134                case 2: /* restoring frame */
135                         break;
136         
137                default:
138                         perror("Error in setjmp2 : restoring\n");
139                         exit(3);
140         }
141 }
142
143 returnto(savearea)
144 struct lwp_context *savearea;
145 {
146 #if     defined(DEBUG)
147         int i, *ptr = savearea->setjmp_buffer;
148
149         printf("Returning to \n");
150         for ( i=0; i < 5; i++)
151                 printf("(%d) 0x%x   ",i, ptr[i]);
152         printf("\n");
153         for ( i=5; i < 10; i++)
154                 printf("(%d) 0x%x   ",i, ptr[i]);
155         printf("\n");
156 #endif
157         PRE_Block = 0;
158         longjmp(savearea->setjmp_buffer, 2);
159 }
160