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