src/lib/lwp/arch.c

Go to the documentation of this file.
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 }

Generated on Fri Mar 28 11:01:14 2008 for empserver by  doxygen 1.5.2