2 * Copyright 2000, International Business Machines Corporation and others.
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
10 /* process.c - manage lwp context switches be means of setjmp/longjmp. */
12 #include <afsconfig.h>
13 #include <afs/param.h>
25 #if defined(AFS_OSF_ENV) || defined(AFS_S390_LINUX20_ENV)
26 extern int PRE_Block; /* used in lwp.c and process.s */
28 extern char PRE_Block; /* used in lwp.c and process.s */
31 #if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H)
34 savecontext(char (*ep) (), struct lwp_context *savearea, char *newsp)
36 #if defined(AFS_IA64_LINUX20_ENV)
37 register unsigned long sp __asm__("r12");
38 #elif defined(AFS_AMD64_LINUX24_ENV)
39 register unsigned long sp __asm__("sp");
40 #elif defined(AFS_HPUX1122_ENV)
41 /* don't need anything special, will use
42 * ucontext.uc_stack.ss_sp as it matches r12.
43 * This should also work for Linux,
44 * but dont have system to test DEE
47 #error "You need to update stack pointer register for this platform"
53 getcontext(&savearea->ucontext);
54 #if defined(AFS_HPUX1122_ENV)
55 savearea->topstack = savearea->ucontext.uc_stack.ss_sp;
57 savearea->topstack = sp;
59 switch (savearea->state) {
65 thread.uc_stack.ss_sp =
66 newsp - AFS_LWP_MINSTACKSIZE + sizeof(void *) +
68 thread.uc_stack.ss_size = AFS_LWP_MINSTACKSIZE - sizeof(void *);
69 makecontext(&thread, ep, 0);
82 struct lwp_context *savearea;
87 setcontext(&savearea->ucontext);
95 #if defined(AFS_SGI64_ENV)
101 #elif defined(AFS_HPUX_ENV) || defined(AFS_PARISC_LINUX24_ENV)
103 #elif defined(AFS_LINUX20_ENV)
104 #if defined(AFS_PPC_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
106 #elif defined(AFS_I386_LINUX20_ENV)
108 #elif defined(AFS_S390_LINUX20_ENV)
111 #elif defined(AFS_SPARC_LINUX20_ENV)
114 #elif defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV)
117 #elif defined(AFS_ALPHA_LINUX20_ENV)
120 #elif defined(AFS_PARISC_LINUX24_ENV)
123 #error Unsupported linux LWP system type.
125 #elif defined(AFS_X86_FBSD_ENV)
127 #elif defined(AFS_DARWIN_ENV)
130 Need offset to SP in jmp_buf for this platform.
133 * On SGIs the type of the elements of the array passed to setjmp
134 * differs based on the ISA chosen. It is int for mips1 and mips2 and
135 * __uint64_t for mips3 and mips4
138 #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4)
139 typedef __uint64_t jmp_buf_type;
142 #if defined(AFS_ALPHA_LINUX20_ENV) || defined(AFS_PPC64_LINUX20_ENV)
143 typedef long jmp_buf_type;
145 typedef int jmp_buf_type;
146 #endif /*AFS_ALPHA_LINUX20_ENV */
149 static jmp_buf jmp_tmp;
150 static char (*EP) ();
152 static jmp_buf_type *jmpBuffer;
155 savecontext(ep, savearea, sp)
157 struct lwp_context *savearea;
165 code = setjmp(savearea->setjmp_buffer);
166 jmpBuffer = (jmp_buf_type *) savearea->setjmp_buffer;
167 savearea->topstack = (char *)jmpBuffer[LWP_SP];
171 int i, *ptr = (int *)savearea->setjmp_buffer;
172 printf("savecontext\n");
173 for (i = 0; i < 5; i++)
174 printf("(%d) 0x%x ", i, ptr[i]);
176 for (i = 5; i < 10; i++)
177 printf("(%d) 0x%x ", i, ptr[i]);
186 rc = setjmp(jmp_tmp);
189 jmpBuffer = (jmp_buf_type *) jmp_tmp;
190 jmpBuffer[LWP_SP] = (jmp_buf_type) sp;
191 #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || (defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV))
192 jmpBuffer[LWP_FP] = (jmp_buf_type) sp;
198 assert(0); /* never returns */
201 perror("Error in setjmp1\n");
206 case 2: /* restoring frame */
210 perror("Error in setjmp2 : restoring\n");
217 returnto(struct lwp_context * savearea)
220 int i, *ptr = savearea->setjmp_buffer;
222 printf("Returning to \n");
223 for (i = 0; i < 5; i++)
224 printf("(%d) 0x%x ", i, ptr[i]);
226 for (i = 5; i < 10; i++)
227 printf("(%d) 0x%x ", i, ptr[i]);
231 longjmp(savearea->setjmp_buffer, 2);