void p_set_alarm(double secs, void (*on_alarm)(void *c), void *context) { p_alarm *me; p_alarm *next = alarm_next; p_alarm **prev = &alarm_next; double time; if (!alarm_free) { int n = 8; alarm_free = p_malloc(sizeof(p_alarm)*n); alarm_free[--n].next = 0; while (n--) alarm_free[n].next = &alarm_free[n+1]; } me = alarm_free; me->time = time = p_wall_secs() + secs; me->on_alarm = on_alarm; me->context = context; /* insert me into alarm_next list, kept in order of time */ while (next && next->time<=time) { prev = &next->next; next = next->next; } alarm_free = alarm_free->next; me->next = next; *prev = me; }
void Y_timer(int nArgs) { Operand op; double *absTime, *incTime, cpu, sys, wall; if (nArgs < 0) { y_wall0= p_wall_secs(); return; } if (nArgs<1 || nArgs>2 || !sp->ops) YError("timer takes exactly one or two arguments"); sp->ops->FormOperand(sp, &op); if (op.ops!=&doubleOps || op.type.number!=3) YError("timer arguments must be array(double,3)"); if (nArgs==1) { absTime= op.value; incTime= 0; } else { incTime= op.value; (sp-1)->ops->FormOperand(sp-1, &op); if (op.ops!=&doubleOps || op.type.number!=3) YError("timer arguments must be array(double,3)"); absTime= op.value; } cpu= p_cpu_secs(&sys); wall= p_wall_secs() - y_wall0; if (incTime) { incTime[0]+= cpu-absTime[0]; incTime[1]+= sys-absTime[1]; incTime[2]+= wall-absTime[2]; } absTime[0]= cpu; absTime[1]= sys; absTime[2]= wall; Drop(nArgs); }
double p_cpu_secs(double *sys) { LARGE_INTEGER t; if (sys) *sys = 0.; if (p_cpu_unit == 0.) { if (QueryPerformanceFrequency(&t)) p_cpu_unit = 1./(t.LowPart + 4294967296.*t.HighPart); else p_cpu_unit = -1.; } if (p_cpu_unit == -1. || !QueryPerformanceCounter(&t)) return p_wall_secs(); return p_cpu_unit*(t.LowPart + 4294967296.*t.HighPart); }
static double alarm_query(void) { if (alarm_next->time != -1.e35) { double time = p_wall_secs(); p_alarm *next = alarm_next; /* if no alarms need to ring yet, return earliest */ if (next->time > time) return next->time - time; do { next->time = -1.e35; /* mark all alarms that need to ring */ next = next->next; } while (next && next->time<=time); } return 0.0; }