initial-freebsd-port-work-20010414
[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_X86_FBSD_ENV)
54 #define LWP_SP 4
55 #elif   defined(AFS_DARWIN_ENV)
56 #define LWP_SP 16
57 #else
58      Need offset to SP in jmp_buf for this platform.
59 #endif
60
61 /**
62   * On SGIs the type of the elements of the array passed to setjmp
63   * differs based on the ISA chosen. It is int for mips1 and mips2 and
64   * __uint64_t for mips3 and mips4
65   */
66    
67 #ifdef AFS_SGI64_ENV
68 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
69 typedef __uint64_t jmp_buf_type;
70 #endif
71 #else
72 #ifdef AFS_ALPHA_LINUX20_ENV
73 typedef long jmp_buf_type;
74 #else
75 typedef int jmp_buf_type;
76 #endif /*AFS_ALPHA_LINUX20_ENV*/
77 #endif /*SGI*/
78
79 static jmp_buf  jmp_tmp;
80 static char     (*EP)();
81 static int      rc;
82 static jmp_buf_type  *jmpBuffer;
83 static int      code;
84
85 savecontext(ep, savearea, sp)
86 char    (*ep)();
87 struct lwp_context *savearea;
88 char*   sp;
89 {
90         int code;
91
92         PRE_Block = 1;
93         EP = ep;
94
95         code =  setjmp(savearea->setjmp_buffer);
96         jmpBuffer = (jmp_buf_type *)savearea->setjmp_buffer;
97         savearea->topstack = (char*)jmpBuffer[LWP_SP];
98
99 #if     defined(DEBUG)
100         {
101             int i, *ptr = (int*)savearea->setjmp_buffer;
102             printf("savecontext\n");
103             for ( i=0; i < 5; i++)
104                 printf("(%d) 0x%x   ",i, ptr[i]);
105             printf("\n");
106             for ( i=5; i < 10; i++)
107                 printf("(%d) 0x%x   ",i, ptr[i]);
108             printf("\n");
109         }
110 #endif
111         switch ( code )
112         {
113                 case 0: if ( !sp )
114                         (*EP)();
115                         else
116                         {
117                                 rc = setjmp(jmp_tmp);
118                                 switch ( rc )
119                                 {
120                                 case 0: jmpBuffer = (jmp_buf_type *)jmp_tmp;
121                                         jmpBuffer[LWP_SP] = (jmp_buf_type)sp; 
122 #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || (defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV))
123                                         jmpBuffer[LWP_FP] = (jmp_buf_type)sp; 
124 #endif
125                                         longjmp(jmp_tmp,1);
126                                         break;
127                                 case 1: (*EP)();
128                                         assert(0); /* never returns */
129                                         break;
130                                 default:
131                                         perror("Error in setjmp1\n");
132                                         exit(2);
133                                 }
134                         }
135                         break; 
136                case 2: /* restoring frame */
137                         break;
138         
139                default:
140                         perror("Error in setjmp2 : restoring\n");
141                         exit(3);
142         }
143 }
144
145 returnto(savearea)
146 struct lwp_context *savearea;
147 {
148 #if     defined(DEBUG)
149         int i, *ptr = savearea->setjmp_buffer;
150
151         printf("Returning to \n");
152         for ( i=0; i < 5; i++)
153                 printf("(%d) 0x%x   ",i, ptr[i]);
154         printf("\n");
155         for ( i=5; i < 10; i++)
156                 printf("(%d) 0x%x   ",i, ptr[i]);
157         printf("\n");
158 #endif
159         PRE_Block = 0;
160         longjmp(savearea->setjmp_buffer, 2);
161 }
162