afsconfig-and-rcsid-all-around-20010705
[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 <afs/param.h>
13 #include <afsconfig.h>
14
15 RCSID("$Header$");
16
17 #include <stdio.h>
18 #include <assert.h>
19 #include "lwp.h"
20 #ifdef HAVE_STDLIB_H
21 #include <stdlib.h>
22 #endif
23
24 #if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
25 extern int PRE_Block;              /* used in lwp.c and process.s */
26 #else
27 extern char PRE_Block;             /* used in lwp.c and process.s */
28 #endif
29
30 /*
31  * Magic stack pointer
32  */
33 #if     defined(AFS_SGI64_ENV)
34 # ifdef _BSD_COMPAT
35 #  define LWP_SP 34
36 # else
37 #  define LWP_SP JB_SP
38 # endif
39 #elif   defined(AFS_HPUX_ENV)
40 #define LWP_SP  1
41 #elif   defined(AFS_LINUX20_ENV)
42 #if defined(AFS_PPC_LINUX20_ENV)
43 #define LWP_SP 0
44 #elif   defined(AFS_I386_LINUX20_ENV)
45 #define LWP_SP 4
46 #elif   defined(AFS_S390_LINUX20_ENV)
47 #define LWP_SP 9
48 #define LWP_FP 5
49 #elif   defined(AFS_SPARC_LINUX20_ENV)
50 #define LWP_SP 0
51 #define LWP_FP 1
52 #elif   defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV)
53 #define LWP_SP 0
54 #define LWP_FP 1
55 #elif defined(AFS_ALPHA_LINUX20_ENV)
56 #define LWP_SP 8
57 #define LWP_FP 7
58 #else
59 #error Unsupported linux LWP system type.
60 #endif
61 #elif   defined(AFS_X86_FBSD_ENV)
62 #define LWP_SP 4
63 #elif   defined(AFS_DARWIN_ENV)
64 #define LWP_SP 16
65 #else
66      Need offset to SP in jmp_buf for this platform.
67 #endif
68
69 /**
70   * On SGIs the type of the elements of the array passed to setjmp
71   * differs based on the ISA chosen. It is int for mips1 and mips2 and
72   * __uint64_t for mips3 and mips4
73   */
74    
75 #ifdef AFS_SGI64_ENV
76 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
77 typedef __uint64_t jmp_buf_type;
78 #endif
79 #else
80 #ifdef AFS_ALPHA_LINUX20_ENV
81 typedef long jmp_buf_type;
82 #else
83 typedef int jmp_buf_type;
84 #endif /*AFS_ALPHA_LINUX20_ENV*/
85 #endif /*SGI*/
86
87 static jmp_buf  jmp_tmp;
88 static char     (*EP)();
89 static int      rc;
90 static jmp_buf_type  *jmpBuffer;
91
92 afs_int32 savecontext(ep, savearea, sp)
93 char    (*ep)();
94 struct lwp_context *savearea;
95 char*   sp;
96 {
97         int code;
98
99         PRE_Block = 1;
100         EP = ep;
101
102         code =  setjmp(savearea->setjmp_buffer);
103         jmpBuffer = (jmp_buf_type *)savearea->setjmp_buffer;
104         savearea->topstack = (char*)jmpBuffer[LWP_SP];
105
106 #if     defined(DEBUG)
107         {
108             int i, *ptr = (int*)savearea->setjmp_buffer;
109             printf("savecontext\n");
110             for ( i=0; i < 5; i++)
111                 printf("(%d) 0x%x   ",i, ptr[i]);
112             printf("\n");
113             for ( i=5; i < 10; i++)
114                 printf("(%d) 0x%x   ",i, ptr[i]);
115             printf("\n");
116         }
117 #endif
118         switch ( code )
119         {
120                 case 0: if ( !sp )
121                         (*EP)();
122                         else
123                         {
124                                 rc = setjmp(jmp_tmp);
125                                 switch ( rc )
126                                 {
127                                 case 0: jmpBuffer = (jmp_buf_type *)jmp_tmp;
128                                         jmpBuffer[LWP_SP] = (jmp_buf_type)sp; 
129 #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || (defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV))
130                                         jmpBuffer[LWP_FP] = (jmp_buf_type)sp; 
131 #endif
132                                         longjmp(jmp_tmp,1);
133                                         break;
134                                 case 1: (*EP)();
135                                         assert(0); /* never returns */
136                                         break;
137                                 default:
138                                         perror("Error in setjmp1\n");
139                                         exit(2);
140                                 }
141                         }
142                         break; 
143                case 2: /* restoring frame */
144                         break;
145         
146                default:
147                         perror("Error in setjmp2 : restoring\n");
148                         exit(3);
149         }
150         return 0;
151 }
152
153 afs_int32 returnto(savearea)
154 struct lwp_context *savearea;
155 {
156 #if     defined(DEBUG)
157         int i, *ptr = savearea->setjmp_buffer;
158
159         printf("Returning to \n");
160         for ( i=0; i < 5; i++)
161                 printf("(%d) 0x%x   ",i, ptr[i]);
162         printf("\n");
163         for ( i=5; i < 10; i++)
164                 printf("(%d) 0x%x   ",i, ptr[i]);
165         printf("\n");
166 #endif
167         PRE_Block = 0;
168         longjmp(savearea->setjmp_buffer, 2);
169         return 0;
170 }
171