[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Tsetitimer()
Here's an implementation of Tsetitimer(), providing interval timers
like the BSD setitimer()/getitimer() system calls.
diff -u ../old/dos.c ./dos.c
--- ../old/dos.c Fri Jul 22 03:48:08 1994
+++ ./dos.c Fri Jul 22 05:53:48 1994
@@ -478,6 +478,211 @@
return oldalarm;
}
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+/*
+ * helper function for t_setitimer: this will be called when the ITIMER_REAL
+ * timer goes off
+ */
+
+static void
+itimer_real_me(p)
+ PROC *p;
+{
+ PROC *real_curproc;
+
+ real_curproc = curproc;
+ curproc = p;
+ if (p->itimer[ITIMER_REAL].interval)
+ p->itimer[ITIMER_REAL].timeout =
+ addtimeout(p->itimer[ITIMER_REAL].interval, itimer_real_me);
+ else
+ p->itimer[ITIMER_REAL].timeout = 0;
+
+ curproc = real_curproc;
+ post_sig(p, SIGALRM);
+}
+
+/*
+ * helper function for t_setitimer: this will be called when the ITIMER_VIRTUAL
+ * timer goes off
+ */
+
+static void
+itimer_virtual_me(p)
+ PROC *p;
+{
+ PROC *real_curproc;
+ long timeleft;
+
+ real_curproc = curproc;
+ curproc = p;
+ timeleft = p->itimer[ITIMER_VIRTUAL].reqtime
+ - (p->systime - p->itimer[ITIMER_VIRTUAL].startsystime);
+ if (timeleft > 0) {
+ p->itimer[ITIMER_VIRTUAL].timeout =
+ addtimeout(timeleft, itimer_virtual_me);
+ } else {
+ timeleft = p->itimer[ITIMER_VIRTUAL].interval;
+ if (timeleft == 0) {
+ p->itimer[ITIMER_VIRTUAL].timeout = 0;
+ } else {
+ p->itimer[ITIMER_VIRTUAL].reqtime = timeleft;
+ p->itimer[ITIMER_VIRTUAL].startsystime = p->systime;
+ p->itimer[ITIMER_VIRTUAL].startusrtime = p->usrtime;
+ p->itimer[ITIMER_VIRTUAL].timeout =
+ addtimeout(timeleft, itimer_virtual_me);
+ }
+ post_sig(p, SIGVTALRM);
+ }
+ curproc = real_curproc;
+}
+
+/*
+ * helper function for t_setitimer: this will be called when the ITIMER_PROF
+ * timer goes off
+ */
+
+static void
+itimer_prof_me(p)
+ PROC *p;
+{
+ PROC *real_curproc;
+ long timeleft;
+
+ real_curproc = curproc;
+ curproc = p;
+ timeleft = p->itimer[ITIMER_PROF].reqtime
+ - (p->systime - p->itimer[ITIMER_PROF].startsystime)
+ - (p->usrtime - p->itimer[ITIMER_PROF].startusrtime);
+ if (timeleft > 0) {
+ p->itimer[ITIMER_PROF].timeout =
+ addtimeout(timeleft, itimer_prof_me);
+ } else {
+ timeleft = p->itimer[ITIMER_PROF].interval;
+ if (timeleft == 0) {
+ p->itimer[ITIMER_PROF].timeout = 0;
+ } else {
+ p->itimer[ITIMER_PROF].reqtime = timeleft;
+ p->itimer[ITIMER_PROF].startsystime = p->systime;
+ p->itimer[ITIMER_PROF].startusrtime = p->usrtime;
+ p->itimer[ITIMER_PROF].timeout =
+ addtimeout(timeleft, itimer_prof_me);
+ }
+ post_sig(p, SIGPROF);
+ }
+ curproc = real_curproc;
+}
+
+/*
+ * t_setitimer(which, interval, value, ointerval, ovalue):
+ * schedule an interval timer
+ * which is ITIMER_REAL (0) for SIGALRM, ITIMER_VIRTUAL (1) for SIGVTALRM,
+ * or ITIMER_PROF (2) for SIGPROF.
+ * the rest of the parameters are pointers to millisecond values.
+ * interval is the value to which the timer will be reset
+ * value is the current timer value
+ * ointerval and ovalue are the previous values
+ */
+
+long ARGS_ON_STACK
+t_setitimer(which, interval, value, ointerval, ovalue)
+ short which;
+ long *interval;
+ long *value;
+ long *ointerval;
+ long *ovalue;
+{
+ long oldtimer;
+ TIMEOUT *t;
+ void (*handler)() = 0;
+ long tmpold;
+
+ if ((which != ITIMER_REAL) && (which != ITIMER_VIRTUAL)
+ && (which != ITIMER_PROF)) {
+ return EINVFN;
+ }
+
+/* ensure that any addresses specified by the calling process are in that
+ process's address space
+*/
+ if ((interval && (!(valid_address((long) interval))))
+ || (value && (!(valid_address((long) value))))
+ || (ointerval && (!(valid_address((long) ointerval))))
+ || (ovalue && (!(valid_address((long) ovalue))))) {
+ return EIMBA;
+ }
+
+/* see how many milliseconds there were to the timeout */
+ oldtimer = 0;
+
+ if (curproc->itimer[which].timeout) {
+ for (t = tlist; t; t = t->next) {
+ oldtimer += t->when;
+ if (t == curproc->itimer[which].timeout)
+ goto foundtimer;
+ }
+ DEBUG(("Tsetitimer: old timer not found!"));
+ oldtimer = 0;
+foundtimer:
+ ;
+ }
+
+ if (ointerval)
+ *ointerval = curproc->itimer[which].interval;
+ if (ovalue) {
+ if (which == ITIMER_REAL) {
+ *ovalue = oldtimer;
+ } else {
+ tmpold = curproc->itimer[which].reqtime
+ - (curproc->systime - curproc->itimer[which].startsystime);
+ if (which == ITIMER_PROF)
+ tmpold -=
+ (curproc->usrtime - curproc->itimer[which].startusrtime);
+ if (tmpold <= 0)
+ tmpold = 0;
+ *ovalue = tmpold;
+ }
+ }
+ if (interval)
+ curproc->itimer[which].interval = *interval;
+ if (value) {
+/* cancel old timer */
+ if (curproc->itimer[which].timeout)
+ canceltimeout(curproc->itimer[which].timeout);
+ curproc->itimer[which].timeout = 0;
+
+/* add a new timer, to occur in x milliseconds */
+ if (*value) {
+ curproc->itimer[which].reqtime = *value;
+ curproc->itimer[which].startsystime =
+ curproc->systime;
+ curproc->itimer[which].startusrtime =
+ curproc->usrtime;
+ switch (which) {
+ case ITIMER_REAL:
+ handler = itimer_real_me;
+ break;
+ case ITIMER_VIRTUAL:
+ handler = itimer_virtual_me;
+ break;
+ case ITIMER_PROF:
+ handler = itimer_prof_me;
+ break;
+ default:
+ break;
+ }
+ curproc->itimer[which].timeout =
+ addtimeout(*value, handler);
+ }
+ else
+ curproc->itimer[which].timeout = 0;
+ }
+ return 0;
+}
+
/*
* sysconf(which): returns information about system configuration.
* "which" specifies which aspect of the system configuration is to
@@ -697,4 +902,5 @@
dos_tab[0x146] = p_setauid;
dos_tab[0x147] = p_getgroups;
dos_tab[0x148] = p_setgroups;
+ dos_tab[0x149] = t_setitimer;
}
diff -u ../old/proc.c ./proc.c
--- ../old/proc.c Fri Jul 22 03:48:56 1994
+++ ./proc.c Fri Jul 22 03:15:54 1994
@@ -116,6 +116,15 @@
p->slices = SLICES(p->pri);
p->starttime = timestamp;
p->startdate = datestamp;
+ p->itimer[0].interval = 0;
+ p->itimer[0].reqtime = 0;
+ p->itimer[0].timeout = 0;
+ p->itimer[1].interval = 0;
+ p->itimer[1].reqtime = 0;
+ p->itimer[1].timeout = 0;
+ p->itimer[2].interval = 0;
+ p->itimer[2].reqtime = 0;
+ p->itimer[2].timeout = 0;
((long *)p->sysstack)[1] = FRAME_MAGIC;
((long *)p->sysstack)[2] = 0;
diff -u ../old/proc.h ./proc.h
--- ../old/proc.h Fri Jul 22 03:48:58 1994
+++ ./proc.h Wed Jul 20 13:16:44 1994
@@ -69,6 +69,14 @@
void (*func) P_((struct proc *)); /* function to call at timeout */
short flags;
} TIMEOUT;
+
+struct itimervalue {
+ TIMEOUT *timeout;
+ long interval;
+ long reqtime;
+ long startsystime;
+ long startusrtime;
+};
#ifndef GENMAGIC
extern TIMEOUT *tlist;
@@ -224,6 +232,7 @@
#define NGROUPMAX 8
short ngroups; /* ts: number of supplementary groups */
short ngroup[NGROUPMAX]; /* ts: supplementary groups */
+ struct itimervalue itimer[3]; /* interval timers */
} PROC;
diff -u ../old/proto.h ./proto.h
--- ../old/proto.h Fri Jul 22 03:50:08 1994
+++ ./proto.h Fri Jul 22 04:15:26 1994
@@ -93,6 +93,7 @@
long ARGS_ON_STACK p_pause P_((void));
long ARGS_ON_STACK t_alarm P_((long x));
long ARGS_ON_STACK t_malarm P_((long x));
+long ARGS_ON_STACK t_setitimer P_((short which, long *interval, long *value, long *ointerval, long *ovalue));
long ARGS_ON_STACK s_ysconf P_((int which));
long ARGS_ON_STACK s_alert P_((char *msg));
void init_dos P_((void));
--
entropy -- it's not just a good idea, it's the second law.
Personal mail: entropy@gnu.ai.mit.edu
MiNT library mail: entropy@terminator.rs.itd.umich.edu
"what do you have against octal?" -jrb