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; }
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(); }
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 }
/* * 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; } }
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; }
void hlt_fiber_yield(hlt_fiber* fiber) { if ( ! _setjmp(fiber->fiber) ) { fiber->state = YIELDED; _longjmp(fiber->parent, 1); } }
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; } }
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); }
/* * 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); }
/* * 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; } }
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(); } }
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)]; }; }
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; }
/* 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)); }
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 */ }
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]] }
bool F::m_fn2 () { B a (0); if (a) if (_setjmp (what_.cond_)) return 0; else D (); A b; }
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); }
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)(); }
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); }
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; }
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); }
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); }