Exemple #1
2
static void
h_check(int test)
{
	struct sigaction sa;
	jmp_buf jb;
	sigjmp_buf sjb;
	sigset_t ss;
	int i, x;

	myself = pthread_self();
	i = getpid();

	if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE)
		expectsignal = 0;
	else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE)
		expectsignal = 1;
	else
		atf_tc_fail("unknown test");

	sa.sa_handler = aborthandler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1);
	REQUIRE_ERRNO(sigemptyset(&ss) != -1);
	REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1);
	REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1);
	ATF_REQUIRE(myself == pthread_self());

	if (test == TEST_SETJMP)
		x = setjmp(jb);
	else if (test == TEST_U_SETJMP)
		x = _setjmp(jb);
	else 
		x = sigsetjmp(sjb, !expectsignal);

	if (x != 0) {
		ATF_REQUIRE(myself == pthread_self());
		ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value");
		kill(i, SIGABRT);
		ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed");
		ATF_REQUIRE(myself == pthread_self());
		atf_tc_pass();
	}

	ATF_REQUIRE(myself == pthread_self());
	REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1);

	if (test == TEST_SETJMP)
		longjmp(jb, i);
	else if (test == TEST_U_SETJMP)
		_longjmp(jb, i);
	else 
		siglongjmp(sjb, i);

	atf_tc_fail("jmp failed");
}
void thread_manager_start()
/* call this once after launching at least one thread */
/* this only returns when all threads are blocked! */
{
	current = thread_dequeue( &readylist );
	if (current == thread_null) {
		/* crisis */
		fprintf(stderr, "Thread manager start failure, no threads!\n");
		exit(-1);
	}
	if (_setjmp( thread_death )) {
		/* comes here when _longjmp( thread_death, 1 ) done */
		fprintf(stderr,
			"Thread manager terminated, %s!\n", thread_error );
		if (mem_to_free != (void *)0 ) {
			/* see comments below */
			free( mem_to_free );
		}
	} else {
		/* we will come back here whenever we need to deallocate */
		(void) _setjmp( go_free_it );

		if (mem_to_free != (void *)0 ) {
			/* it's not safe to call free() anywhere but on the
			   real stack, so once the thread manager is running,
			   this is the only safe place to call it!
		        */
			free( mem_to_free );
			mem_to_free = (void *)0;
		}

		_longjmp( current->state, 1 );
	}
}
int
f (void)
{
  static int counter = 0;
  static int way_point1 = 3;
  static int way_point2 = 2;
  int lose = 0;

  if (setjmp (buf1) != 101)
    {
      int a[n_x];		/* reallocate stack space */
      g_counter++;
      p = &a[0];
      if (g_counter < 5)
	longjmp (buf1, 2);
      else if (g_counter == 5)
	longjmp (buf1, 101);
      else
	{
	  _setjmp (buf2);
	  _longjmp (buf1, 101);
	}
    }

  way_point1--;

  if (counter == 0)
    {
      counter++;
      {
	int a[n_x];		/* reallocate stack space */
	g_counter++;
	p = &a[0];
	if (g_counter < 5)
	  longjmp (buf1, 2);
	else if (g_counter == 5)
	  longjmp (buf1, 101);
	else
	  {
	    _setjmp (buf2);
	    _longjmp (buf1, 101);
	  }
      }
    }

  way_point2--;

  if (counter == 1)
    {
      counter++;
      longjmp (buf2, 2);
    }

  lose = !(way_point1 == 0 && way_point2 == 0
	   && g_counter == 6 && counter == 2);

  return lose;
}
Exemple #4
0
void HalGetInitialStackFrame( struct MACHINE_CONTEXT * Context )
{
#ifdef DEBUG
        int status = _setjmp( Context->Registers );
        ASSERT( status == 0 );//We should never wake here.
#else
        _setjmp( Context->Registers );
#endif
}
void probe()
/* purpose:  probe the activation record and jump buffer structure */
{
	int c;
	prior_local = probe_local;
	probe_local = &c;
	_setjmp( *ref_probe );
	ref_probe = &probe_env;
	_setjmp( probe_sameAR );
	(void) boundhigh();
}
Exemple #6
0
void HalGetInitialStackFrame( struct MACHINE_CONTEXT * Context )
{
#ifdef DEBUG
        int status = _setjmp( Context->Registers );
        ASSERT( status == 0 );//We should never wake here.
#else
        _setjmp( Context->Registers );
#endif

#ifdef DEBUG
        //The stack bounderies are infinite for the initial stack.
        Context->High = (char *) -1;
        Context->Low = (char *) 0;
#endif
}
Exemple #7
0
/*
 * sigaltstack will cause this fuction to be called on an alternate stack.
 * This allows us to bootstrap new threads.
 */
