From: Brian Norris Date: Thu, 4 Apr 2013 02:27:06 +0000 (-0700) Subject: swapcontext() fix for Mac OSX X-Git-Url: http://plrg.eecs.uci.edu/git/?p=cdsspec-compiler.git;a=commitdiff_plain;h=2b004336a919f74a5ca8f6d87ad5414360a949c7 swapcontext() fix for Mac OSX We provide our own model_swapcontext() for Mac OSX. --- diff --git a/common.mk b/common.mk index b2adf4c..9fe9f09 100644 --- a/common.mk +++ b/common.mk @@ -8,11 +8,9 @@ UNAME = $(shell uname) LIB_NAME = model LIB_SO = lib$(LIB_NAME).so -CPPFLAGS += -Wall -g +CPPFLAGS += -Wall -g -O3 # Mac OSX options ifeq ($(UNAME), Darwin) -CPPFLAGS += -D_XOPEN_SOURCE -DMAC -O0 -else -CPPFLAGS += -O3 +CPPFLAGS += -D_XOPEN_SOURCE -DMAC endif diff --git a/context.h b/context.h new file mode 100644 index 0000000..862cda5 --- /dev/null +++ b/context.h @@ -0,0 +1,37 @@ +/** + * @file context.h + * @brief ucontext header, since Mac OSX swapcontext() is broken + */ + +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ + +#include + +static inline int model_swapcontext(ucontext_t *oucp, ucontext_t *ucp) +{ +#ifdef MAC + /* + * Mac OSX swapcontext() clobbers some registers, so use a hand-rolled + * version with {get,set}context(). We can avoid the same problem + * (where optimizations can break the following code) because we don't + * statically link with the C library + */ + + /* volatile, so that 'i' doesn't get promoted to a register */ + volatile int i = 0; + + getcontext(oucp); + + if (i == 0) { + i = 1; + setcontext(ucp); + } + + return 0; +#else + return swapcontext(oucp, ucp); +#endif +} + +#endif /* __CONTEXT_H__ */ diff --git a/model.h b/model.h index cbd1027..12ec06c 100644 --- a/model.h +++ b/model.h @@ -6,7 +6,6 @@ #define __MODEL_H__ #include -#include #include #include "mymemory.h" @@ -15,6 +14,7 @@ #include "config.h" #include "modeltypes.h" #include "stl-model.h" +#include "context.h" /* Forward declaration */ class Node; diff --git a/snapshot.cc b/snapshot.cc index fb1f911..ba1c090 100644 --- a/snapshot.cc +++ b/snapshot.cc @@ -6,12 +6,12 @@ #include #include #include -#include #include "hashtable.h" #include "snapshot.h" #include "mymemory.h" #include "common.h" +#include "context.h" #define FAILURE(mesg) { model_print("failed in the API: %s with errno relative message: %s\n", mesg, strerror(errno)); exit(EXIT_FAILURE); } @@ -247,8 +247,6 @@ static void mprot_roll_back(snapshot_id theID) #else /* !USE_MPROTECT_SNAPSHOT */ -#include - #define SHARED_MEMORY_DEFAULT (100 * ((size_t)1 << 20)) // 100mb for the shared memory #define STACK_SIZE_DEFAULT (((size_t)1 << 20) * 20) // 20 mb out of the above 100 mb for my stack @@ -325,7 +323,7 @@ static void fork_snapshot_init(unsigned int numbackingpages, newContext.uc_stack.ss_size = STACK_SIZE_DEFAULT; makecontext(&newContext, entryPoint, 0); /* switch to a new entryPoint context, on a new stack */ - swapcontext(&savedSnapshotContext, &newContext); + model_swapcontext(&savedSnapshotContext, &newContext); /* switch back here when takesnapshot is called */ pid_t forkedID = 0; @@ -369,7 +367,7 @@ static void fork_snapshot_init(unsigned int numbackingpages, static snapshot_id fork_take_snapshot() { - swapcontext(&savedUserSnapshotContext, &savedSnapshotContext); + model_swapcontext(&savedUserSnapshotContext, &savedSnapshotContext); DEBUG("TAKESNAPSHOT RETURN\n"); return snapshotid; } diff --git a/threads-model.h b/threads-model.h index ef2c9e1..5fc6d67 100644 --- a/threads-model.h +++ b/threads-model.h @@ -5,13 +5,13 @@ #ifndef __THREADS_MODEL_H__ #define __THREADS_MODEL_H__ -#include #include #include "mymemory.h" #include #include "modeltypes.h" #include "stl-model.h" +#include "context.h" struct thread_params { thrd_start_t func; diff --git a/threads.cc b/threads.cc index 5bfd028..ae2905a 100644 --- a/threads.cc +++ b/threads.cc @@ -93,7 +93,7 @@ int Thread::create_context() int Thread::swap(Thread *t, ucontext_t *ctxt) { t->set_state(THREAD_READY); - return swapcontext(&t->context, ctxt); + return model_swapcontext(&t->context, ctxt); } /** @@ -107,7 +107,7 @@ int Thread::swap(Thread *t, ucontext_t *ctxt) int Thread::swap(ucontext_t *ctxt, Thread *t) { t->set_state(THREAD_RUNNING); - return swapcontext(ctxt, &t->context); + return model_swapcontext(ctxt, &t->context); }