Пример #1
0
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);
    }
}
Пример #2
0
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
}
Пример #3
0
/*
 * ------------------------------------------
 * 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)
Пример #4
0
/*
 * ----------------------------------------------------
 * 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);
}
Пример #5
0
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
  }
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
/*
 * ------------------------------------------------------
 * 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);
		}
	}
}
Пример #9
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));

}
Пример #10
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);
}
Пример #11
0
/*
 * 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 */
}
Пример #12
0
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
}
Пример #13
0
/*
 * 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;  
}
Пример #14
0
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;
}
Пример #15
0
/*
 * 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
}
Пример #16
0
/*
**++
**  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 */
Пример #17
0
/*
 * 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 */
}
Пример #18
0
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 = &gtcm_exi_handler;
	gtcm_exi_blk.arg_cnt = 1;
	gtcm_exi_blk.cond_val = &gtcm_exi_condition;
	sys$dclexh(&gtcm_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(&gtcm_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);
	}
}
Пример #19
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;
	}
}
Пример #20
0
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? *****/

}
Пример #21
0
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 */
Пример #22
0
/*
 * ------------------------------------------
 * 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;
}
Пример #23
0
/*
 * 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 */
}
Пример #24
0
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 = &section_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;
}
Пример #25
0
/*
 * 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 */
}
Пример #26
0
/*
 * ------------------------------------------
 * 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)