+#ifdef CONTEXT_THREADS
+
+ self = current_context;
+
+ if (is_main_thread()) {
+ /* the main thread has called this function
+ * - update the current context
+ * - signal the condition of the process to run
+ * - wait on its condition
+ * - restore thr current contex
+ */
+
+ xbt_os_mutex_lock(master_mutex);
+ xbt_os_mutex_lock(context->mutex);
+
+ /* update the current context */
+ current_context = context;
+ xbt_os_cond_signal(context->cond);
+ xbt_os_mutex_unlock(context->mutex);
+
+ xbt_os_cond_wait(master_cond, master_mutex);
+ xbt_os_mutex_unlock(master_mutex);
+ /* retore the current context */
+ current_context = self;
+
+ } else {
+ /* a java thread has called this function
+ * - update the current context
+ * - signal the condition of the main thread
+ * - wait on its condition
+ * - restore thr current contex
+ */
+
+ xbt_os_mutex_lock(master_mutex);
+ xbt_os_mutex_lock(context->mutex);
+ /* update the current context */
+ current_context = context;
+ xbt_os_cond_signal(master_cond);
+ xbt_os_mutex_unlock(master_mutex);
+ xbt_os_cond_wait(context->cond, context->mutex);
+ xbt_os_mutex_unlock(context->mutex);
+ /* retore the current context */
+ current_context = self;
+ }
+
+#else /* use SUSv2 contexts */
+ VOIRP(current_context);
+ VOIRP(current_context->save);
+
+ VOIRP(context);
+ VOIRP(context->save);
+
+ int return_value = 0;
+
+ if (context->save == NULL) {
+ DEBUG1("[%p] **** Yielding to somebody else ****", current_context);
+ DEBUG2("Saving current_context value (%p) to context(%p)->save",
+ current_context, context);
+ context->save = current_context;
+ DEBUG1("current_context becomes context(%p) ", context);
+ current_context = context;
+ DEBUG1
+ ("Current position memorized (context->save). Jumping to context (%p)",
+ context);
+ return_value = swapcontext(&(context->save->uc), &(context->uc));
+ xbt_assert0((return_value == 0), "Context swapping failure");
+ DEBUG1("I am (%p). Coming back\n", context);
+ } else {
+ xbt_context_t old_context = context->save;
+
+ DEBUG1("[%p] **** Back ! ****", context);
+ DEBUG2("Setting current_context (%p) to context(%p)->save",
+ current_context, context);
+ current_context = context->save;
+ DEBUG1("Setting context(%p)->save to NULL", context);
+ context->save = NULL;
+ DEBUG2("Current position memorized (%p). Jumping to context (%p)",
+ context, old_context);
+ return_value = swapcontext(&(context->uc), &(old_context->uc));
+ xbt_assert0((return_value == 0), "Context swapping failure");
+ DEBUG1("I am (%p). Coming back\n", context);
+ }
+#endif
+
+ if (current_context->iwannadie)
+ xbt_context_stop(1);
+}
+
+
+
+
+
+/**
+ * Calling this function makes the current context yield. The context
+ * that scheduled it returns from xbt_context_schedule as if nothing
+ * had happened.
+ *
+ * Only the processes can call this function, giving back the control
+ * to the maestro
+ */
+void xbt_context_yield(void)
+{
+ __xbt_context_yield(current_context);
+}
+
+/**
+ * \param context the winner
+ *
+ * Calling this function blocks the current context and schedule \a context.
+ * When \a context will call xbt_context_yield, it will return
+ * to this function as if nothing had happened.
+ *
+ * Only the maestro can call this function to run a given process.
+ */
+void xbt_context_schedule(xbt_context_t context)
+{
+ DEBUG1("Scheduling %p", context);
+ xbt_assert0((current_context == init_context),
+ "You are not supposed to run this function here!");
+ __xbt_context_yield(context);
+}
+
+
+/**
+ * \param context poor victim
+ *
+ * This function simply kills \a context... scarry isn't it ?
+ */
+void xbt_context_kill(xbt_context_t context)
+{
+ DEBUG1("Killing %p", context);
+
+ context->iwannadie = 1;
+
+ DEBUG1("Scheduling %p", context);
+ __xbt_context_yield(context);
+ DEBUG1("End of Scheduling %p", context);