void HalStackTrampoline( int SignalNumber )
{
        int status;
        status = _setjmp( halTempContext->Registers );

        if( status == 0 ) {
                //Because status was 0 we know that this is the creation of
                //the stack frame. We can use the locals to construct the frame.

                halTempContextProcessed = TRUE;
                halTempContext = NULL;
                return;
        } else {
                //If we get here, then someone has jumped into a newly created thread.
                //Test to make sure we are atomic
                ASSERT( HalIsIrqAtomic(IRQ_LEVEL_TIMER) );

                StackInitRoutine();

                //Returning from a function which was invoked by siglongjmp is not
                //supported. Foo should never retrun.
                HalPanic("Tried to return from StackInitRoutine!\n", 0 );
                return;
        }
}
Exemple #8
0
enum pause_reason single_step(struct thread *thread)
{
    assert(!InInterpreter);
    assert(thread->status == status_Running);
    assert(thread->suspend_count == 0);

    check_fds(false);

    thread_set_current(thread);
    InInterpreter = true;
    PauseReason = pause_NoReason;
    set_interrupt_handler(set_pause_interrupted);
    if (_setjmp(Catcher) == 0) {
#if SLOW_FUNCTION_POINTERS
        if (thread->advance)
            thread->advance(thread);
        else
            interpret_next_byte(thread);
#else
        thread->advance(thread);
#endif
    }
    InInterpreter = false;
    clear_interrupt_handler();
    if (TimeToGC)
        collect_garbage(false);
    return PauseReason;
}
Exemple #9
0
void hlt_fiber_yield(hlt_fiber* fiber)
{
    if ( ! _setjmp(fiber->fiber) ) {
        fiber->state = YIELDED;
        _longjmp(fiber->parent, 1);
    }
}
Exemple #10
0
void
set_prompt(int to, Source *s)
{
	char *ps1;
	Area *saved_atemp;

	cur_prompt = to;

	switch (to) {
	case PS1: /* command */
		ps1 = str_save(str_val(global("PS1")), ATEMP);
		saved_atemp = ATEMP;	/* ps1 is freed by substitute() */
		newenv(E_ERRH);
		if (_setjmp(e->jbuf)) {
			prompt = safe_prompt;
			/* Don't print an error - assume it has already
			 * been printed.  Reason is we may have forked
			 * to run a command and the child may be
			 * unwinding its stack through this code as it
			 * exits.
			 */
		} else
			prompt = str_save(substitute(ps1, 0),
					 saved_atemp);
		quitenv(NULL);
		break;
	case PS2: /* command continuation */
		prompt = str_val(global("PS2"));
		break;
	}
}
Exemple #11
0
void
db_task_trap(
	int		type,
	int		code,
	boolean_t	user_space)
{
	jmp_buf_t db_jmpbuf;
	jmp_buf_t *prev;
	boolean_t	bkpt;
	boolean_t	watchpt;
	task_t		task;
	task_t		task_space;

	task = db_current_task();
	task_space = db_target_space(current_act(), user_space);
	bkpt = IS_BREAKPOINT_TRAP(type, code);
	watchpt = IS_WATCHPOINT_TRAP(type, code);

	/*
	 * Note:  we look up PC values in an address space (task_space),
	 * but print symbols using a (task-specific) symbol table, found
	 * using task.
	 */
	db_init_default_act();
	db_check_breakpoint_valid();
	if (db_stop_at_pc(&bkpt, task, task_space)) {
	    if (db_inst_count) {
		db_printf("After %d instructions (%d loads, %d stores),\n",
			  db_inst_count, db_load_count, db_store_count);
	    }
	    if (bkpt)
		db_printf("Breakpoint at  ");
	    else if (watchpt)
		db_printf("Watchpoint at  ");
	    else
		db_printf("Stopped at  ");
	    db_dot = PC_REGS(DDB_REGS);

	    prev = db_recover;
	    if (_setjmp(db_recover = &db_jmpbuf) == 0) {
#if defined(__alpha)
		db_print_loc(db_dot, task_space);
		db_printf("\n\t");
		db_print_inst(db_dot, task_space);
#else /* !defined(__alpha) */
#if defined(__powerpc__)
		db_print_loc_and_inst(db_dot, task_space);
#else	/* __powerpc__ */
		db_print_loc_and_inst(db_dot, task);
#endif	/* __powerpc__ */
#endif /* defined(__alpha) */
	    } else
		db_printf("Trouble printing location %#X.\n", db_dot);
	    db_recover = prev;

	    db_command_loop();
	}

	db_restart_at_pc(watchpt, task_space);
}
Exemple #12
0
/*
 * Like read() system call, but is deliberately interruptible.
 * A call to intread() from a signal handler will interrupt
 * any pending iread().
 */
