Add helper that reenters vcore context at top of stack
authorAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 8 Jan 2013 20:00:02 +0000 (12:00 -0800)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 8 Jan 2013 20:00:02 +0000 (12:00 -0800)
user/parlib/include/vcore.h
user/parlib/vcore.c

index 549bd8e..db5cba4 100644 (file)
@@ -55,6 +55,7 @@ void vcore_event_init(void);
 void vcore_change_to_m(void);
 int vcore_request(long nr_new_vcores);
 void vcore_yield(bool preempt_pending);
+void vcore_reenter(void (*entry_func)(void));
 void enable_notifs(uint32_t vcoreid);
 void disable_notifs(uint32_t vcoreid);
 void vcore_idle(void);
index 78fb0ab..c0571ea 100644 (file)
@@ -23,6 +23,9 @@ extern void** vcore_thread_control_blocks;
 bool vc_initialized = FALSE;
 __thread struct syscall __vcore_one_sysc = {.flags = (atomic_t)SC_DONE, 0};
 
+/* Per vcore entery function used when reentering at the top of a vcore's stack */
+static __thread void (*__vcore_reentry_func)(void) = NULL;
+
 /* TODO: probably don't want to dealloc.  Considering caching */
 static void free_transition_tls(int id)
 {
@@ -123,6 +126,26 @@ vcore_init_fail:
        assert(0);
 }
 
+/* Helper functions used to reenter at the top of a vcore's stack for an
+ * arbitrary function */
+static void __attribute__((noinline, noreturn)) 
+__vcore_reenter()
+{
+  __vcore_reentry_func();
+  assert(0);
+}
+
+void vcore_reenter(void (*entry_func)(void))
+{
+  assert(in_vcore_context());
+  struct preempt_data *vcpd = vcpd_of(vcore_id());
+
+  __vcore_reentry_func = entry_func;
+  set_stack_pointer((void*)vcpd->transition_stack);
+  cmb();
+  __vcore_reenter();
+}
+
 /* This gets called in glibc before calling the programs 'main'.  Need to set
  * ourselves up so that thread0 is a uthread, and then register basic signals to
  * go to vcore 0. */