We provide our own model_swapcontext() for Mac OSX.
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
--- /dev/null
+/**
+ * @file context.h
+ * @brief ucontext header, since Mac OSX swapcontext() is broken
+ */
+
+#ifndef __CONTEXT_H__
+#define __CONTEXT_H__
+
+#include <ucontext.h>
+
+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__ */
#define __MODEL_H__
#include <cstddef>
-#include <ucontext.h>
#include <inttypes.h>
#include "mymemory.h"
#include "config.h"
#include "modeltypes.h"
#include "stl-model.h"
+#include "context.h"
/* Forward declaration */
class Node;
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
-#include <ucontext.h>
#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); }
#else /* !USE_MPROTECT_SNAPSHOT */
-#include <ucontext.h>
-
#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
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;
static snapshot_id fork_take_snapshot()
{
- swapcontext(&savedUserSnapshotContext, &savedSnapshotContext);
+ model_swapcontext(&savedUserSnapshotContext, &savedSnapshotContext);
DEBUG("TAKESNAPSHOT RETURN\n");
return snapshotid;
}
#ifndef __THREADS_MODEL_H__
#define __THREADS_MODEL_H__
-#include <ucontext.h>
#include <stdint.h>
#include "mymemory.h"
#include <threads.h>
#include "modeltypes.h"
#include "stl-model.h"
+#include "context.h"
struct thread_params {
thrd_start_t func;
int Thread::swap(Thread *t, ucontext_t *ctxt)
{
t->set_state(THREAD_READY);
- return swapcontext(&t->context, ctxt);
+ return model_swapcontext(&t->context, 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);
}