int
iread(int fd, unsigned char *buf, unsigned int len)
{
	int n;
	sigset_t mask;

start:
	if (_setjmp(read_label)) {
		/*
		 * We jumped here from intread.
		 */
		reading = 0;
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, NULL);
		return (READ_INTR);
	}

	flush();
	reading = 1;
	n = read(fd, buf, len);
	reading = 0;
	if (n < 0) {
		/*
		 * Certain values of errno indicate we should just retry the
		 * read.
		 */
		if (errno == EINTR)
			goto start;
		if (errno == EAGAIN)
			goto start;
		return (-1);
	}
	return (n);
}
Exemple #13
0
/*
 * sigaltstack will cause this function to be called on an alternate stack.
 * This allows us to bootstrap new threads.
 */
void HalStackTrampoline( int SignalNumber )
{
        int status;
        //Save stack startup state before releaseing the tempContext.
        STACK_INIT_ROUTINE * foo = halTempContext->Foo;
        void * arg = halTempContext->Arg;

        status = _setjmp( halTempContext->Registers );

        if( status == 0 ) {
                //Because status was 0 we know that this is the creation of
                //the stack frame. We can use the locals to construct the frame.

                halTempContextProcessed = TRUE;
                halTempContext = NULL;
                return;
        } else {
                //If we get here, then someone has jumped into a newly created thread.
                //Test to make sure we are atomic
                ASSERT( HalIsIrqAtomic(IRQ_LEVEL_MAX) );

                foo(arg);

                //Returning from a function which was invoked by siglongjmp is not
                //supported. Foo should never retrun.
                HalPanic("Tried to return from trampoline!");
                return;
        }
}
Exemple #14
0
int8_t hlt_fiber_start(hlt_fiber* fiber, hlt_execution_context* ctx)
{
    int init = (fiber->state == INIT);

    __hlt_context_set_fiber(fiber->context, fiber);

    if ( ! _setjmp(fiber->parent) ) {
        fiber->state = RUNNING;

        if ( init )
            setcontext(&fiber->uctx);
        else
            _longjmp(fiber->fiber, 1);

        abort();
    }

    switch ( fiber->state ) {
     case YIELDED:
        __hlt_memory_safepoint(fiber->context, "fiber_start/yield");
        return 0;

     case IDLE:
        __hlt_memory_safepoint(fiber->context, "fiber_start/done");
        __hlt_context_set_fiber(fiber->context, 0);
        hlt_fiber_delete(fiber, ctx);
        return 1;

     default:
        abort();
    }
}
Exemple #15
0
static SCM vm_debug_engine (SCM vm, SCM program, SCM *argv, int nargs) {
    register scm_t_uint8 *ip ;
    register SCM *sp ;
    register SCM *fp ;
    struct scm_vm *vp = ((struct scm_vm *) ((((scm_t_bits) (0? (*(SCM*)0=((((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=((((vm))))): (((vm)))))))) [((1))]))): (((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=((((vm))))): (((vm)))))))) [((1))]))))));
    static const void **jump_table_pointer = ((void *)0);
    const void **jump_table;
    if (__builtin_expect ((!jump_table_pointer), 0))     {
	jump_table_pointer[0] = &&l_nop;
    }
