static void ualarm_AST(Alarm *a) { int iss; unsigned long now[2]; iss = sys$gettim(now); if (VMSERR(iss)) lib$signal(iss); if (a->function == UAL_SET || a->function == UAL_CLEAR) { if (a0->function == UAL_ACTIVE) { iss = sys$cantim(a0,PSL$C_USER); if (VMSERR(iss)) lib$signal(iss); iss = lib$subx(a0->remain, now, a->remain); if (VMSERR(iss)) lib$signal(iss); if (a->remain[1] & 0x80000000) a->remain[0] = a->remain[1] = 0; } if (a->function == UAL_SET) { a->function = a0->function; a0->function = UAL_ACTIVE; a0->repeat = a->repeat; if (a0->repeat) { a0->interval[0] = a->interval[0]; a0->interval[1] = a->interval[1]; } a0->delay[0] = a->delay[0]; a0->delay[1] = a->delay[1]; iss = lib$subx(now, a0->delay, a0->remain); if (VMSERR(iss)) lib$signal(iss); iss = sys$setimr(0,a0->delay,ualarm_AST,a0); if (VMSERR(iss)) lib$signal(iss); } else { a->function = a0->function; a0->function = UAL_NULL; } iss = sys$setef(alarm_ef); if (VMSERR(iss)) lib$signal(iss); } else if (a->function == UAL_ACTIVE) { if (a->repeat) { iss = lib$subx(now, a->interval, a->remain); if (VMSERR(iss)) lib$signal(iss); iss = sys$setimr(0,a->interval,ualarm_AST,a); if (VMSERR(iss)) lib$signal(iss); } else { a->function = UAL_NULL; } iss = sys$wake(0,0); if (VMSERR(iss)) lib$signal(iss); lib$signal(SS$_ASTFLT); } else { lib$signal(SS$_BADPARAM); } }
void __init init_nonpaged(void *pgdat, unsigned long totalpages) { memset(&npp_pool, 0, sizeof(npp_pool)); memset(&bap_pool, 0, sizeof(bap_pool)); memset(&npp_listheads, 0, sizeof(npp_listheads)); memset(&bap_listheads, 0, sizeof(npp_listheads)); npp_pool.npool$ar_lsthds=&npp_listheads; bap_pool.npool$ar_lsthds=&bap_listheads; exe$gs_npp_npool=&npp_pool; exe$gs_bap_npool=&bap_pool; exe$gs_npp_base_lsthds=&npp_listheads; exe$gs_bap_base_lsthds=&bap_listheads; //memset(&ioc$gq_listheads[0], 0, sizeof(ioc$gq_listheads)); // ordinary nonpaged pool //override for now; half space is for nonpaged pool sgn$gl_npagedyn=totalpages<<(PAGE_SHIFT-2); // half again/quarter init_nonpaged_pool(pgdat, 2*1024*1024, exe$gs_bap_npool, &mmg$gq_bap, &exe$gq_bap_variable); init_nonpaged_pool(pgdat, totalpages<<(PAGE_SHIFT-2), exe$gs_npp_npool, &mmg$gl_npagedyn, &exe$gl_nonpaged); #if 0 void exe$reclaim_pool_gentle(void * pool); signed long long time=-10000000*60; exe$setimr(0, &time, exe$reclaim_pool_gentle, exe$gs_npp_npool, 0); #endif }
/* * ------------------------------------------ * Hang the process for a specified time. * * Goes to sleep for a positive value. * Any caught signal will terminate the sleep * following the execution of that signal's catching routine. * * Arguments: * num - time to sleep * * Return: * none * ------------------------------------------ */ void op_hang(mval* num) { int ms; #ifdef VMS uint4 time[2]; int4 efn_mask, status; error_def(ERR_SYSCALL); #endif ms = 0; MV_FORCE_NUM(num); if (num->mvtype & MV_INT) { if (0 < num->m[1]) { assert(MV_BIAS >= 1000); /* if formats change overflow may need attention */ ms = num->m[1] * (1000 / MV_BIAS); } } else if (0 == num->sgn) /* if sign is not 0 it means num is negative */ ms = mval2i(num) * 1000; /* too big to care about fractional amounts */ if (ms) { UNIX_ONLY(hiber_start(ms);) VMS_ONLY( time[0] = -time_low_ms(ms); time[1] = -time_high_ms(ms) - 1; efn_mask = (1 << efn_outofband | 1 << efn_timer); if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0))) rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status); if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask))) rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status); ) if (outofband)
/* * ---------------------------------------------------- * System call to set timer. * Time is given im msecs. * * Arguments: * tid - timer id * time_to_expir - time to expiration. * handler - address of handler routine * ---------------------------------------------------- */ void start_timer(TID tid, int4 time_to_expir, void (*handler)(), int4 dummy_hdata_len, void *dummy_hdata) { int4 time[2]; int status; time[1] = -time_high_ms(time_to_expir) - 1; time[0] = -time_low_ms(time_to_expir); status = sys$setimr(efn_timer, time, handler, tid, 0); assert(SS$_NORMAL == status); }
static void waitTime ( pwr_tTime *t ) { pwr_tStatus sts; pwr_tTime now; pwr_tTime then = *t; char tims[24]; short len; struct dsc$descriptor_s tims_desc = { sizeof(tims)-1, DSC$K_DTYPE_T, DSC$K_CLASS_S,}; #if 0 subTime(&then, nowTime(&now)); #endif if ((int)then.tv_sec > 0 || ((int)then.tv_sec == 0 && then.tv_nsec > 0)) { #if defined OS_VMS || defined OS_ELN int tv_nsec; int vmstime[2]; int multiplier = -10000000; /* Used to convert 1 s to 100 ns, delta time. */ static pwr_tTime tick = {0, 10000000}; addTime(&then, &tick); tv_nsec = -then.tv_nsec/100; /* Convert to 100 ns. */ sts = lib$emul(&then.tv_sec, &multiplier, &tv_nsec, vmstime); #if defined OS_VMS tims_desc.dsc$a_pointer = tims; sys$asctim( &len, &tims_desc, vmstime, 0); tims[len] = '\0'; printf(" %s\n", tims); #if 0 sts = sys$clref(timerFlag); sts = sys$setimr(timerFlag, vmstime, 0, 0, 0); sts = sys$waitfr(timerFlag); #endif #elif defined OS_ELN eln$time_string(tims, vmstime); tims[23] = '\0'; printf(" %s\n", tims); #if 0 ker$wait_any(&sts, NULL, vmstime); #endif #endif #elif defined OS_LYNX pwr_tTime rmt; nanosleep(&then, &rmt); #endif } }
void mup_bak_pause(void) { int4 pause[2]; pause[0] = 2 * -10000000; pause[1] = -1; if (sys$setimr( efn_immed_wait, &pause, 0, 0, 0) == SS$_NORMAL) /* Safety wait to make sure that all blocks have been */ { sys$synch(efn_immed_wait, 0); /* returned to the frozen queues before flushing */ } return; }
void ccp_tr_close( ccp_action_record *rec) { ccp_db_header *db; uint4 status; db = ccp_get_reg(&rec->v.file_id); if (db != NULL && db->segment->nl->ccp_state != CCST_OPNREQ) { status = ccp_enqw(EFN$C_ENF, LCK$K_EXMODE, &db->refcnt_iosb, LCK$M_CONVERT | LCK$M_NOQUEUE, NULL, 0, NULL, 0, NULL, PSL$C_USER, 0); /***** Check error status here? *****/ if (status == SS$_NORMAL || ccp_stop) if (db->segment->nl->ccp_state == CCST_RDMODE) ccp_close1(db); else { db->close_region = TRUE; if (db->wmexit_requested) status = sys$dclast(ccp_exitwm_attempt, db, PSL$C_USER); else status = sys$dclast(ccp_exitwm_blkast, &db->exitwm_timer_id, PSL$C_USER); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ } /* NOTE: The following `else' clause is a temporary kludge. There appears to be a scenario in which the CCP loses track of a request to relinquish write mode, causing GT.M processes to hang. We piggyback on the checkdb timer processing here to guarantee that the hang doesn't persist, by simulating the receipt of the blocking AST that initiates write mode exit processing. */ else if (db->quantum_expired && CCP_SEGMENT_STATE(db->segment->nl, CCST_MASK_WRITE_MODE)) { status = sys$dclast(ccp_exitwm_blkast, &db->exitwm_timer_id, PSL$C_USER); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ } } if (rec->pid == 0 && !checkdb_timer) { /* Request was from ccp_tr_checkdb */ status = sys$setimr(0, delta_30_sec, ccp_tr_checkdb, 0, 0); if (status == SS$_NORMAL) checkdb_timer = TRUE; else ccp_signal_cont(status); /***** Is this reasonable? *****/ } return; }
/* * ------------------------------------------------------ * Start hibernating by starting a timer using hiber_time * (in msecs) and doing a pause * ------------------------------------------------------ */ void hiber_start(uint4 hiber) { int4 hiber_time[2]; /* don't have static since can be interrupted by an AST */ int status_timr, status_wait, ast_in_prog; if (0 == hiber) return; /* in PRO code return */ hiber_time[0] = -time_low_ms((int4)hiber); hiber_time[1] = -time_high_ms((int4)hiber); if (hiber_time[1] == 0) hiber_time[1] -= 1; if (0 != (ast_in_prog = lib$ast_in_prog())) { /* sleep sounder but less permanently; * note that an AST may cause an inappropriate time to be used for another hiber_start in progress, * but that risk should be statistically small, and the consequences (as far as known) are not important */ status_timr = sys$setimr(efn_timer_ast, hiber_time, 0, hiber_start_ast, 0); assert(SS$_NORMAL == status_timr); if (SS$_NORMAL == status_timr) { status_wait = sys$waitfr(efn_timer_ast); assert(SS$_NORMAL == status_wait); } } else { /* timr->hiber should not be changed to timr->waitfr. The former waits for a wakeup or outofband event; whichever * happens sooner will stop the hiber while the latter does not recognize outofband events (like tp timeouts) */ status_timr = sys$setimr(efn_hiber_start, hiber_time, wake, hiber_start, 0); assert(SS$_NORMAL == status_timr); if (SS$_NORMAL == status_timr) { sys$hiber(); sys$cantim(hiber_start, 0); } } }
main() { $DESCRIPTOR(tensec,"0 00:00:10.00"); sys$bintim(&tensec,&step1); sys$setimr(50,&step1,my1,0,0); printf("before waitfr %x\n",time(0)); sys$waitfr( 50 ); printf("after waitfr %x\n",time(0)); }
/*********************************************************************** This routine is called to wait for a clustered data base to transition to a new state. If the "state" parameter is non-zero, then it is considered a bit mask, with state zero being the lsb, etc. (All of these masks are symbolically defined in ccp.h as CCST_MASK_nnnnn.) In this case we will return when the state is obtained. If the state is zero, we will return when the ccp_cycle count is bumped, indicating that we have transitioned into read mode. In any event we will return after the "next" cycle has passed, so that if we "miss" our window, we can try again. ***********************************************************************/ bool ccp_userwait(gd_region *reg, uint4 state, int4 *timadr, unsigned short cycle) /* if timadr is non-zero, then the timeout quadword, else use the seg's timeout interval */ { int4 status; static void ccp_nocomm(); bool timer_on; sgmnt_data *seg; sgmnt_addrs *csa; int4 *timptr; char buff[(MM_BLOCK - 1) * DISK_BLOCK_SIZE]; short iosb[4]; error_def(ERR_CCPNOTFND); csa = &((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->s_addrs; seg = ((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->s_addrs.hdr; timptr = timadr ? timadr : (int4 *) &seg->ccp_response_interval; timer_on = timptr[0] != 0 && timptr[1] != 0; for (; ;) { ccp_communication_timeout = FALSE; if (timer_on) { status = sys$setimr(0, timptr, ccp_nocomm, ccp_nocomm, 0); if ((status & 1) == 0) rts_error(VARLSTCNT(1) status); } while (!CCP_SEGMENT_STATE(csa->nl, state) && csa->nl->ccp_cycle == cycle && !ccp_communication_timeout) { sys$hiber(); } if (ccp_communication_timeout && !(CCP_SEGMENT_STATE(csa->nl, state) || csa->nl->ccp_cycle != cycle)) { status = sys$qiow(EFN$C_ENF, ((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->fab->fab$l_stv, IO$_READVBLK, &iosb[0], 0, 0, buff, SIZEOF(buff), 1, 0, 0, 0); if ((status & 1) && (iosb[0] & 1) && ((sgmnt_data *)buff)->freeze) continue; rts_error(VARLSTCNT(1) ERR_CCPNOTFND); }else break; } if (timer_on) sys$cantim(ccp_nocomm,0); return CCP_SEGMENT_STATE(csa->nl, state); }
/* * alarming - tell the world we've been alarmed */ static RETSIGTYPE alarming( int sig ) { #if !defined(VMS) if (initializing) return; if (alarm_flag) alarm_overflow++; else alarm_flag++; #else /* VMS AST routine */ if (!initializing) { if (alarm_flag) alarm_overflow++; else alarm_flag = 1; /* increment is no good */ } lib$addx(&vmsinc,&vmstimer,&vmstimer); sys$setimr(0,&vmstimer,alarming,alarming,0); #endif /* VMS */ }
static void waitClock ( time_tClock diff, int *tmo_ms ) { #if defined OS_VMS || defined OS_ELN pwr_tStatus sts; int sec; int nsec; int vmstime[2]; int multiplier = -10000000; /* Used to convert 1 s to 100 ns, delta time. */ sec = diff / CLK_TCK; nsec = - (diff % CLK_TCK * 10000000 / CLK_TCK); /* Convert to 100 ns. */ sts = lib$emul(&sec, &multiplier, &nsec, vmstime); # if defined OS_VMS sts = sys$clref(timer_flag); sts = sys$setimr(timer_flag, vmstime, 0, 0, 0); sts = sys$waitfr(timer_flag); # elif defined OS_ELN ker$wait_any(&sts, NULL, vmstime); # endif #elif defined OS_POSIX // pwr_tTime rmt; // pwr_tTime wait; static int tics_per_sec = 0; if (tics_per_sec == 0) { tics_per_sec = sysconf(_SC_CLK_TCK); } // printf("waitClock: %d\n", diff); // time_ClockToD(NULL, (pwr_tDeltaTime *)&wait, diff); *tmo_ms = diff * 1000 / tics_per_sec; // *tmo_ms = wait.tv_sec * 1000 + wait.tv_nsec / 1000000; // nanosleep(&wait, &rmt); #endif }
/* * plc_LoopWait() * * Description: * Returns False if a slip is detected. * The plc_sLoopWait structure must be initialized with a call to * plc_LoopInit. */ pwr_tBoolean plc_LoopWait ( plc_sLoopWait *p, unsigned int DeltaTime /* ms */ ) { unsigned int Next, Tick, Seconds; pwr_tVaxTime WaitTime; pwr_tUInt32 Diff; Next = p->LastLoop + DeltaTime / 10; if (Next < p->LastLoop) p->LoopOflw = 1; p->LastLoop = Next; plc_LoopGetVmsUpTime (&Seconds, &Tick); if (Tick < p->LastTick) p->TickOflw = 1; p->LastTick = Tick; /* Reset overflow flags if both flags have been set */ if (p->LoopOflw && p->TickOflw) p->LoopOflw = p->TickOflw = 0; /* Return if there is a slip */ if (!p->LoopOflw && !p->TickOflw) { if (Tick > Next) return FALSE; } else if (!p->LoopOflw && p->TickOflw) return FALSE; Diff = (Next - Tick) * 10; /* ms */ plc_ConvMSToLI(Diff, &WaitTime); sys$clref(p->TimerFlag); sys$setimr(p->TimerFlag, &WaitTime, 0, 0, 0); sys$waitfr(p->TimerFlag); return TRUE; }
unsigned int lib$wait(float *seconds, int flags, int float_type) { // check pointer if (*seconds<0 || *seconds>100000) return LIB$_INVARG; float hundreds_f = *seconds * 100; long long hundreds = hundreds_f; long long vmstime = - hundreds * 100000; int sts; if (flags & 1) { // LIB$K_NOWAKE is 1 sts = sys$setimr (0, &vmstime, dummyast, 0, 0); if ((sts & 1) == 0) return sts; sts = sys$synch (0, 0); if ((sts & 1) == 0) return sts; } else { sts = sys$schdwk(0, 0, &vmstime, 0); if ((sts & 1) == 0) return sts; return sys$hiber(); } return SS$_NORMAL; }
/* * alarming - tell the world we've been alarmed */ static RETSIGTYPE alarming( int sig ) { # ifdef DEBUG const char *msg = "alarming: initializing TRUE\n"; # endif if (!initializing) { if (alarm_flag) { alarm_overflow++; # ifdef DEBUG msg = "alarming: overflow\n"; # endif } else { # ifndef VMS alarm_flag++; # else /* VMS AST routine, increment is no good */ alarm_flag = 1; # endif # ifdef DEBUG msg = "alarming: normal\n"; # endif } } # ifdef VMS lib$addx(&vmsinc, &vmstimer, &vmstimer); sys$setimr(0, &vmstimer, alarming, alarming, 0); # endif # ifdef DEBUG if (debug >= 4) (void)(-1 == write(1, msg, strlen(msg))); # endif }
/* **++ ** ROUTINE: netlib_read ** ** FUNCTIONAL DESCRIPTION: ** ** tbs ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** tbs ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: None. ** **-- */ unsigned int netlib_read (struct CTX **xctx, struct dsc$descriptor *dsc, struct SINDEF *sa, unsigned int *sasize, unsigned int *salen, TIME *timeout, struct NETLIBIOSBDEF *iosb, void (*astadr)(), void *astprm) { struct CTX *ctx; struct IOR *ior; unsigned int status; ITMLST sname; int argc, do_from; VERIFY_CTX(xctx, ctx); SETARGCOUNT(argc); if (dsc->dsc$b_dtype != DSC$K_DTYPE_T && dsc->dsc$b_dtype != 0) return SS$_BADPARAM; if (dsc->dsc$b_class == DSC$K_CLASS_D) { if (dsc->dsc$w_length == 0) return SS$_BADPARAM; } else { if (dsc->dsc$b_class != DSC$K_CLASS_S && dsc->dsc$b_class != 0) return SS$_BADPARAM; } do_from = (argc > 3 && sa != 0 && sasize != 0 && *sasize != 0); if (argc > 7 && astadr != 0) { struct IOR *ior; GET_IOR(ior, ctx, iosb, astadr, (argc > 8) ? astprm : 0); if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &ior->specior.from, &ior->specior.fromlen); if (do_from) { ior->spec_userfrom = sa; ior->spec_length = *sasize; ior->spec_retlen = salen; ior->iorflags = IOR_M_COPY_FROM; } else ior->iorflags = 0; if (timeout != 0) { ior->iorflags |= IOR_M_IO_TIMED; status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior); if (!OK(status)) { FREE_IOR(ior); return status; } } status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_READVBLK, &ior->iosb, io_completion, ior, dsc->dsc$a_pointer, dsc->dsc$w_length, do_from ? &sname : 0, 0, 0, 0); if (!OK(status)) { if (timeout != 0) sys$cantim(ior, 0); FREE_IOR(ior); } } else { struct NETLIBIOSBDEF myiosb; struct SINDEF from; unsigned short fromlen; int timed_out; if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF), &from, &fromlen); timed_out = 0; if (argc > 5 && timeout != 0) { GET_IOR(ior, ctx, 0, 0, 0); ior->iorflags = IOR_M_IO_TIMED; status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior); if (!OK(status)) { FREE_IOR(ior); return status; } } status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_READVBLK, &myiosb, 0, 0, dsc->dsc$a_pointer, dsc->dsc$w_length, do_from ? &sname : 0, 0, 0, 0); if (argc > 5 && timeout != 0) { sys$cantim(ior, 0); timed_out = ior->iorflags & IOR_M_IO_TIMEOUT; FREE_IOR(ior); } if (OK(status)) { if (timed_out && myiosb.iosb_w_status == SS$_CANCEL) myiosb.iosb_w_status = SS$_TIMEOUT; status = netlib___cvt_status(&myiosb); } if (argc > 6 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb); if (OK(status) && do_from) { unsigned int len; len = fromlen; if (len > *sasize) len = *sasize; memcpy(sa, &from, len); if (argc > 4 && salen != 0) *salen = len; } } return status; } /* netlib_read */
/* * init_timer - initialize the timer data structures */ void init_timer(void) { /* * Initialize... */ alarm_flag = 0; alarm_overflow = 0; adjust_timer = 1; stats_timer = 0; huffpuff_timer = 0; interface_timer = 0; current_time = 0; timer_overflows = 0; timer_xmtcalls = 0; timer_timereset = 0; #if !defined(SYS_WINNT) /* * Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT * seconds from now and they continue on every 2**EVENT_TIMEOUT * seconds. */ # if !defined(VMS) # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) if (timer_create (CLOCK_REALTIME, NULL, &ntpd_timerid) == # ifdef SYS_VXWORKS ERROR # else -1 # endif ) { fprintf (stderr, "timer create FAILED\n"); exit (0); } (void) signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1<<EVENT_TIMEOUT); itimer.it_interval.tv_nsec = itimer.it_value.tv_nsec = 0; timer_settime(ntpd_timerid, 0 /*!TIMER_ABSTIME*/, &itimer, NULL); # else (void) signal_no_reset(SIGALRM, alarming); nap_time = 1; itimer.it_interval.tv_sec = itimer.it_value.tv_sec = nap_time; itimer.it_interval.tv_usec = itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); # endif # else /* VMS */ vmsinc[0] = 10000000; /* 1 sec */ vmsinc[1] = 0; lib$emul(&(1<<EVENT_TIMEOUT), &vmsinc, &0, &vmsinc); sys$gettim(&vmstimer); /* that's "now" as abstime */ lib$addx(&vmsinc, &vmstimer, &vmstimer); sys$setimr(0, &vmstimer, alarming, alarming, 0); # endif /* VMS */ #else /* SYS_WINNT */ /* * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds * Under Windows/NT, */ WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL); if (WaitableTimerHandle == NULL) { msyslog(LOG_ERR, "CreateWaitableTimer failed: %m"); exit(1); } else { DWORD Period = (1<<EVENT_TIMEOUT) * 1000; LARGE_INTEGER DueTime; DueTime.QuadPart = Period * 10000i64; if (!SetWaitableTimer(WaitableTimerHandle, &DueTime, Period, NULL, NULL, FALSE) != NO_ERROR) { msyslog(LOG_ERR, "SetWaitableTimer failed: %m"); exit(1); } } #endif /* SYS_WINNT */ }
gtcm_server() { static readonly int4 reptim[2] = {-100000, -1}; /* 10ms */ static readonly int4 wait[2] = {-1000000, -1}; /* 100ms */ void gtcm_ch(), gtcm_exi_handler(), gtcm_init_ast(), gtcm_int_unpack(), gtcm_mbxread_ast(), gtcm_neterr(), gtcm_read_ast(), gtcm_remove_from_action_queue(), gtcm_shutdown_ast(), gtcm_write_ast(), la_freedb(); bool gtcm_link_accept(); bool alid; char buff[512]; char *h = NULL; char *la_getdb(); char nbuff[256]; char *pak = NULL; char reply; unsigned short outlen; int4 closewait[2] = {0, -1}; int4 inid = 0, mdl = 0, nid = 0, days = 0; int4 lic_status; int4 lic_x; int4 lm_mdl_nid(); uint4 status; int i, receive(), value; mstr name1, name2; struct NTD *cmu_ntdroot(); connection_struct *prev_curr_entry; struct dsc$descriptor_s dprd; struct dsc$descriptor_s dver; $DESCRIPTOR(node_name, nbuff); $DESCRIPTOR(proc_name, "GTCM_SERVER"); $DESCRIPTOR(timout, buff); DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; assert(0 == EMPTY_QUEUE); /* check so dont need gdsfhead everywhere */ common_startup_init(GTCM_GNP_SERVER_IMAGE); /* Side-effect: Sets skip_dbtriggers to TRUE for non-trigger platforms */ gtm_env_init(); /* read in all environment variables */ name1.addr = "GTCMSVRNAM"; name1.len = SIZEOF("GTCMSVRNAM") - 1; status = trans_log_name(&name1, &name2, nbuff); if (SS$_NORMAL == status) { proc_name.dsc$a_pointer = nbuff; proc_name.dsc$w_length = node_name.dsc$w_length = name2.len; } else if (SS$_NOLOGNAM == status) { MEMCPY_LIT(nbuff, "GTCMSVR"); node_name.dsc$w_length = SIZEOF("GTCMSVR") - 1; } else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); sys$setprn(&proc_name); status = lib$get_foreign(&timout, 0, &outlen, 0); if ((status & 1) && (6 > outlen)) { for (i = 0; i < outlen; i++) { value = value * 10; if (buff[i] <= '9' && buff[i] >= '0') value += buff[i] - 48; else break; } if (outlen && (i == outlen)) { cm_timeout = TRUE; closewait[0] = value * -10000000; } } dprd.dsc$w_length = cm_prd_len; dprd.dsc$b_dtype = DSC$K_DTYPE_T; dprd.dsc$b_class = DSC$K_CLASS_S; dprd.dsc$a_pointer= cm_prd_name; dver.dsc$w_length = cm_ver_len; dver.dsc$b_dtype = DSC$K_DTYPE_T; dver.dsc$b_class = DSC$K_CLASS_S; dver.dsc$a_pointer= cm_ver_name; ast_init(); licensed = TRUE; lkid = 2; # ifdef NOLICENSE lid = 1; # else /* this code used to be scattered to discourage reverse engineering, but since it now disabled, that seems pointless */ lic_status = ((NULL == (h = la_getdb(LMDB))) ? LP_NOCNFDB : SS$_NORMAL); lic_status = ((1 == (lic_status & 1)) ? lm_mdl_nid(&mdl, &nid, &inid) : lic_status); lic_status = ((1 == (lic_status & 1)) ? lp_licensed(h, &dprd, &dver, mdl, nid, &lid, &lic_x, &days, pak) : lic_status); if (LP_NOCNFDB != lic_status) la_freedb(h); if (1 == (lic_status & 1)) { licensed = TRUE; if (days < 14) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WILLEXPIRE); } else { licensed = FALSE; sys$exit(lic_status); } # endif gtcm_ast_avail = astq_dyn_avail - GTCM_AST_OVRHD; stp_init(STP_INITSIZE); rts_stringpool = stringpool; cache_init(); procnum = 0; get_proc_info(0, TADR(login_time), &image_count); memset(proc_to_clb, 0, SIZEOF(proc_to_clb)); status = cmi_init(&node_name, 0, 0, gtcm_init_ast, gtcm_link_accept); if (!(status & 1)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ((status ^ 3) | 4)); sys$exit(status); } ntd_root = cmu_ntdroot(); ntd_root->mbx_ast = gtcm_mbxread_ast; ntd_root->err = gtcm_neterr; gtcm_connection = FALSE; lib$establish(gtcm_ch); gtcm_exi_blk.exit_hand = >cm_exi_handler; gtcm_exi_blk.arg_cnt = 1; gtcm_exi_blk.cond_val = >cm_exi_condition; sys$dclexh(>cm_exi_blk); INVOKE_INIT_SECSHR_ADDRS; initialize_pattern_table(); assert(run_time); /* Should have been set by common_startup_init */ while (!cm_shutdown) { if (blkdlist) gtcml_chkreg(); assert(!lib$ast_in_prog()); status = sys$dclast(>cm_remove_from_action_queue, 0, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0); if (INTERLOCK_FAIL == curr_entry) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) CMERR_CMINTQUE); if (EMPTY_QUEUE != curr_entry) { switch (*curr_entry->clb_ptr->mbf) { case CMMS_L_LKCANALL: reply = gtcmtr_lkcanall(); break; case CMMS_L_LKCANCEL: reply = gtcmtr_lkcancel(); break; case CMMS_L_LKREQIMMED: reply = gtcmtr_lkreqimmed(); break; case CMMS_L_LKREQNODE: reply = gtcmtr_lkreqnode(); break; case CMMS_L_LKREQUEST: reply = gtcmtr_lkrequest(); break; case CMMS_L_LKRESUME: reply = gtcmtr_lkresume(); break; case CMMS_L_LKACQUIRE: reply = gtcmtr_lkacquire(); break; case CMMS_L_LKSUSPEND: reply = gtcmtr_lksuspend(); break; case CMMS_L_LKDELETE: reply = gtcmtr_lkdelete(); break; case CMMS_Q_DATA: reply = gtcmtr_data(); break; case CMMS_Q_GET: reply = gtcmtr_get(); break; case CMMS_Q_KILL: reply = gtcmtr_kill(); break; case CMMS_Q_ORDER: reply = gtcmtr_order(); break; case CMMS_Q_PREV: reply = gtcmtr_zprevious(); break; case CMMS_Q_PUT: reply = gtcmtr_put(); break; case CMMS_Q_QUERY: reply = gtcmtr_query(); break; case CMMS_Q_ZWITHDRAW: reply = gtcmtr_zwithdraw(); break; case CMMS_S_INITPROC: reply = gtcmtr_initproc(); break; case CMMS_S_INITREG: reply = gtcmtr_initreg(); break; case CMMS_S_TERMINATE: reply = gtcmtr_terminate(TRUE); break; case CMMS_E_TERMINATE: reply = gtcmtr_terminate(FALSE); break; case CMMS_U_LKEDELETE: reply = gtcmtr_lke_clearrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_U_LKESHOW: reply = gtcmtr_lke_showrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_B_BUFRESIZE: reply = CM_WRITE; value = *(unsigned short *)(curr_entry->clb_ptr->mbf + 1); if (value > curr_entry->clb_ptr->mbl) { free(curr_entry->clb_ptr->mbf); curr_entry->clb_ptr->mbf = malloc(value); } *curr_entry->clb_ptr->mbf = CMMS_C_BUFRESIZE; curr_entry->clb_ptr->mbl = value; curr_entry->clb_ptr->cbl = 1; break; case CMMS_B_BUFFLUSH: reply = gtcmtr_bufflush(); break; case CMMS_Q_INCREMENT: reply = gtcmtr_increment(); break; default: reply = FALSE; if (SS$_NORMAL == status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf); break; } if (curr_entry) /* curr_entry can be NULL if went through gtcmtr_terminate */ { status = sys$gettim(&curr_entry->lastact[0]); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); /* curr_entry is used by gtcm_mbxread_ast to determine if it needs to defer the interrupt message */ prev_curr_entry = curr_entry; if (CM_WRITE == reply) { /* if ast == gtcm_write_ast, let it worry */ curr_entry->clb_ptr->ast = gtcm_write_ast; curr_entry = EMPTY_QUEUE; cmi_write(prev_curr_entry->clb_ptr); } else { curr_entry = EMPTY_QUEUE; if (1 == (prev_curr_entry->int_cancel.laflag & 1)) { /* valid interrupt cancel msg, handle in gtcm_mbxread_ast */ status = sys$dclast(gtcm_int_unpack, prev_curr_entry, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); } else if (CM_READ == reply) { prev_curr_entry->clb_ptr->ast = gtcm_read_ast; cmi_read(prev_curr_entry->clb_ptr); } } } } else if (1 < astq_dyn_avail) { # ifdef GTCM_REPTIM /* if reptim is not needed - and smw doesn't know why it would be - remove this */ status = sys$schdwk(0, 0, &wait[0], &reptim[0]); # else status = sys$schdwk(0, 0, &wait[0], 0); # endif sys$hiber(); sys$canwak(0, 0); } if (cm_timeout && (0 == gtcm_users)) sys$setimr(efn_ignore, closewait, gtcm_shutdown_ast, &cm_shutdown, 0); } }
void ccp_reqwm_interrupt(ccp_db_header **pdb) { ccp_db_header *db; sgmnt_addrs *csa; uint4 status; assert(lib$ast_in_prog()); db = *pdb; csa = db->segment; if (csa == NULL || csa->nl->ccp_state == CCST_CLOSED) return; switch (db->wm_iosb.cond) { case SS$_DEADLOCK: ccp_signal_cont(SS$_DEADLOCK); /* Just try again */ ccp_request_write_mode(db); return; case SS$_CANCEL: /* Lock cancelled by close */ return; case SS$_VALNOTVALID: /* Force reads from disk */ db->wm_iosb.valblk[CCP_VALBLK_TRANS_HIST] = 0; db->last_lk_sequence = db->master_map_start_tn = 0; /* Drop through ... */ case SS$_NORMAL: if (db->wm_iosb.valblk[CCP_VALBLK_TRANS_HIST] == csa->ti->curr_tn + csa->ti->lock_sequence) { /* No change to current tn, do not need to update header */ if (csa->now_crit) { assert (csa->nl->in_crit == process_id); csa->nl->in_crit = 0; (void)mutex_unlockw(csa->critical, csa->critical->crashcnt, &csa->now_crit); /***** Check error status here? *****/ } ccp_writedb5(db); } else { if (csa->nl->in_crit == 0) { if (mutex_lockwim(csa->critical, csa->critical->crashcnt, &csa->now_crit) == cdb_sc_normal) csa->nl->in_crit = process_id; /* now_crit was set by mutex_lockwim */ else if (csa->nl->in_crit == 0) /***** Why is this re-tested? *****/ { status = sys$setimr(0, delta_100_msec, ccp_reqwm_interrupt, &db->wmcrit_timer_id, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ return; } } status = sys$qio(0, FILE_INFO(db->greg)->fab->fab$l_stv, IO$_READVBLK, &db->qio_iosb, ccp_writedb2, db, &db->glob_sec->trans_hist, BT_SIZE(csa->hdr) + SIZEOF(th_index), TH_BLOCK, 0, 0, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ } return; default: ccp_signal_cont(db->wm_iosb.cond); /***** Is this reasonable? *****/ return; } }
void ccp_tr_writedb1(ccp_action_record *rec) { ccp_action_record request; ccp_db_header *db; jnl_buffer *jb; sgmnt_addrs *csa; int4 curr_time[2]; uint4 status, *p1, *p2, *top; if ((db = rec->v.h) == NULL) return; csa = db->segment; assert(csa->nl->ccp_state == CCST_RDMODE || csa->nl->ccp_state == CCST_CLOSED || csa->nl->ccp_state == CCST_OPNREQ); if (JNL_ENABLED(csa->hdr)) { assert(csa->jnl->channel != 0); jb = csa->jnl->jnl_buff; if (jb->blocked != 0) { /* jnl writes from a previous write mode are not done yet; try again later */ if ((status = sys$setimr(0, delta_100_msec, ccp_writedb5, db, 0)) != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ return; } jb->epoch_tn = db->wm_iosb.valblk[CCP_VALBLK_EPOCH_TN]; jb->freeaddr = jb->dskaddr = ROUND_UP(db->wm_iosb.valblk[CCP_VALBLK_JNL_ADDR], DISK_BLOCK_SIZE); /* lastaddr is no longer a field in jnl_buff * jb->lastaddr = db->wm_iosb.valblk[CCP_VALBLK_LST_ADDR]; */ jb->free = jb->dsk = 0; } /* Note: We must clear these flags prior to changing state or a set from ccp_exitwm_blkast may be missed */ db->quantum_expired = FALSE; db->tick_in_progress = FALSE; if (db->remote_wakeup) { for (p2 = NULL, p1 = csa->lock_addrs[0], top = p1 + SIZEOF(int4) * NUM_CLST_LCKS; *p1 != 0 && p1 <= top; ++p1) { if ((*p1 & NODENUMBER) == (process_id & NODENUMBER)) { crit_wake(p1); if (p2 == NULL) p2 = p1; *p1 = 0; } else if (p2 != NULL) { *p2++ = *p1; *p1 = 0; } } db->remote_wakeup = FALSE; status = ccp_enq(0, LCK$K_CRMODE, &db->lock_iosb, LCK$M_CONVERT | LCK$M_SYNCSTS, NULL, 0, ccp_lkrqwake1, db, ccp_lkdowake_blkast, PSL$C_USER, 0); /***** Check error status here? *****/ } db->glob_sec->freeze = 0; /* db->glob_sec->wcs_active_lvl = db->glob_sec->n_bts / 2; */ db->drop_lvl = 0; sys$gettim(curr_time); lib$add_times(curr_time, db->glob_sec->ccp_quantum_interval, &db->start_wm_time); csa->nl->ccp_state = CCST_WRTGNT; if (db->blocking_ast_received) { status = sys$dclast(ccp_exitwm_blkast, &db->exitwm_timer_id, PSL$C_USER); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ } csa->nl->ccp_crit_blocked = FALSE; ++csa->nl->ccp_cycle; status = sys$setimr(0, &db->glob_sec->ccp_quantum_interval, ccp_quantum_interrupt, &db->quantum_timer_id, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ db->dirty_buffers_acquired = FALSE; ccp_pndg_proc_wake(&db->write_wait); status = ccp_enq(0, LCK$K_EXMODE, &db->flush_iosb, LCK$M_CONVERT | LCK$M_SYNCSTS, NULL, 0, ccp_reqdrtbuf_interrupt, db, NULL, PSL$C_USER, 0); if (status == SS$_SYNCH) { request.action = CCTR_GOTDRT; request.pid = 0; request.v.h = db; ccp_act_request(&request); } /***** Check error status here? *****/ }
pwr_tUInt32 bck_WaitBackup ( void *context, pwr_tBoolean timeout) { pwr_tUInt32 sts; pwr_tObjid objid; pwr_tInt32 c; pwr_tTime t; pwr_tVaxTime tmo; pwr_tVaxTime tmptime; pwr_sClass_Backup_Conf *backup_confp; /* Backup_Conf object pointer */ $DESCRIPTOR (timeunitdsc, "0 0:0:0.1"); /* 0.1 second units */ int cycletime; #ifdef OS_ELN pwr_tInt32 res; pwr_tVaxTime *tmop; #endif #ifdef OS_VMS $DESCRIPTOR (efcname, BCK_EFC_NAME); #endif /* * Initialize */ #ifdef OS_ELN if (!areas_mapped) { BCK_MAP_AREAS; areas_mapped = TRUE; } #endif /* * Find the local Backup_Conf object */ sts = gdh_GetClassList (pwr_cClass_Backup_Conf, &objid); while (ODD (sts)) { sts = gdh_ObjidToPointer (objid, (pwr_tAddress *)&backup_confp); if (ODD (sts)) break; sts = gdh_GetNextObject (objid, &objid); } if (EVEN (sts)) return sts; /* Something wrong, quit */ /* * Pick up argument information */ if (context == NULL) time_GetTime(&t); else { t = *(pwr_tTime *)context; free (context); } #ifdef OS_ELN tmop = NULL; #else timed_out = FALSE; sts = sys$ascefc (BCK_EFC, &efcname, 0, 0); if (EVEN (sts)) lib$signal (sts); /* BUG */ #endif if (timeout) { cycletime = backup_confp->CycleSlow * 2; if (cycletime == 0) cycletime = BCK_DEFAULT_SLOW * 2; #ifdef OS_ELN tmo = eln$time_value (&timeunitdsc); #else sts = sys$bintim (&timeunitdsc, &tmo); if (EVEN (sts)) lib$signal (sts); /* BUG, should not happen */ #endif lib$mult_delta_time ( &cycletime, /* multiplier */ &tmo); /* delta_time (modified) */ sys$gettim (&tmptime); lib$add_times (&tmo, &tmptime, &tmo); /* Make absolute time */ #ifdef OS_ELN tmop = &tmo; #else sts = sys$setimr (BCK_WRITE_DONE, &tmo, &astrtn, 4711, 0); if (EVEN (sts)) lib$signal (sts); /* BUG */ #endif } /* * Loop, and wait for things to happen */ while (TRUE) { #ifdef OS_ELN ker$clear_event (NULL, bck_write_done); ker$wait_any (NULL, &res, tmop, bck_write_done); /* Check for timeout */ if (res == 0) return SS$_TIMEOUT; #else sts = sys$clref (BCK_WRITE_DONE); if (EVEN (sts)) lib$signal (sts); /* BUG */ sts = sys$waitfr (BCK_WRITE_DONE); if (EVEN (sts)) lib$signal (sts); /* BUG */ /* Check for timeout */ if (timed_out) return SS$_TIMEOUT; #endif /* Check if both cycles done */ if (time_Acomp(&backup_confp->ObjTimeSlow, &t) < 0) continue; if (time_Acomp(&backup_confp->ObjTimeFast, &t) < 0) continue; break; } /* Loop */ #ifdef OS_VMS sys$cantim (4711, 0); #endif return 1; /* Done. */ } /* bck_WaitBackup */
/* * ------------------------------------------ * Hang the process for a specified time. * * Goes to sleep for a positive value. * Any caught signal will terminate the sleep * following the execution of that signal's catching routine. * * The actual hang duration should be NO LESS than the specified * duration for specified durations greater than .001 seconds. * Certain applications depend on this assumption. * * Arguments: * num - time to sleep * * Return: * none * ------------------------------------------ */ void op_hang(mval* num) { int ms; double tmp; mv_stent *mv_zintcmd; ABS_TIME cur_time, end_time; # ifdef VMS uint4 time[2]; int4 efn_mask, status; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ms = 0; MV_FORCE_NUM(num); if (num->mvtype & MV_INT) { if (0 < num->m[1]) { assert(MV_BIAS >= 1000); /* if formats change overflow may need attention */ ms = num->m[1] * (1000 / MV_BIAS); } } else if (0 == num->sgn) /* if sign is not 0 it means num is negative */ { tmp = mval2double(num) * (double)1000; ms = ((double)MAXPOSINT4 >= tmp) ? (int)tmp : (int)MAXPOSINT4; } if (ms) { if (TREF(tpnotacidtime) * 1000 < ms) TPNOTACID_CHECK(HANGSTR); # if defined(DEBUG) && defined(UNIX) if (WBTEST_ENABLED(WBTEST_DEFERRED_TIMERS) && (3 > gtm_white_box_test_case_count) && (123000 == ms)) { DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); DBGFPF((stderr, "OP_HANG: will sleep for 20 seconds\n")); LONG_SLEEP(20); DBGFPF((stderr, "OP_HANG: done sleeping\n")); ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); return; } if (WBTEST_ENABLED(WBTEST_BREAKMPC)&& (0 == gtm_white_box_test_case_count) && (999 == ms)) { frame_pointer->old_frame_pointer->mpc = (unsigned char *)GTM64_ONLY(0xdeadbeef12345678) NON_GTM64_ONLY(0xdead1234); return; } if (WBTEST_ENABLED(WBTEST_UTIL_OUT_BUFFER_PROTECTION) && (0 == gtm_white_box_test_case_count) && (999 == ms)) { /* Upon seeing a .999s hang this white-box test launches a timer that pops with a period of * UTIL_OUT_SYSLOG_INTERVAL and prints a long message via util_out_ptr. */ start_timer((TID)&util_out_syslog_dump, UTIL_OUT_SYSLOG_INTERVAL, util_out_syslog_dump, 0, NULL); return; } # endif sys_get_curr_time(&cur_time); mv_zintcmd = find_mvstent_cmd(ZINTCMD_HANG, restart_pc, restart_ctxt, FALSE); if (!mv_zintcmd) add_int_to_abs_time(&cur_time, ms, &end_time); else { end_time = mv_zintcmd->mv_st_cont.mvs_zintcmd.end_or_remain; cur_time = sub_abs_time(&end_time, &cur_time); /* get remaing time to sleep */ if (0 <= cur_time.at_sec) ms = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000); else ms = 0; /* all done */ /* restore/pop previous zintcmd_active[ZINTCMD_HANG] hints */ TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).count--; assert(0 <= TAREF1(zintcmd_active, ZINTCMD_HANG).count); if (mv_chain == mv_zintcmd) POP_MV_STENT(); /* just pop if top of stack */ else { /* flag as not active */ mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP; mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL; } if (0 == ms) return; /* done HANGing */ } # ifdef UNIX if (ms < 10) SLEEP_USEC(ms * 1000, TRUE); /* Finish the sleep if it is less than 10ms. */ else hiber_start(ms); # elif defined(VMS) time[0] = -time_low_ms(ms); time[1] = -time_high_ms(ms) - 1; efn_mask = (1 << efn_outofband | 1 << efn_timer); if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status); if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status); if (outofband) { if (SS$_WASCLR == (status = sys$readef(efn_timer, &efn_mask))) { if (SS$_NORMAL != (status = sys$cantim(&time, 0))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$cantim"), CALLFROM, status); } else assertpro(SS$_WASSET == status); } # endif } else rel_quant(); if (outofband) { PUSH_MV_STENT(MVST_ZINTCMD); mv_chain->mv_st_cont.mvs_zintcmd.end_or_remain = end_time; mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_check = restart_ctxt; mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_check = restart_pc; /* save current information from zintcmd_active */ mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last; mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = restart_pc; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = restart_ctxt; TAREF1(zintcmd_active, ZINTCMD_HANG).count++; mv_chain->mv_st_cont.mvs_zintcmd.command = ZINTCMD_HANG; outofband_action(FALSE); } return; }
/* * init_timer - initialize the timer data structures */ void init_timer(void) { /* * Initialize... */ alarm_flag = FALSE; alarm_overflow = 0; adjust_timer = 1; stats_timer = SECSPERHR; leapf_timer = SECSPERDAY; huffpuff_timer = 0; interface_timer = 0; current_time = 0; timer_overflows = 0; timer_xmtcalls = 0; timer_timereset = 0; #ifndef SYS_WINNT /* * Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT * seconds from now and they continue on every 2**EVENT_TIMEOUT * seconds. */ # ifndef VMS # ifdef HAVE_TIMER_CREATE if (TC_ERR == timer_create(CLOCK_REALTIME, NULL, &timer_id)) { msyslog(LOG_ERR, "timer_create failed, %m"); exit(1); } # endif signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1 << EVENT_TIMEOUT); itimer.it_interval.itv_frac = itimer.it_value.itv_frac = 0; set_timer_or_die(&itimer); # else /* VMS follows */ vmsinc[0] = 10000000; /* 1 sec */ vmsinc[1] = 0; lib$emul(&(1<<EVENT_TIMEOUT), &vmsinc, &0, &vmsinc); sys$gettim(&vmstimer); /* that's "now" as abstime */ lib$addx(&vmsinc, &vmstimer, &vmstimer); sys$setimr(0, &vmstimer, alarming, alarming, 0); # endif /* VMS */ #else /* SYS_WINNT follows */ /* * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds * Under Windows/NT, */ WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL); if (WaitableTimerHandle == NULL) { msyslog(LOG_ERR, "CreateWaitableTimer failed: %m"); exit(1); } else { DWORD Period; LARGE_INTEGER DueTime; BOOL rc; Period = (1 << EVENT_TIMEOUT) * 1000; DueTime.QuadPart = Period * 10000i64; rc = SetWaitableTimer(WaitableTimerHandle, &DueTime, Period, NULL, NULL, FALSE); if (!rc) { msyslog(LOG_ERR, "SetWaitableTimer failed: %m"); exit(1); } } #endif /* SYS_WINNT */ }
void ccp_close1(ccp_db_header *db) { ccp_db_header *db0, *db1; ccp_que_entry *que_ent; ccp_relque *que_hd; mem_list *ml_ptr, *ml_ptr_hold; sgmnt_addrs *csa; vms_gds_info *gds_info; unsigned char section_name[GLO_NAME_MAXLEN]; uint4 retadr[2], status, outaddrs[2]; struct dsc$descriptor_s name_dsc; if (ccp_stop) ccp_stop_ctr--; if (db->stale_in_progress) sys$cantim(&db->stale_timer_id, PSL$C_USER); ccp_quemin_adjust(CCP_CLOSE_REGION); sys$cantim(&db->tick_timer_id, PSL$C_USER); sys$cantim(&db->quantum_timer_id, PSL$C_USER); db->segment->nl->ccp_state = CCST_CLOSED; db->wmexit_requested = TRUE; /* ignore any blocking ASTs - already releasing */ gds_info = FILE_INFO(db->greg); if (JNL_ENABLED(db->glob_sec)) { if (db->segment->jnl != NULL && db->segment->jnl->channel != 0) { status = sys$setimr(0, delta_1_sec, ccp_close_timeout, &db->close_timer_id, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = ccp_enqw(EFN$C_ENF, LCK$K_EXMODE, &db->wm_iosb, LCK$M_CONVERT | LCK$M_NOQUEUE, NULL, 0, NULL, 0, NULL, PSL$C_USER, 0); if (status == SS$_NOTQUEUED) /* We're not the only node accessing the journal file */ jnl_file_close(db->greg, FALSE, FALSE); else { /***** Check error status here? *****/ if (db->segment->jnl->jnl_buff->before_images && db->segment->ti->curr_tn > db->segment->jnl->jnl_buff->epoch_tn) { csa = db->segment; JNL_SHORT_TIME(jgbl.gbl_jrec_time); /* needed for jnl_put_jrt_pini() and jnl_write_epoch_rec() */ if (0 == csa->jnl->pini_addr) jnl_put_jrt_pini(csa); db->segment->jnl->jnl_buff->epoch_tn = db->segment->ti->curr_tn; jnl_write_epoch_rec(db->segment); } jnl_file_close(db->greg, TRUE, FALSE); } sys$cantim(&db->close_timer_id, PSL$C_USER); status = gtm_deq(gds_info->s_addrs.jnl->jnllsb->lockid, NULL, PSL$C_USER, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ } } db->segment = NULL; /* Warn AST's that the segment has been deleted */ status = sys$deq(db->lock_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL); if (status != SS$_NORMAL && status != SS$_CANCELGRANT) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$deq(db->refcnt_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL); if (status != SS$_NORMAL && status != SS$_CANCELGRANT) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$deq(db->wm_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL); if (status != SS$_NORMAL && status != SS$_CANCELGRANT) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$deq(db->flush_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL); if (status != SS$_NORMAL && status != SS$_CANCELGRANT) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$cancel(gds_info->fab->fab$l_stv); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$dassgn(gds_info->fab->fab$l_stv); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ csa = &gds_info->s_addrs; outaddrs[0] = csa->db_addrs[0] - OS_PAGE_SIZE; /* header no access page */ outaddrs[1] = csa->db_addrs[1] + OS_PAGE_SIZE; /* trailer no access page */ if (FALSE == is_va_free(outaddrs[0])) gtm_deltva(outaddrs, NULL, PSL$C_USER); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = sys$cretva(csa->db_addrs, retadr, PSL$C_USER); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ assert(retadr[0] == csa->db_addrs[0] && retadr[1] == csa->db_addrs[1]); ml_ptr_hold=db->mem_ptr; if (ml_ptr_hold->prev != NULL) { /* if prior segment is adjacent and free, coalesce the segments */ if (ml_ptr_hold->prev->free && ml_ptr_hold->addr == ml_ptr_hold->prev->addr + OS_PAGELET_SIZE * ml_ptr_hold->prev->pages) { ml_ptr = ml_ptr_hold->prev; ml_ptr->next = ml_ptr_hold->next; if (ml_ptr->next != NULL) ml_ptr->next->prev = ml_ptr; ml_ptr->pages += ml_ptr_hold->pages; free(ml_ptr_hold); ml_ptr_hold = ml_ptr; } } if (ml_ptr_hold->next != NULL) { /* if next segment is adjacent and free, coalesce the segments */ if (ml_ptr_hold->next->free && ml_ptr_hold->next->addr == ml_ptr_hold->addr + OS_PAGELET_SIZE * ml_ptr_hold->pages) { ml_ptr = ml_ptr_hold->next; ml_ptr_hold->next = ml_ptr->next; if (ml_ptr_hold->next != NULL) ml_ptr_hold->next->prev = ml_ptr_hold; ml_ptr_hold->pages += ml_ptr->pages; free(ml_ptr); } } ml_ptr_hold->free = TRUE; global_name("GT$S", &gds_info->file_id, section_name); name_dsc.dsc$a_pointer = §ion_name[1]; name_dsc.dsc$w_length = section_name[0]; name_dsc.dsc$b_dtype = DSC$K_DTYPE_T; name_dsc.dsc$b_class = DSC$K_CLASS_S; status = del_sec(SEC$M_SYSGBL, &name_dsc, NULL); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ /* Dequeue locks after delete section in ccp_close, acquire lock before create section in gvcst_init, release lock after delete section in gds_rundown */ status = gtm_deq(db->lock_iosb.lockid, NULL, PSL$C_USER, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = gtm_deq(db->refcnt_iosb.lockid, NULL, PSL$C_USER, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = gtm_deq(db->wm_iosb.lockid, NULL, PSL$C_USER, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ status = gtm_deq(db->flush_iosb.lockid, NULL, PSL$C_USER, 0); if (status != SS$_NORMAL) ccp_signal_cont(status); /***** Is this reasonable? *****/ que_hd = &ccp_action_que[PRIORITY]; for (que_ent = (char *)que_hd + que_hd->bl; que_ent != que_hd; que_ent = (char *)que_ent + que_ent->q.bl) if (que_ent->value.v.h == db) que_ent->value.v.h = 0; free(gds_info->fab->fab$l_nam); free(gds_info->fab); free(db->greg->dyn.addr); free(db->greg); /* Remove db from list, this list should never be changed in an AST */ for (db0 = ccp_reg_root, db1 = NULL; db0 != db; db1 = db0, db0 = db0->next) ; if (db1 == NULL) ccp_reg_root = db0->next; else db1->next = db0->next; free(db); return; }
/* * init_timer - initialize the timer data structures */ void init_timer(void) { # if defined SYS_WINNT & !defined(SYS_CYGWIN32) HANDLE hToken = INVALID_HANDLE_VALUE; TOKEN_PRIVILEGES tkp; # endif /* SYS_WINNT */ /* * Initialize... */ alarm_flag = 0; alarm_overflow = 0; adjust_timer = 1; stats_timer = 0; huffpuff_timer = 0; interface_timer = 0; current_time = 0; timer_overflows = 0; timer_xmtcalls = 0; timer_timereset = 0; #if !defined(SYS_WINNT) /* * Set up the alarm interrupt. The first comes 2**EVENT_TIMEOUT * seconds from now and they continue on every 2**EVENT_TIMEOUT * seconds. */ # if !defined(VMS) # if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) if (timer_create (CLOCK_REALTIME, NULL, &ntpd_timerid) == # ifdef SYS_VXWORKS ERROR # else -1 # endif ) { fprintf (stderr, "timer create FAILED\n"); exit (0); } (void) signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1<<EVENT_TIMEOUT); itimer.it_interval.tv_nsec = itimer.it_value.tv_nsec = 0; timer_settime(ntpd_timerid, 0 /*!TIMER_ABSTIME*/, &itimer, NULL); # else (void) signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1<<EVENT_TIMEOUT); itimer.it_interval.tv_usec = itimer.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); # endif # else /* VMS */ vmsinc[0] = 10000000; /* 1 sec */ vmsinc[1] = 0; lib$emul(&(1<<EVENT_TIMEOUT), &vmsinc, &0, &vmsinc); sys$gettim(&vmstimer); /* that's "now" as abstime */ lib$addx(&vmsinc, &vmstimer, &vmstimer); sys$setimr(0, &vmstimer, alarming, alarming, 0); # endif /* VMS */ #else /* SYS_WINNT */ _tzset(); /* * Get privileges needed for fiddling with the clock */ /* get the current process token handle */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { msyslog(LOG_ERR, "OpenProcessToken failed: %m"); exit(1); } /* get the LUID for system-time privilege. */ LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; /* one privilege to set */ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; /* get set-time privilege for this process. */ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); /* cannot test return value of AdjustTokenPrivileges. */ if (GetLastError() != ERROR_SUCCESS) { msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); } /* * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds * Under Windows/NT, */ WaitableTimerHandle = CreateWaitableTimer(NULL, FALSE, NULL); if (WaitableTimerHandle == NULL) { msyslog(LOG_ERR, "CreateWaitableTimer failed: %m"); exit(1); } else { DWORD Period = (1<<EVENT_TIMEOUT) * 1000; LARGE_INTEGER DueTime; DueTime.QuadPart = Period * 10000i64; if (!SetWaitableTimer(WaitableTimerHandle, &DueTime, Period, NULL, NULL, FALSE) != NO_ERROR) { msyslog(LOG_ERR, "SetWaitableTimer failed: %m"); exit(1); } } #endif /* SYS_WINNT */ }
/* * ------------------------------------------ * Hang the process for a specified time. * * Goes to sleep for a positive value. * Any caught signal will terminate the sleep * following the execution of that signal's catching routine. * * Arguments: * num - time to sleep * * Return: * none * ------------------------------------------ */ void op_hang(mval* num) { int ms; mv_stent *mv_zintcmd; ABS_TIME cur_time, end_time; # ifdef VMS uint4 time[2]; int4 efn_mask, status; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; ms = 0; MV_FORCE_NUM(num); if (num->mvtype & MV_INT) { if (0 < num->m[1]) { assert(MV_BIAS >= 1000); /* if formats change overflow may need attention */ ms = num->m[1] * (1000 / MV_BIAS); } } else if (0 == num->sgn) /* if sign is not 0 it means num is negative */ ms = mval2i(num) * 1000; /* too big to care about fractional amounts */ if (ms) { if (TREF(tpnotacidtime) * 1000 < ms) TPNOTACID_CHECK(HANGSTR); # if defined(DEBUG) && defined(UNIX) if (gtm_white_box_test_case_enabled && (WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number) && (3 > gtm_white_box_test_case_count) && (123000 == ms)) { DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); DBGFPF((stderr, "OP_HANG: will sleep for 20 seconds\n")); LONG_SLEEP(20); DBGFPF((stderr, "OP_HANG: done sleeping\n")); ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); return; } if (gtm_white_box_test_case_enabled && (WBTEST_BREAKMPC == gtm_white_box_test_case_number) && (0 == gtm_white_box_test_case_count) && (999 == ms)) { frame_pointer->old_frame_pointer->mpc = (unsigned char *)GTM64_ONLY(0xdeadbeef12345678) NON_GTM64_ONLY(0xdead1234); return; } /* Upon seeing a .999s hang this white-box test launches a timer that pops with a period of UTIL_OUT_SYSLOG_INTERVAL * and prints a long message via util_out_ptr. */ if (gtm_white_box_test_case_enabled && (WBTEST_UTIL_OUT_BUFFER_PROTECTION == gtm_white_box_test_case_number) && (0 == gtm_white_box_test_case_count) && (999 == ms)) { start_timer((TID)&util_out_syslog_dump, UTIL_OUT_SYSLOG_INTERVAL, util_out_syslog_dump, 0, NULL); return; } # endif sys_get_curr_time(&cur_time); mv_zintcmd = find_mvstent_cmd(ZINTCMD_HANG, restart_pc, restart_ctxt, FALSE); if (!mv_zintcmd) add_int_to_abs_time(&cur_time, ms, &end_time); else { end_time = mv_zintcmd->mv_st_cont.mvs_zintcmd.end_or_remain; cur_time = sub_abs_time(&end_time, &cur_time); /* get remaing time to sleep */ if (0 <= cur_time.at_sec) ms = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000); else ms = 0; /* all done */ /* restore/pop previous zintcmd_active[ZINTCMD_HANG] hints */ TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior; TAREF1(zintcmd_active, ZINTCMD_HANG).count--; assert(0 <= TAREF1(zintcmd_active, ZINTCMD_HANG).count); if (mv_chain == mv_zintcmd) POP_MV_STENT(); /* just pop if top of stack */ else { /* flag as not active */ mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP; mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL; } if (0 == ms) return; /* done HANGing */ } UNIX_ONLY(hiber_start(ms);) VMS_ONLY( time[0] = -time_low_ms(ms); time[1] = -time_high_ms(ms) - 1; efn_mask = (1 << efn_outofband | 1 << efn_timer); if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0))) rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status); if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask))) rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status); ) if (outofband)