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"); }
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; }
void siglongjmp(sigjmp_buf env, int val) { #ifdef SIGJMP_OLD if(__sigjmp_old) { struct jmpbuf *oenv = (struct jmpbuf *)env; if(oenv->__flg) { SignalProcmask_r(0, 0, SIG_SETMASK, (sigset_t *)(void *)oenv->__msk, 0); } _longjmp(oenv->__buf, val); } #endif if(env->__flg) { SignalProcmask_r(0, 0, SIG_SETMASK, (sigset_t *)(void *)env->__msk, 0); } _longjmp(env, val); }
/* xljump - jump to a saved execution context */ void xljump(XLCONTEXT *target, int mask, LVAL val) { /* unwind the execution stack */ for (; xlcontext != target; xlcontext = xlcontext->c_xlcontext) /* check for an UNWIND-PROTECT */ if ((xlcontext->c_flags & CF_UNWIND)) { xltarget = target; xlmask = mask; break; } /* restore the state */ xlstack = xlcontext->c_xlstack; xlenv = xlcontext->c_xlenv; xlfenv = xlcontext->c_xlfenv; xlunbind(xlcontext->c_xldenv); xlargv = xlcontext->c_xlargv; xlargc = xlcontext->c_xlargc; xlfp = xlcontext->c_xlfp; xlsp = xlcontext->c_xlsp; xlvalue = val; /* call the handler */ _longjmp(xlcontext->c_jmpbuf,mask); }
void hlt_fiber_yield(hlt_fiber* fiber) { if ( ! _setjmp(fiber->fiber) ) { fiber->state = YIELDED; _longjmp(fiber->parent, 1); } }
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(); } }
void thread_exit() /* call this within a thread to terminate that thread */ { /* we can't deallocate, so we schedule this thread for deallocation */ mem_to_free = (void *)current; /* now, get the next thread to run */ current = thread_dequeue( &readylist ); if (current == thread_null) { /* crisis */ thread_error = "ready list empty"; _longjmp( thread_death, 1 ); } _longjmp( go_free_it, 1 ); }
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 ); } }
void segv_handler(int sig) { fprintf(stderr, "*** Caught a segfault during stack trace sampling!\n"); assert(saved_handler); _longjmp(saved_location, 1); }
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 ); } }
/* _setjmp_test2 */ static void __setjmp_test2(void) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif _ret = 4; _longjmp(_jb, 5); _ret = 6; }
reset() { indent(); if(get_yes_no("Confirm delete all operations and reset variables")) { print("All operations specified have been deleted.\n"); exdent(-1); _longjmp(reset_environ, 1); } exdent(1); }
void thread_wait( struct thread_semaphore * s ) /* call this within a thread to block on a semaphore */ { if (s->count > 0) { s->count--; } else { if (_setjmp( current->state ) == 0) { thread_enqueue( current, &s->queue ); current = thread_dequeue( &readylist ); if (current == thread_null) { /* crisis */ thread_error = "possible deadlock"; _longjmp( thread_death, 1 ); } _longjmp( current->state, 1 ); } } }
void thread_safety_check() /* call this to check for thread stack overflow */ { long int t = (long int)current + sizeof(struct thread); if ( ((long int)&t < t) || ((long int)&t > (t + current->size)) ) { /* crisis */ thread_error = "thread stack overflow"; _longjmp( thread_death, 1 ); } }
int test30() { if (j) longjmp(test30_j, 1); else #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) longjmp(test30_j, 2); #else _longjmp(test30_j, 1); #endif }
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 */ }
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); }
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); }
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); }
void dispatch() { sigset_t waitmask; sigemptyset(&waitmask); sigaddset(&waitmask,SIGUSR1); if (enadsp && (!runtsk || (runtsk != schedtsk && _setjmp(runtsk->tskctxb.env) == 0))) { while (!(runtsk = schedtsk)) { sigsuspend(&waitmask); } _longjmp(runtsk->tskctxb.env, 1); }else{ calltex(); } }
void x_raise(error *e) { sigjmp_buf *jmp = pthread_getspecific(g_except_key); //No handler, simply abort if (jmp == NULL) { printf("%s\n",errorMsg(e)); abort(); } errorAssert(pthread_setspecific(g_error_key, e) == 0, error_create, "Failed setting key to error"); _longjmp(*jmp, 1); }
u2_noun u2_cm_bail(c3_l how_l) { u2_ray kit_r = u2_wire_kit_r(u2_Wire); if ( u2_yes == u2_Flag_Abort ) { if ( c3__fail == how_l ) { c3_assert(0); } c3_assert(0); } u2_tx_sys_bit(u2_Wire, u2_yes); // fprintf(stderr, "bail\n"); // if ( _num == 0 ) { c3_assert(0); } else _num--; { u2_noun jaq; jmp_buf buf_f; // Reset the old stack trace, pulling off the local top. // jaq = u2_cm_wail(); // Reset the old action trace. { u2z(u2_wrac_at(u2_Wire, duz.don)); u2_wrac_at(u2_Wire, duz.don) = u2_kite_don(kit_r); } // Copy out the jump buffer; free the old kite. { memcpy((void *)buf_f, u2_at_cord(u2_kite_buf_r(kit_r), c3_wiseof(jmp_buf)), sizeof(jmp_buf)); u2_wire_kit_r(u2_Wire) = u2_kite_par_r(kit_r); u2_rl_rfree(u2_Wire, kit_r); } // Longjmp with the how-trace pair. XX: no workee with 64-bit nouns. // { _longjmp(buf_f, u2nc(how_l, jaq)); } } return 0; }
/* * Performs a context switch between one MACHINE_CONTEXT (thread) and another. * Because want to avoid having interrupts fire while the register file is in an intermidiate * state, all regilar interrupts should be disabled when calling this function. */ void HalContextSwitch(struct MACHINE_CONTEXT * oldStack, struct MACHINE_CONTEXT * newStack) { int status; ASSERT( HalIsIrqAtomic(IRQ_LEVEL_MAX) ); //Save the stack state into old context. status = _setjmp( oldStack->Registers ); if( status == 0 ) { //This was the saving call to setjmp. _longjmp( newStack->Registers, 1 ); } else { //This was the restore call started by longjmp call. //We have just switched into a different thread. } ASSERT( HalIsIrqAtomic(IRQ_LEVEL_MAX) ); }
/* u2_cm_bowl(): bail out with preset report. */ u2_noun u2_cm_bowl(u2_noun how) { u2_ray kit_r = u2_wire_kit_r(u2_Wire); u2_tx_sys_bit(u2_Wire, u2_yes); { u2_noun jaq; jmp_buf buf_f; // Reset the old stack trace, pulling off the local top. // jaq = u2_cm_wail(); // Reset the old action trace. { u2z(u2_wrac_at(u2_Wire, duz.don)); u2_wrac_at(u2_Wire, duz.don) = u2_kite_don(kit_r); } // Copy out the jump buffer; free the old kite. { memcpy((void *)buf_f, u2_at_cord(u2_kite_buf_r(kit_r), c3_wiseof(jmp_buf)), sizeof(jmp_buf)); u2_wire_kit_r(u2_Wire) = u2_kite_par_r(kit_r); u2_rl_rfree(u2_Wire, kit_r); } // Longjmp with the how-trace pair. XX: no workee with 64-bit nouns. // { u2z(jaq); _longjmp(buf_f, how); } } return 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(); }
void hlt_fiber_return(hlt_fiber* fiber) { __hlt_context_set_fiber(fiber->context, 0); _longjmp(fiber->trampoline, 1); }
/* Catch SEGV's when poking at memory */ static void segv_handler (int number) { _longjmp(trap_environment, -1); }
MINDY_NORETURN void go_on(void) { assert(InInterpreter); _longjmp(Catcher, 1); }
/* * Interrupt a pending iread(). */ void intread(void) { _longjmp(read_label, 1); }