l_nop:
      {
	SCM *old_sp;
	scm_t_int32 n;
	old_sp = sp;
	sp = (fp - 1) + n;
	if (old_sp < sp)     {
	    while (old_sp < sp)         *++old_sp = ((SCM) ((((((9)) << 8) + scm_tc8_flag))));
	}
	  {
	      { if (__builtin_expect ((vp->trace_level > 0), 0)) { { vp->ip = ip; vp->sp = sp; vp->fp = fp; }; vm_dispatch_hook (vm, SCM_VM_NEXT_HOOK); } };
	  };
      }
      {
	SCM k, prompt;
	if ((_setjmp (((struct scm_prompt_registers*)((((scm_t_bits) (0? (*(SCM*)0=((((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=((((prompt))))): (((prompt)))))))) [((2))]))): (((SCM *)((scm_t_cell *) (((scm_t_bits) (0? (*(SCM*)0=((((prompt))))): (((prompt)))))))) [((2))]))))))->regs)))     {
	      { ip = vp->ip; sp = vp->sp; fp = vp->fp; };
	      { { if (__builtin_expect ((vp->trace_level > 0), 0)) { { vp->ip = ip; vp->sp = sp; vp->fp = fp; }; vm_dispatch_hook (vm, SCM_VM_NEXT_HOOK); } }; ; goto *jump_table[(*ip++) & ((1<<8)-1)]; };
	}
