00001 /* 00002 * Empire - A multi-player, client/server Internet based war game. 00003 * Copyright (C) 1994-2007, Dave Pare, Jeff Bailey, Thomas Ruschak, 00004 * Ken Stevens, Steve McClure 00005 * Copyright (C) 1991-3 Stephen Crane 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * --- 00022 * 00023 * See files README, COPYING and CREDITS in the root of the source 00024 * tree for related information and legal notices. It is expected 00025 * that future projects/authors will amend these files as needed. 00026 * 00027 * --- 00028 * 00029 * arch.c: architecture-dependant process context code 00030 * 00031 * Known contributors to this file: 00032 * Dave Pare, 1994 00033 * Steve McClure, 1994-2000 00034 * Markus Armbruster, 2004-2007 00035 */ 00036 00037 #include <config.h> 00038 00039 #include <stdlib.h> 00040 #include "lwp.h" 00041 #include "lwpint.h" 00042 00043 /* 00044 * Historically, this was implemented by abusing setjmp() and 00045 * longjump(), which required a fair amount of system-dependent and 00046 * fragile hackery. We now use POSIX ucontext.h. 00047 */ 00048 00049 int 00050 lwpNewContext(struct lwpProc *newp, int stacksz) 00051 { 00052 char *s; 00053 int size, redsize; 00054 00055 /* Make size a multiple of sizeof(long) to keep things aligned */ 00056 stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long); 00057 /* Add a red zone on each side of the stack for LWP_STACKCHECK */ 00058 redsize = newp->flags & LWP_STACKCHECK ? LWP_REDZONE : 0; 00059 size = stacksz + 2 * redsize; 00060 00061 s = malloc(size); 00062 if (!s) 00063 return -1; 00064 00065 newp->sbtm = s; 00066 newp->size = size; 00067 newp->ustack = s + redsize; 00068 newp->usize = stacksz; 00069 00070 if (getcontext(&newp->context) < 0) { 00071 free(s); 00072 return -1; 00073 } 00074 #ifdef MAKECONTEXT_SP_HIGH 00075 /* 00076 * Known systems that are broken that way: Solaris prior to 10, 00077 * IRIX. 00078 */ 00079 newp->context.uc_stack.ss_sp = newp->ustack + stacksz - 8; 00080 #else 00081 newp->context.uc_stack.ss_sp = newp->ustack; 00082 #endif 00083 newp->context.uc_stack.ss_size = newp->usize; 00084 newp->context.uc_stack.ss_flags = 0; 00085 newp->context.uc_link = NULL; 00086 makecontext(&newp->context, lwpEntryPoint, 0); 00087 return 0; 00088 } 00089 00090 void 00091 lwpSwitchContext(struct lwpProc *oldp, struct lwpProc *nextp) 00092 { 00093 if (!oldp) { 00094 setcontext(&nextp->context); 00095 abort(); 00096 } else { 00097 if (swapcontext(&oldp->context, &nextp->context) < 0) 00098 abort(); 00099 } 00100 }
1.5.2