//POSIX signal handler. void handler(int c) { seh_info *act_seh_object=NULL; int curr_seh_index = 0; //get lastest seh. its active. curr_seh_index = g_seh_index - 1; //check for valid seh. if (curr_seh_index < 0) { //we aren't in SEH_TRY scope. go to invalid handler. LONGJMP(g_invalid_handler,0); return; } else { //serious problem! if (!g_sehs[curr_seh_index]._is_in_seh_area) { if (g_failhandler) g_failhandler(); } } //guard cricital area seh_guard(); //we are in the guarded area. g_sync.guarded_in_handler = 1; act_seh_object = &g_sehs[curr_seh_index]; //if used SEH_CATCH_EX, we must detect to exception type. if (act_seh_object->_exception_type_ptr) { switch (c) { case SIGFPE: *act_seh_object->_exception_type_ptr = CSEH_FPE_FAULT; break; case SIGSEGV: *act_seh_object->_exception_type_ptr = CSEH_SEGMENTATION_FAULT; break; case SIGILL: *act_seh_object->_exception_type_ptr = CSEH_ILLEGAL_INSTRUCTION; break; } } //mark to raised. act_seh_object->_exception_raised = 1; //continue with restored context LONGJMP(act_seh_object->_context,0); }
SCM_EXPORT void scm_call_continuation(ScmObj cont, ScmObj ret) { struct scm_continuation_frame *frame; #if SCM_NESTED_CONTINUATION_ONLY ScmObj dst; #endif DECLARE_INTERNAL_FUNCTION("scm_call_continuation"); frame = CONTINUATION_FRAME(cont); if (frame != INVALID_CONTINUATION_OPAQUE #if SCM_NESTED_CONTINUATION_ONLY && (dst = continuation_stack_unwind(cont), CONTINUATIONP(dst)) #endif ) { /* Don't refer cont because it may already be invalidated by * continuation_stack_unwind(). */ exit_dynamic_extent(frame->dyn_ext); frame->ret_val = ret; LONGJMP(frame->c_env, scm_true); /* NOTREACHED */ } else { ERR("expired continuation"); } }
static void NORET jumpfun(RCNTXT * cptr, int mask, SEXP val) { Rboolean savevis = R_Visible; /* run onexit/cend code for all contexts down to but not including the jump target */ PROTECT(val); cptr->returnValue = val;/* in case the on.exit code wants to see it */ R_run_onexits(cptr); UNPROTECT(1); R_Visible = savevis; R_ReturnedValue = val; R_GlobalContext = cptr; /* this used to be set to cptr->nextcontext for non-toplevel jumps (with the context set back at the SETJMP for restarts). Changing this to always using cptr as the new global context should simplify some code and perhaps allow loops to be handled with fewer SETJMP's. LT */ R_restore_globals(R_GlobalContext); LONGJMP(cptr->cjmpbuf, mask); }
int SC_signal_async(int sig) {int rv; conpool *cp; asyncstate *cs; GET_CLIENT_STATE(cs); rv = TRUE; cp = cs->pool; if (cp != NULL) {if (cp->active == TRUE) {switch (sig) {case SIGUSR1 : sig = SIGINT; rv = FALSE; SC_show_pool_logs(cp, -1); break; case SIGUSR2 : sig = SIGINT; rv = FALSE; SC_show_pool_stats(cp, -1, TRUE); break;}; if (rv == TRUE) LONGJMP(cp->cpu, sig);};}; return(rv);}
extern void read_date(int *py, int *pm, int *pd) { int y = 0, m = 0, d = 0; filepos fp_date; skipblanks(); get_pos(&fp_date); y = read_uint_internal(/*Expecting date, found “%s”*/198, &fp_date); /* Two digit year is 19xx. */ if (y < 100) y += 1900; if (y < 1900 || y > 2078) { set_pos(&fp_date); compile_diagnostic(DIAG_WARN|DIAG_UINT, /*Invalid year (< 1900 or > 2078)*/58); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } if (ch == '.') { filepos fp; nextch(); get_pos(&fp); m = read_uint_internal(/*Expecting date, found “%s”*/198, &fp_date); if (m < 1 || m > 12) { set_pos(&fp); compile_diagnostic(DIAG_WARN|DIAG_UINT, /*Invalid month*/86); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } if (ch == '.') { nextch(); get_pos(&fp); d = read_uint_internal(/*Expecting date, found “%s”*/198, &fp_date); if (d < 1 || d > last_day(y, m)) { set_pos(&fp); /* TRANSLATORS: e.g. 31st of April, or 32nd of any month */ compile_diagnostic(DIAG_WARN|DIAG_UINT, /*Invalid day of the month*/87); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } } } if (py) *py = y; if (pm) *pm = m; if (pd) *pd = d; }
/* a wrapper for longjmp so we can keep everything local */ void bail_to_command_line() { #ifdef _Windows call_kill_pending_Pause_dialog(); #endif LONGJMP(command_line_env, TRUE); }
NORETURN void _SC_timeout_cont(int sig) {JMP_BUF *cpu; /* io_printf(stdout, "Timeout %d\n", sig); */ SC_timeout(0, _SC_timeout_cont, NULL, 0); cpu = _SC_get_to_buf(-1); LONGJMP(*cpu, 1);}
/* a wrapper for longjmp so we can keep everything local */ void bail_to_command_line() { #ifdef _WIN32 kill_pending_Pause_dialog(); ctrlc_flag = FALSE; #endif LONGJMP(command_line_env, TRUE); }
static SIGTYPE alarm_signal (int signo) { if (interrupts_slowed_down) { something_happened = 1; /* tell QUIT to wake up */ /* we are in "slowed-down interrupts" mode; the only alarm happening here is the slowed-down quit-check alarm, so we set this flag. Do NOT set alarm_happened, because we don't want anyone looking at the timeout queue. We didn't set it and it needs to stay the way it is. */ quit_check_signal_happened = 1; #ifdef WIN32_NATIVE can_break_system_calls = 0; #else /* can_break_system_calls is set when we want to break out of non-interruptible system calls. */ if (can_break_system_calls) { /* reset the flag for safety and such. Do this *before* unblocking or reestablishing the signal to avoid potential race conditions. */ can_break_system_calls = 0; EMACS_UNBLOCK_SIGNAL (signo); EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); LONGJMP (break_system_call_jump, 0); } #endif EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); SIGRETURN; } something_happened = 1; /* tell QUIT to wake up */ alarm_happened = 1; if (emacs_is_blocking) alarm_happened_while_emacs_was_blocking = 1; /* #### This is for QUITP. When it is run, it may not be the place to do arbitrary stuff like run asynch. handlers, but it needs to know whether the poll-for-quit asynch. timeout went off. Rather than put the code in to compute this specially, we just set this flag. Should fix this. */ quit_check_signal_happened = 1; #ifdef HAVE_UNIXOID_EVENT_LOOP signal_fake_event (); #endif EMACS_REESTABLISH_SIGNAL (signo, alarm_signal); SIGRETURN; }
extern void read_string(char **pstr, int *plen) { s_zero(pstr); skipblanks(); if (ch == '\"') { /* String quoted in "" */ nextch(); while (1) { if (isEol(ch)) { compile_error(-/*Missing \"*/69); LONGJMP(file.jbSkipLine); } if (ch == '\"') break; s_catchar(pstr, plen, ch); nextch(); } } else { /* Unquoted string */ while (1) { if (isEol(ch) || isComm(ch)) { if (!*pstr || !(*pstr)[0]) { compile_error(-/*Expecting string field*/121); LONGJMP(file.jbSkipLine); } return; } if (isBlank(ch)) break; s_catchar(pstr, plen, ch); nextch(); } } nextch(); }
static AuBool nas_IOerror_handler(AuServer *aud) { NAS_CRITICAL("Strange things happened.\n"); if (aud) { NAS_CRITICAL("Connection seems to be broken.\n"); } else { NAS_CRITICAL("Server raised SIGPIPE.\n"); } LONGJMP(nas_server_sig, 1); return AuTrue; }
ZEND_API ZEND_COLD void _zend_bailout(char *filename, uint lineno) /* {{{ */ { if (!EG(bailout)) { zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", filename, lineno); exit(-1); } CG(unclean_shutdown) = 1; CG(active_class_entry) = NULL; CG(in_compilation) = 0; EG(current_execute_data) = NULL; LONGJMP(*EG(bailout), FAILURE); }
extern void read_date(int *py, int *pm, int *pd) { int y = 0, m = 0, d = 0; filepos fp; skipblanks(); get_pos(&fp); y = read_uint_internal(/*Expecting date, found “%s”*/198, &fp); /* Two digit year is 19xx. */ if (y < 100) y += 1900; if (y < 1900 || y > 2078) { compile_warning(/*Invalid year (< 1900 or > 2078)*/58); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } if (ch == '.') { nextch(); m = read_uint_internal(/*Expecting date, found “%s”*/198, &fp); if (m < 1 || m > 12) { compile_warning(/*Invalid month*/86); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } if (ch == '.') { nextch(); d = read_uint_internal(/*Expecting date, found “%s”*/198, &fp); if (d < 1 || d > last_day(y, m)) { compile_warning(/*Invalid day of the month*/87); LONGJMP(file.jbSkipLine); return; /* for brain-fried compilers */ } } } if (py) *py = y; if (pm) *pm = m; if (pd) *pd = d; }
/* * abortcmd - catch interrupts and abort the current command */ static RETSIGTYPE abortcmd( int sig ) { if (current_output == stdout) (void)fflush(stdout); putc('\n', stderr); (void)fflush(stderr); if (jump) { jump = 0; LONGJMP(interrupt_buf, 1); } }
static AuBool nas_error_handler(AuServer* aud, AuErrorEvent* ev) { char s[100]; AuGetErrorText(aud, ev->error_code, s, 100); NAS_CRITICAL("error [%s]\n" "error_code: %d\n" "request_code: %d\n" "minor_code: %d\n", s, ev->error_code, ev->request_code, ev->minor_code); LONGJMP(nas_server_sig, 1); return AuTrue; }
/* read numeric expr or omit (return HUGE_REAL); else longjmp */ extern real read_numeric_multi_or_omit(int *p_n_readings) { real v = read_numeric_multi(fTrue, p_n_readings); if (v == HUGE_REAL) { if (!isOmit(ch)) { compile_diagnostic_token_show(DIAG_ERR, /*Expecting numeric field, found “%s”*/9); LONGJMP(file.jbSkipLine); return 0.0; /* for brain-fried compilers */ } nextch(); } return v; }
/* Don't skip blanks, variable error code */ static unsigned int read_uint_internal(int errmsg, const filepos *fp) { unsigned int n = 0; if (!isdigit(ch)) { if (fp) set_pos(fp); compile_diagnostic_token_show(DIAG_ERR, errmsg); LONGJMP(file.jbSkipLine); } while (isdigit(ch)) { n = n * 10 + (char)(ch - '0'); nextch(); } return n; }
static void sig_handler(int sig) {int err; SC_setup_sig_handlers(sig_handler, NULL, 0, FALSE); SC_LOCKON(tlock); err = SC_retrace_exe(NULL, -1, 60000); SC_ASSERT(err == TRUE); LONGJMP(cpu, TRUE); SC_LOCKOFF(tlock); return;}
static void* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size, size_t alignment) { if (EXPECTED(size == PHPDBG_SIGSAFE_MEM_SIZE && !PHPDBG_G(sigsafe_mem).allocated)) { PHPDBG_G(sigsafe_mem).allocated = 1; return PHPDBG_G(sigsafe_mem).mem; } write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Tried to allocate more than " EXP_STR(PHPDBG_SIGSAFE_MEM_SIZE) " bytes from stack memory in signal handler ... bailing out of signal handler\n")); if (*EG(bailout)) { LONGJMP(*EG(bailout), FAILURE); } write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Bailed out without a bailout address in signal handler!\n")); return NULL; }
void sighandler(int sig) { extern FILE *errfile; extern logical anywarns; extern char *commandname; #ifndef NOALARM extern JMP_BUF jumpbuf; if (sig == SIGALRM) LONGJMP(jumpbuf, 1); #endif fprintf(errfile, "%s: Received ", commandname); if (sig == SIGTERM) fprintf(errfile, "termination"); else if (sig == SIGINT) fprintf(errfile, "interrupt"); #ifdef SIGHUP else if (sig == SIGHUP) fprintf(errfile, "HUP"); #endif #ifdef SIGQUIT else if (sig == SIGQUIT) fprintf(errfile, "quit"); #endif fprintf(errfile, " signal: exiting\n"); if (errfile != stderr) { fprintf(stderr, "Received "); if (sig == SIGTERM) fprintf(stderr, "termination"); else if (sig == SIGINT) fprintf(stderr, "interrupt"); #ifdef SIGHUP else if (sig == SIGHUP) fprintf(stderr, "HUP"); #endif #ifdef SIGQUIT else if (sig == SIGQUIT) fprintf(stderr, "quit"); #endif fprintf(stderr, " signal: exiting\n"); } anywarns = TRUE; my_exit(EXIT_SIGNAL); }
void uim_throw_error(const char *msg) { assert(msg || !msg); err_msg = msg; if (!guarded) { print_caught_error(); exit(EX_SOFTWARE); } #if UIM_USE_ERROR_GUARD /* To run print_caught_error() on roomed stack space, exit to the * guarded point first. */ LONGJMP(uim_catch_block_env, guarded); #endif }
/* * Interrupt handler for builtin_editor(). */ static void builtin_interrupt_handler(int sig) { signal(SIGINT, builtin_interrupt_handler); signal(SIGQUIT, builtin_interrupt_handler); ++builtin_interrupt_count; #if defined(SIGSET) && defined(HASSIGHOLD) /* * During execution of a signal handler set with sigset(), * the originating signal is held. It must be released or * it cannot recur. */ sigrelse(sig); #endif /* SIGSET and HASSIGHOLD */ LONGJMP(builtin_jmpbuf, 1); }
static void fiber_swap(ACL_FIBER *from, ACL_FIBER *to) { if (from->status == FIBER_STATUS_EXITING) { size_t slot = from->slot; int n = acl_ring_size(&__thread_fiber->dead); /* if the cached dead fibers reached the limit, * some will be freed */ if (n > MAX_CACHE) { n -= MAX_CACHE; fiber_kick(n); } if (!from->sys) __thread_fiber->count--; __thread_fiber->fibers[slot] = __thread_fiber->fibers[--__thread_fiber->slot]; __thread_fiber->fibers[slot]->slot = slot; acl_ring_prepend(&__thread_fiber->dead, &from->me); } #ifdef USE_JMP /* use setcontext() for the initial jump, as it allows us to set up * a stack, but continue with longjmp() as it's much faster. */ if (SETJMP(from->env) == 0) { /* context just be used once for set up a stack, which will * be freed in fiber_start. The context in __thread_fiber * was set NULL. */ if (to->context != NULL) setcontext(to->context); else LONGJMP(to->env); } #else if (swapcontext(from->context, to->context) < 0) acl_msg_fatal("%s(%d), %s: swapcontext error %s", __FILE__, __LINE__, __FUNCTION__, acl_last_serror()); #endif }
void ooc_throw( Exception exc_obj_ptr ) { if( exc_obj_ptr == NULL ) exc_obj_ptr = exception_new( err_bad_throw ); /* Throwing Exception clears the managed stack */ clear_managed_stack(); if( try_pt ) { /* if we are in an exception handling, then its a rethrow with the new Exception */ if( try_pt->exc_obj != NULL && try_pt->exc_obj != exc_obj_ptr ) { #ifndef OOC_NO_DYNAMIC_MEM if( try_pt->exc_obj != & static_exception ) ooc_delete( (Object) try_pt->exc_obj ); #else ooc_release( (Object) try_pt->exc_obj ); #endif try_pt->exc_obj = exc_obj_ptr; try_pt->status |= RETHROWN; } else { try_pt->exc_obj = exc_obj_ptr; LONGJMP( try_pt->buffer, !0 ); } } else { /* if no error handler was set, we call the system to handle the error */ /* fprintf(stderr, "*** Unhandled exception! Exception object is:\n\n" ); //dump_item( exc_obj_ptr, 128 ); //dump_item( exc_obj_ptr->_vtab->_class, 16 ); //dump_item( exc_obj_ptr->_vtab->_class->name, 16 ); */ abort(); } }
/* Don't static for INLINE */ void thrSwitch( Thread t ) { /* register Thread run_thread = ThrRunningThread ; */ volatile Thread run_thread; run_thread = ThrRunningThread; run_thread->errno = errno ; run_thread->debugFlags = OzDebugFlags ; if ( SETJMP(run_thread->context) ) { while ( thrDefunctThreads ) { register Thread defunct ; defunct = thrDefunctThreads ; thrDefunctThreads = thrDefunctThreads->next ; stkFree( defunct->stack, defunct->stack_size ) ; defunct->status = FREE ; defunct->next = thrFreeThreads ; thrFreeThreads = defunct ; } /* errno = run_thread->errno ; OzDebugFlags = run_thread->debugFlags ; */ return ; /* to signaled pc */ } ThrRunningThread = t ; t->status = RUNNING ; errno = t->errno ; OzDebugFlags = t->debugFlags ; run_thread->sigBlocking = sigBlocking ; if (run_thread->sigBlocking && !t->sigBlocking) SigDisable() ; else if (!run_thread->sigBlocking && t->sigBlocking) thrAllocSignalStack( &(t->signal_stack) ) ; if (!run_thread->sigBlocking || !t->sigBlocking) SIGSTACK(&(t->signal_stack), &(run_thread->signal_stack)); else if ( t != run_thread ) { t->signal_stack = run_thread->signal_stack ; run_thread->signal_stack.ss_sp = NULL ; SIGSTACK_FLAGS(run_thread->signal_stack) = 0 ; } sigBlocking = t->sigBlocking; if (run_thread->sigBlocking && !t->sigBlocking) { thrFreeSignalStack( &(run_thread->signal_stack) ); } else if (!run_thread->sigBlocking && t->sigBlocking) { SigEnable() ; } if ( t->first ) { /* first dispatch */ register void (*pc)() ; register void *sp ; #if defined(SVR4) sp = (char *)t->context[1] ; pc = (void (*))t->context[2] ; #else /* SVR4 */ sp = (char *)t->context[2] ; pc = (void (*))t->context[3] ; #endif /* SVR4 */ t->first = 0 ; thrJumpThread( thrStart, pc, ThrExit, sp ) ; /* NOT REACHED */ } LONGJMP( t->context, 1 ) ; /* NOT REACHED */ }
int SC_exec_async(const char *shell, char **cmnds, char **dirs, const char *consh, char **conenv, int nc, const char *lname, const char *fname, int na, int show, int ignore, int lg) {int is, id, nd, ns, ja, st, sig; int nhst, reset, ioi; char *ldir[1]; fspec *filter; conpool *cp; asyncstate *as; SC_contextdes hnd; as = CMAKE(asyncstate); SC_MEM_INIT(asyncstate, as); _SC_setup_async_state(as, SC_get_host_length_max(NULL, TRUE, FALSE)); as->debug = FALSE; if (lname != NULL) {as->log = io_open(lname, "a"); SC_setbuf(as->log, NULL);} else as->log = NULL; /* save old interrupt state */ hnd = SC_which_signal_handler(SC_SIGIO); ioi = SC_set_io_interrupts(FALSE); SC_signal_n(SC_SIGIO, SIG_IGN, NULL, 0); filter = _SC_read_filter(fname); shell = SC_get_shell(shell); /* count commands */ SC_ptr_arr_len(ns, cmnds); /* count the directories */ if (dirs == NULL) {ldir[0] = SC_getcwd(); dirs = ldir; nd = 1;} else SC_ptr_arr_len(nd, dirs); /* open the connection pool */ nhst = SC_get_nhosts(PSY_Arch); nc = min(nc, nhst); nc = min(nc, ns); cp = SC_open_connection_pool(nc, PSY_Arch, consh, conenv, na, show, ignore, DEFAULT_HEARTBEAT, filter); cp->as = as; as->pool = cp; sig = SETJMP(cp->cpu); if (sig == 0) {cp->active = TRUE; /* launch all commands */ reset = TRUE; for (id = 0; id < nd; id++) for (is = 0; is < ns; is++) {if (IS_BARRIER(cmnds[is])) {while (SC_wait_pool_job(cp, DEFAULT_WAIT) != 2); reset = TRUE;} else {ja = SC_launch_pool_job(cp, na, reset, shell, dirs[id], cmnds[is]); if (ja < 0) {LONGJMP(cp->cpu, SC_EXIT_BAD);}; reset = FALSE;};}; /* wait for commands to complete */ while (SC_wait_pool_job(cp, DEFAULT_WAIT) != 2);}; cp->active = FALSE; as->pool = NULL; st = SC_connection_pool_status(cp); if (lg == TRUE) {SC_close_connection_pool(cp, -1, TRUE); as->to_stdout = FALSE;} else {as->to_stdout = FALSE; SC_close_connection_pool(cp, sig, TRUE);}; CFREE(as); /* cleanup */ _SC_free_filter(filter); /* restore old interrupt state */ SC_set_io_interrupts(ioi); SC_restore_signal_n(SC_SIGIO, hnd); if (sig == SC_EXIT_BAD) st = sig; return(st);}
static MySignalHandler KeyAbort(SIGNAL_ARG) { LONGJMP(AbortLoading, 1); SIGNAL_RETURN; }
static void doneh(void) { clear_sys(); LONGJMP(SC_gs.cpu, ERR_FREE);}
/* if prefix is omitted: if PFX_OPT set return NULL, otherwise use longjmp */ extern prefix * read_prefix(unsigned pfx_flags) { bool f_optional = !!(pfx_flags & PFX_OPT); bool fSurvey = !!(pfx_flags & PFX_SURVEY); bool fSuspectTypo = !!(pfx_flags & PFX_SUSPECT_TYPO); prefix *back_ptr, *ptr; char *name; size_t name_len = 32; size_t i; bool fNew; bool fImplicitPrefix = fTrue; int depth = -1; filepos fp_firstsep; skipblanks(); #ifndef NO_DEPRECATED if (isRoot(ch)) { if (!(pfx_flags & PFX_ALLOW_ROOT)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*ROOT is deprecated*/25); LONGJMP(file.jbSkipLine); } if (root_depr_count < 5) { compile_diagnostic(DIAG_WARN|DIAG_COL, /*ROOT is deprecated*/25); if (++root_depr_count == 5) compile_diagnostic(DIAG_WARN, /*Further uses of this deprecated feature will not be reported*/95); } nextch(); ptr = root; if (!isNames(ch)) { if (!isSep(ch)) return ptr; /* Allow optional SEPARATOR after ROOT */ get_pos(&fp_firstsep); nextch(); } fImplicitPrefix = fFalse; #else if (0) { #endif } else { if ((pfx_flags & PFX_ANON) && (isSep(ch) || (pcs->dash_for_anon_wall_station && ch == '-'))) { int first_ch = ch; filepos here; get_pos(&here); nextch(); if (isBlank(ch) || isEol(ch)) { if (!isSep(first_ch)) goto anon_wall_station; /* A single separator alone ('.' by default) is an anonymous * station which is on a point inside the passage and implies * the leg to it is a splay. */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); return new_anon_station(); } if (isSep(first_ch) && ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A double separator ('..' by default) is an anonymous station * which is on the wall and implies the leg to it is a splay. */ prefix * pfx; anon_wall_station: if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); pfx = new_anon_station(); pfx->sflags |= BIT(SFLAGS_WALL); return pfx; } if (ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A triple separator ('...' by default) is an anonymous * station, but otherwise not handled specially (e.g. for * a single leg down an unexplored side passage to a station * which isn't refindable). */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END); return new_anon_station(); } } } set_pos(&here); } ptr = pcs->Prefix; } i = 0; name = NULL; do { fNew = fFalse; if (name == NULL) { /* Need a new name buffer */ name = osmalloc(name_len); } /* i==0 iff this is the first pass */ if (i) { i = 0; nextch(); } while (isNames(ch)) { if (i < pcs->Truncate) { /* truncate name */ name[i++] = (pcs->Case == LOWER ? tolower(ch) : (pcs->Case == OFF ? ch : toupper(ch))); if (i >= name_len) { name_len = name_len + name_len; name = osrealloc(name, name_len); } } nextch(); } if (isSep(ch)) { fImplicitPrefix = fFalse; get_pos(&fp_firstsep); } if (i == 0) { osfree(name); if (!f_optional) { if (isEol(ch)) { if (fSurvey) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting survey name*/89); } else { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting station name*/28); } } else { /* TRANSLATORS: Here "station" is a survey station, not a train station. */ compile_diagnostic(DIAG_ERR|DIAG_COL, /*Character “%c” not allowed in station name (use *SET NAMES to set allowed characters)*/7, ch); } LONGJMP(file.jbSkipLine); } return (prefix *)NULL; } name[i++] = '\0'; back_ptr = ptr; ptr = ptr->down; if (ptr == NULL) { /* Special case first time around at each level */ name = osrealloc(name, i); ptr = osnew(prefix); ptr->ident = name; name = NULL; ptr->right = ptr->down = NULL; ptr->pos = NULL; ptr->shape = 0; ptr->stn = NULL; ptr->up = back_ptr; ptr->filename = file.filename; ptr->line = file.line; ptr->min_export = ptr->max_export = 0; ptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) ptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); back_ptr->down = ptr; fNew = fTrue; } else { /* Use caching to speed up adding an increasing sequence to a * large survey */ static prefix *cached_survey = NULL, *cached_station = NULL; prefix *ptrPrev = NULL; int cmp = 1; /* result of strcmp ( -ve for <, 0 for =, +ve for > ) */ if (cached_survey == back_ptr) { cmp = strcmp(cached_station->ident, name); if (cmp <= 0) ptr = cached_station; } while (ptr && (cmp = strcmp(ptr->ident, name))<0) { ptrPrev = ptr; ptr = ptr->right; } if (cmp) { /* ie we got to one that was higher, or the end */ prefix *newptr; name = osrealloc(name, i); newptr = osnew(prefix); newptr->ident = name; name = NULL; if (ptrPrev == NULL) back_ptr->down = newptr; else ptrPrev->right = newptr; newptr->right = ptr; newptr->down = NULL; newptr->pos = NULL; newptr->shape = 0; newptr->stn = NULL; newptr->up = back_ptr; newptr->filename = file.filename; newptr->line = file.line; newptr->min_export = newptr->max_export = 0; newptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) newptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); ptr = newptr; fNew = fTrue; } cached_survey = back_ptr; cached_station = ptr; } depth++; f_optional = fFalse; /* disallow after first level */ if (isSep(ch)) get_pos(&fp_firstsep); } while (isSep(ch)); if (name) osfree(name); /* don't warn about a station that is referred to twice */ if (!fNew) ptr->sflags &= ~BIT(SFLAGS_SUSPECTTYPO); if (fNew) { /* fNew means SFLAGS_SURVEY is currently set */ SVX_ASSERT(TSTBIT(ptr->sflags, SFLAGS_SURVEY)); if (!fSurvey) { ptr->sflags &= ~BIT(SFLAGS_SURVEY); if (TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } } else { /* check that the same name isn't being used for a survey and station */ if (fSurvey ^ TSTBIT(ptr->sflags, SFLAGS_SURVEY)) { /* TRANSLATORS: Here "station" is a survey station, not a train station. * * Here "survey" is a "cave map" rather than list of questions - it should be * translated to the terminology that cavers using the language would use. */ compile_diagnostic(DIAG_ERR, /*“%s” can’t be both a station and a survey*/27, sprint_prefix(ptr)); } if (!fSurvey && TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } /* check the export level */ #if 0 printf("R min %d max %d depth %d pfx %s\n", ptr->min_export, ptr->max_export, depth, sprint_prefix(ptr)); #endif if (ptr->min_export == 0 || ptr->min_export == USHRT_MAX) { if (depth > ptr->max_export) ptr->max_export = depth; } else if (ptr->max_export < depth) { prefix *survey = ptr; char *s; const char *p; int level; for (level = ptr->max_export + 1; level; level--) { survey = survey->up; SVX_ASSERT(survey); } s = osstrdup(sprint_prefix(survey)); p = sprint_prefix(ptr); if (survey->filename) { compile_diagnostic_pfx(DIAG_ERR, survey, /*Station “%s” not exported from survey “%s”*/26, p, s); } else { compile_diagnostic(DIAG_ERR, /*Station “%s” not exported from survey “%s”*/26, p, s); } osfree(s); #if 0 printf(" *** pfx %s warning not exported enough depth %d " "ptr->max_export %d\n", sprint_prefix(ptr), depth, ptr->max_export); #endif } if (!fImplicitPrefix && (pfx_flags & PFX_WARN_SEPARATOR)) { filepos fp_tmp; get_pos(&fp_tmp); set_pos(&fp_firstsep); compile_diagnostic(DIAG_WARN|DIAG_COL, /*Separator in survey name*/392); set_pos(&fp_tmp); } return ptr; } /* if numeric expr is omitted: if f_optional return HUGE_REAL, else longjmp */ static real read_number(bool f_optional) { bool fPositive, fDigits = fFalse; real n = (real)0.0; filepos fp; int ch_old; get_pos(&fp); ch_old = ch; fPositive = !isMinus(ch); if (isSign(ch)) nextch(); while (isdigit(ch)) { n = n * (real)10.0 + (char)(ch - '0'); nextch(); fDigits = fTrue; } if (isDecimal(ch)) { real mult = (real)1.0; nextch(); while (isdigit(ch)) { mult *= (real).1; n += (char)(ch - '0') * mult; fDigits = fTrue; nextch(); } } /* !'fRead' => !fDigits so fDigits => 'fRead' */ if (fDigits) return (fPositive ? n : -n); /* didn't read a valid number. If it's optional, reset filepos & return */ set_pos(&fp); if (f_optional) { return HUGE_REAL; } if (isOmit(ch_old)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Field may not be omitted*/8); } else { compile_diagnostic_token_show(DIAG_ERR, /*Expecting numeric field, found “%s”*/9); } LONGJMP(file.jbSkipLine); return 0.0; /* for brain-fried compilers */ }
sigjmp_buf * hytm_start(TXPARAMS stm_tx_attr_t attr) { TX_GET; unsigned long err; tx->retries = 0; /* Set status */ UPDATE_STATUS(tx->status, TX_ACTIVE); stm_check_quiesce(tx); /* copy attributes if need to switch to software mode */ tx->attr = attr; tx->start = rdtsc(); hytm_restart: /* All registers are lost when ASF aborts, thus we discard registers */ asm volatile (ASF_SPECULATE :"=a" (err) : :"memory","rbp","rbx","rcx","rdx","rsi","rdi", "r8", "r9","r10","r11","r12","r13","r14","r15" ); tx = tls_get_tx(); if (unlikely(asf_status_code(err) != 0)) { /* Set status to ABORTED */ SET_STATUS(tx->status, TX_ABORTED); tx->retries++; /* Error management */ if (asf_status_code(err) == ASF_STATUS_CONTENTION) { if (tx->retries > ASF_ABORT_THRESHOLD) { /* There is too many conflicts, software will not help, start irrevocability. */ stm_set_irrevocable(TXARGS 1); /* Set irrevocable serial */ #if defined(TM_DTMC) || defined(TM_GCC) stm_set_irrevocable(TXARGS -1); /* Acquire irrevocability */ UPDATE_STATUS(tx->status, TX_IRREVOCABLE); LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */ #else /* ! defined(TM_DTMC) && ! defined(TM_GCC) */ /* Non-tm compiler doesn't have path without instrumentation. */ tx->software = 1; #endif /* ! defined(TM_DTMC) && ! defined(TM_GCC) */ } } else if (asf_status_code(err) == ASF_STATUS_ABORT) { if (asf_abort_code(err) == ASF_FORCE_SOFTWARE) { tx->software = 1; #ifdef IRREVOCABLE_ENABLED } else if(asf_abort_code(err) == ASF_RETRY_IRREVOCABLE) { # if defined(TM_DTMC) || defined(TM_GCC) if (tx->irrevocable != 0) { stm_set_irrevocable(TXARGS -1); UPDATE_STATUS(tx->status, TX_IRREVOCABLE); LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */ } # else /* ! defined(TM_DTMC) || defined(TM_GCC) */ /* Non-tm compiler doesn't have path without instrumentation. */ tx->software = 1; # endif /* ! defined(TM_DTMC) || defined(TM_GCC) */ #endif /* IRREVOCABLE_ENABLED */ } else { if (tx->retries > ASF_ABORT_THRESHOLD) { tx->software = 1; } } } else { /* Other cases are critical and needs software mode */ tx->software = 1; } if (tx->software) { /* Start a software transaction (it cannot use attr since the register/stack can be corrupted) */ stm_start(TXARGS tx->attr); /* Restoring the context */ #if defined(TM_DTMC) LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */ #else /* ! defined(TM_DTMC) */ LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */ #endif /* ! defined(TM_DTMC) */ } else { uint64_t cur = (uint64_t)rdtsc(); uint64_t wait = cur + (random() % (cur - tx->start)); /* XXX random but maybe not reliable */ /* Waiting... */ while (rdtsc() < wait); UPDATE_STATUS(tx->status, TX_ACTIVE); /* Check quiesce before to restart */ stm_check_quiesce(tx); goto hytm_restart; } } /* Reset write set */ tx->w_set.nb_entries = 0; if (tx->retries > 0) { /* Restoring registers for retry */ #if defined(TM_DTMC) LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */ #else /* ! defined(TM_DTMC) */ LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */ #endif /* ! defined(TM_DTMC) */ } return &tx->env; }