Exemple #16
0
N_NIMCALL(NimStringDesc*, opslurp_379044)(NimStringDesc* file, Tlineinfo162338 info, Tsym190843* module) {
	NimStringDesc* volatile result;
	TSafePoint TMP2884;
	result = 0;
	pushSafePoint(&TMP2884);
	TMP2884.status = _setjmp(TMP2884.context);
	if (TMP2884.status == 0) {
		NimStringDesc* filename;
		Tnodeseq190807* LOC2;
		TY208694 LOC3;
		Tnode190813* LOC4;
		filename = findfile_154341(file);
		result = readfile_13434(filename);
		LOC2 = 0;
		LOC2 = (Tnodeseq190807*) newSeq((&NTI190807), 1);
		memset((void*)LOC3, 0, sizeof(LOC3));
		LOC3[0] = newstrnode_191644(((NU8) 20), filename);
		asgnRefNoCycle((void**) (&LOC2->data[0]), LOC3[0]);
		LOC4 = 0;
		LOC4 = newnode_192607(((NU8) 121), info, LOC2, NIM_NIL);
		appendtomodule_191911(module, LOC4);
		popSafePoint();
	}
	else {
		popSafePoint();
		if (isObj(getCurrentException()->Sup.m_type, (&NTI3431))) {
			TMP2884.status = 0;
			localerror_164171(info, ((NU16) 3), file);
			result = copyString(((NimStringDesc*) &TMP2885));
			popCurrentException();
		}
	}
	if (TMP2884.status != 0) reraiseException();
	return result;
}
Exemple #17
0
/* ctxt is either a pointer to a ucontext_t we generated, or NULL.	*/
void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
				 ptr_t arg)
{
    word dummy;
    void * context = 0;

#   if defined(HAVE_PUSH_REGS)
      GC_push_regs();
#   elif defined(UNIX_LIKE) && !defined(DARWIN) && !defined(ARM32)
      /* Older versions of Darwin seem to lack getcontext(). */
      /* ARM Linux often doesn't support a real getcontext(). */
      ucontext_t ctxt;
      if (getcontext(&ctxt) < 0)
	ABORT ("Getcontext failed: Use another register retrieval method?");
      context = &ctxt;
#     if defined(SPARC) || defined(IA64)
        /* On a register window machine, we need to save register	*/
        /* contents on the stack for this to work.  This may already be	*/
        /* subsumed by the getcontext() call.				*/
        {
          GC_save_regs_ret_val = GC_save_regs_in_stack();
        }
#     endif /* register windows. */
#   elif defined(HAVE_BUILTIN_UNWIND_INIT)
      /* This was suggested by Richard Henderson as the way to	*/
      /* force callee-save registers and register windows onto	*/
      /* the stack.						*/
      __builtin_unwind_init();
#   else /* !HAVE_BUILTIN_UNWIND_INIT && !UNIX_LIKE  */
         /* && !HAVE_PUSH_REGS			     */
        /* Generic code                          */
        /* The idea is due to Parag Patel at HP. */
        /* We're not sure whether he would like  */
        /* to be he acknowledged for it or not.  */
        jmp_buf regs;
        register word * i = (word *) regs;
        register ptr_t lim = (ptr_t)(regs) + (sizeof regs);

        /* Setjmp doesn't always clear all of the buffer.		*/
        /* That tends to preserve garbage.  Clear it.   		*/
	for (; (char *)i < lim; i++) {
	    *i = 0;
	}
#       if defined(MSWIN32) || defined(MSWINCE) \
                  || defined(UTS4) || defined(LINUX) || defined(EWS4800)
	  (void) setjmp(regs);
#       else
          (void) _setjmp(regs);
	  /* We don't want to mess with signals. According to	*/
	  /* SUSV3, setjmp() may or may not save signal mask.	*/
	  /* _setjmp won't, but is less portable.		*/
#       endif
#   endif /* !HAVE_PUSH_REGS ... */
    fn(arg, context);
    /* Strongly discourage the compiler from treating the above	*/
    /* as a tail-call, since that would pop the register 	*/
    /* contents before we get a chance to look at them.		*/
    GC_noop1((word)(&dummy));
}
Exemple #18
0
void e() {
  d.m_fn2();
  try {
    a();
    _setjmp(0);
  } catch (...) {
  }
}
void thread_relinquish()
/* call this within a thread to allow scheduling of a new thread */
{
	if (_setjmp( current->state ) == 0) {
		thread_enqueue( current, &readylist );
		current = thread_dequeue( &readylist );
		_longjmp( current->state, 1 );
	}
}
TEST(setjmp, _setjmp_smoke) {
  int value;
  jmp_buf jb;
  if ((value = _setjmp(jb)) == 0) {
    _longjmp(jb, 456);
    FAIL(); // Unreachable.
  } else {
    ASSERT_EQ(456, value);
  }
}
void thread_free( void * ptr )
/* call this from within threads instead of free, because some
   heap managers are paranoid enough to forbid a call to free
   when the stack itself is in a block allocated in the heap */
{
	mem_to_free = ptr;
	if (_setjmp( current->state ) == 0) {
		_longjmp( go_free_it, 1 );
	}
	/* after call to free(), there will be a longjmp back to here */
}
Exemple #22
0
int test_setjmp() {
  return _setjmp(jb);
  // I386-LABEL: define i32 @test_setjmp
  // I386:       %[[call:.*]] = call i32 (i8*, i32, ...)* @_setjmp3(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i32 0)
  // I386-NEXT:  ret i32 %[[call]]

  // X64-LABEL: define i32 @test_setjmp
  // X64:       %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
  // X64:       %[[call:.*]] = call i32 @_setjmp(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
  // X64-NEXT:  ret i32 %[[call]]
}
Exemple #23
0
bool
F::m_fn2 ()
{
  B a (0);
  if (a)
    if (_setjmp (what_.cond_))
      return 0;
    else
      D ();
  A b;
}
Exemple #24
0
static void fiber_start_fnc(void* p)
{
    fiber_ctx_t* ctx = (fiber_ctx_t*)p;
    void (*volatile ufnc)(void*) = ctx->fnc;
    void* volatile uctx = ctx->ctx;
    if (_setjmp(*ctx->cur) == 0)
    {
        ucontext_t tmp;
        swapcontext(&tmp, ctx->prv);
    }
    ufnc(uctx);
}
Exemple #25
0
PRIVATE void createco_aux(int sig)
{
  Dbg(("CreateCo: running on new coroutine stack (%x), CurrentCo %x", &sig, CurrentCo));
  Dbg(("CreateCo: saving new coroutine state in %x", CurrentCo));
  if (_setjmp(CurrentCo->JmpBuf, 0) == 0)
   { Dbg(("CreateCo: new coroutine, jumping back via %x", CurrentCo->Parent->JmpBuf));
     siglongjmp((sigjmp_buf *) CurrentCo->Parent->JmpBuf, 1);
   }

  Dbg(("New coroutine has been called, CurrentCo %x", CurrentCo));
  forever
   (*CurrentCo->Fun)();
}
Exemple #26
0
static void _fiber_trampoline(unsigned int y, unsigned int x)
{
    hlt_fiber* fiber;

    // Magic from from libtask/task.c to turn the two words back into a pointer.
    unsigned long z;
    z = (x << 16);
    z <<= 16;
    z |= y;
    fiber = (hlt_fiber*)z;

    // Via recycling a fiber can run an arbitrary number of user jobs. So
    // this trampoline is really a loop that yields after it has finished its
    // run() function, and expects a new run function once it's resumed.

    while ( 1 ) {
        assert(fiber->run);

        hlt_fiber_func run = fiber->run;
        void* cookie = fiber->cookie;

        assert(fiber->state == RUNNING);

        if ( ! _setjmp(fiber->trampoline) ) {
            (*run)(fiber, cookie);
        }

        if ( ! _setjmp(fiber->fiber) ) {
            fiber->run = 0;
            fiber->cookie = 0;
            fiber->state = IDLE;
            _longjmp(fiber->parent, 1);
        }
    }

    // Cannot be reached.
    abort();
}
TEST(setjmp, _setjmp_signal_mask) {
  // _setjmp/_longjmp do not save/restore the signal mask.
  SigSets ss;
  sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
  jmp_buf jb;
  if (_setjmp(jb) == 0) {
    sigprocmask(SIG_SETMASK, &ss.two, NULL);
    _longjmp(jb, 1);
    FAIL(); // Unreachable.
  } else {
    AssertSigmaskEquals(ss.two);
  }
  sigprocmask(SIG_SETMASK, &ss.original, NULL);
}
Exemple #28
0
enum pause_reason do_stuff(void)
{
    struct thread *thread;
    volatile int timer;
    volatile bool do_select = true;

    assert (!InInterpreter);

    do {
        if (do_select)
            check_fds(false);
        else
            do_select = true;
        PauseReason = pause_NoReason;
        thread = thread_pick_next();
        if (thread) {
            timer = OPS_PER_TIME_SLICE;
            InInterpreter = true;
            set_interrupt_handler(set_pause_interrupted);
            _setjmp(Catcher);
            if (PauseReason == pause_NoReason)
                while (timer-- > 0) {
#if SLOW_FUNCTION_POINTERS
                    if (thread->advance)
                        thread->advance(thread);
                    else
                        interpret_next_byte(thread);
#else
                    thread->advance(thread);
#endif
                }
            InInterpreter = false;
            clear_interrupt_handler();

            if (TimeToGC)
                collect_garbage(false);
        }
        else if (all_threads() == NULL)
            PauseReason = pause_NothingToRun;
        else {
            set_interrupt_handler(set_pause_interrupted);
            check_fds(true);
            do_select = false;
            clear_interrupt_handler();
        }
    } while (PauseReason == pause_NoReason
             || PauseReason == pause_PickNewThread);
    return PauseReason;
}
Exemple #29
0
WORD CallCo(Coroutine *cortn, word arg)
{
  Dbg(("CallCo: calling coroutine %x, CurrentCo %x", cortn, CurrentCo));
  cortn->Parent		= CurrentCo;
  CurrentCo		= cortn;
  Arg	= arg;

  Dbg(("CallCo: saving current state in %x", cortn->Parent->JmpBuf));
  if (_setjmp(cortn->Parent->JmpBuf) == 0)
   { Dbg(("CallCo: jumping to coroutine via %x", cortn->JmpBuf));
     _longjmp(cortn->JmpBuf, 1);
   }
  else
   return(Arg);
}
Exemple #30
0
WORD WaitCo(word arg)
{ Coroutine	*current	= CurrentCo;

  Dbg(("WaitCo: CurrentCo is %x, parent is %x", CurrentCo, CurrentCo->Parent));
  CurrentCo	= current->Parent;
  Arg		= arg;

  Dbg(("WaitCo: saving current state in %x", current->JmpBuf));
  if (_setjmp(current->JmpBuf, 0) == 0)
   { Dbg(("WaitCo: jumping to parent coroutine via %x", CurrentCo->JmpBuf));
     _longjmp(CurrentCo->JmpBuf, 1);
   }
  else
   return(Arg);
}