[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
addroottimeout() patches v2
These are the patches that bring addroottimeout() and cancelroottimeout()
to Mint 1.10.
They fix a bug in the previous release of the patches. Please update your
version of Mint.
Kay.
*** file.h.orig Sun Mar 20 19:08:10 1994
--- file.h Wed May 18 23:01:32 1994
***************
*** 243,251 ****
/* functions for adding/cancelling timeouts */
struct timeout * ARGS_ON_STACK (*addtimeout) P_((long, void (*)()));
void ARGS_ON_STACK (*canceltimeout) P_((struct timeout *));
/* reserved for future use */
! long res2[7];
};
/* flags for open() modes */
--- 243,253 ----
/* functions for adding/cancelling timeouts */
struct timeout * ARGS_ON_STACK (*addtimeout) P_((long, void (*)()));
void ARGS_ON_STACK (*canceltimeout) P_((struct timeout *));
+ struct timeout * ARGS_ON_STACK (*addroottimeout) P_((long, void (*)(), short));
+ void ARGS_ON_STACK (*cancelroottimeout) P_((struct timeout *));
/* reserved for future use */
! long res2[5];
};
/* flags for open() modes */
*** main.c.orig Sun Mar 20 19:07:52 1994
--- main.c Wed May 18 23:00:44 1994
***************
*** 193,199 ****
strnicmp, stricmp, strlwr, strupr, ksprintf,
ms_time, unixtim, dostim,
nap, sleep, wake, wakeselect,
! denyshare, denylock, addtimeout, canceltimeout
};
/* table of processor frame sizes in _words_ (not used on MC68000) */
--- 193,200 ----
strnicmp, stricmp, strlwr, strupr, ksprintf,
ms_time, unixtim, dostim,
nap, sleep, wake, wakeselect,
! denyshare, denylock, addtimeout, canceltimeout,
! addroottimeout, cancelroottimeout
};
/* table of processor frame sizes in _words_ (not used on MC68000) */
*** proc.h.orig Sun Mar 20 19:08:10 1994
--- proc.h Sun Mar 20 19:07:40 1994
***************
*** 67,72 ****
--- 67,73 ----
struct proc *proc;
long when;
void (*func) P_((struct proc *)); /* function to call at timeout */
+ short flags;
} TIMEOUT;
#ifndef GENMAGIC
*** proto.h.orig Sun Mar 20 19:08:10 1994
--- proto.h Wed May 18 22:59:42 1994
***************
*** 274,281 ****
--- 274,283 ----
/* timeout.c */
TIMEOUT * ARGS_ON_STACK addtimeout P_((long delta, void (*func)(PROC *p)));
+ TIMEOUT * ARGS_ON_STACK addroottimeout P_((long delta, void (*func)(PROC *p), short flags));
void ARGS_ON_STACK cancelalltimeouts P_((void));
void ARGS_ON_STACK canceltimeout P_((TIMEOUT *which));
+ void ARGS_ON_STACK cancelroottimeout P_((TIMEOUT *which));
void ARGS_ON_STACK timeout P_((void));
void checkalarms P_((void));
void ARGS_ON_STACK nap P_((unsigned n));
*** timeout.c.orig Sun Mar 20 19:07:52 1994
--- timeout.c Wed May 18 22:58:18 1994
***************
*** 19,55 ****
extern short in_kernel; /* in main.c */
static void unnapme P_((PROC *));
! /*
! * addtimeout(long delta, void (*func)()): schedule a timeout for the current
! * process, to take place in "delta" milliseconds. "func" specifies a
! * function to be called at that time; the function is passed as a parameter
! * the process for which the timeout was specified (i.e. the value of
! * curproc at the time addtimeout() was called; note that this is probably
! * *not* the current process when the timeout occurs).
*/
!
! TIMEOUT *tlist;
- #define newtimeout() (TIMEOUT *)kmalloc(SIZEOF(TIMEOUT))
- #define disposetimeout(t) kfree(t)
! TIMEOUT * ARGS_ON_STACK
! addtimeout(delta, func)
! long delta;
! void (*func) P_((PROC *));
{
! TIMEOUT *t, **prev, *cur;
! t = newtimeout();
! /* BUG: we should have some fallback mechanism for timeouts when the
! kernel memory is exhausted
! */
! assert(t);
! t->proc = curproc;
! t->func = func;
cur = tlist;
prev = &tlist;
--- 19,80 ----
extern short in_kernel; /* in main.c */
static void unnapme P_((PROC *));
+ static TIMEOUT *newtimeout P_((short));
+ static void disposetimeout P_((TIMEOUT *));
+ static void inserttimeout P_ ((TIMEOUT *, long));
+
+ #define TIMEOUTS 20 /* # of static timeout structs */
+ #define TIMEOUT_USED 0x01 /* timeout struct is in use */
+ #define TIMEOUT_STATIC 0x02 /* this is a static timeout */
! /* This gets implizitly initialized to zero, thus the flags are
! * set up correctly.
*/
! static TIMEOUT timeouts[TIMEOUTS] = { { 0, }, };
! TIMEOUT *tlist = NULL;
! static TIMEOUT *
! newtimeout(fromlist)
! short fromlist;
{
! TIMEOUT *t;
! short i, sr;
! if (!fromlist) {
! t = kmalloc(SIZEOF(TIMEOUT));
! if (t) {
! t->flags = 0;
! return t;
! }
! }
! sr = spl7();
! for (i = 0; i < TIMEOUTS; ++i) {
! if (!(timeouts[i].flags & TIMEOUT_USED)) {
! timeouts[i].flags |= (TIMEOUT_STATIC|TIMEOUT_USED);
! spl(sr);
! return &timeouts[i];
! }
! }
! spl(sr);
! return 0;
! }
! static void
! disposetimeout(t)
! TIMEOUT *t;
! {
! if (t->flags & TIMEOUT_STATIC) t->flags &= ~TIMEOUT_USED;
! else kfree(t);
! }
! static void
! inserttimeout(t, delta)
! TIMEOUT *t;
! long delta;
! {
! TIMEOUT **prev, *cur;
! short sr = spl7();
cur = tlist;
prev = &tlist;
***************
*** 59,65 ****
t->next = cur;
t->when = delta;
*prev = t;
! return t;
}
delta -= cur->when;
prev = &cur->next;
--- 84,91 ----
t->next = cur;
t->when = delta;
*prev = t;
! spl(sr);
! return;
}
delta -= cur->when;
prev = &cur->next;
***************
*** 69,74 ****
--- 95,167 ----
t->when = delta;
t->next = cur;
*prev = t;
+ spl(sr);
+ }
+
+ /*
+ * addtimeout(long delta, void (*func)()): schedule a timeout for the current
+ * process, to take place in "delta" milliseconds. "func" specifies a
+ * function to be called at that time; the function is passed as a parameter
+ * the process for which the timeout was specified (i.e. the value of
+ * curproc at the time addtimeout() was called; note that this is probably
+ * *not* the current process when the timeout occurs).
+ *
+ * NOTE: if kernel memory is low, newtimeout() will try to get a statically
+ * allocated timeout struct (fallback method).
+ */
+
+ TIMEOUT * ARGS_ON_STACK
+ addtimeout(delta, func)
+ long delta;
+ void (*func) P_((PROC *));
+ {
+ TIMEOUT *t;
+
+ t = newtimeout(0);
+
+ /* BUG: we should have some fallback mechanism for timeouts when the
+ kernel memory is exhausted
+ */
+ assert(t);
+
+ t->proc = curproc;
+ t->func = func;
+ inserttimeout(t, delta);
+ return t;
+ }
+
+ /*
+ * addroottimeout(long delta, void (*)(PROC *), short flags);
+ * Same as addtimeout(), except that the timeout is attached to Pid 0 (MiNT).
+ * This means the timeout won't be cancelled if the process which was
+ * running at the time addroottimeout() was called exits.
+ *
+ * Currently only bit 0 of `flags' is used. Meaning:
+ * Bit 0 set: Call from interrupt (cannot use kmalloc, use statically
+ * allocated `struct timeout' instead).
+ * Bit 0 clear: Not called from interrupt, can use kmalloc.
+ *
+ * Thus addroottimeout() can be called from interrupts (bit 0 of flags set),
+ * which makes it *extremly* useful for device drivers.
+ * A serial device driver would make an addroottimeout(0, check_keys, 1)
+ * if some bytes have arrived.
+ * check_keys() is then called at the next context switch, can use all
+ * the kernel functions and can do time cosuming jobs.
+ */
+
+ TIMEOUT * ARGS_ON_STACK
+ addroottimeout(delta, func, flags)
+ long delta;
+ void (*func) P_((PROC *));
+ short flags;
+ {
+ TIMEOUT *t;
+
+ t = newtimeout(flags & 1);
+ if (!t) return NULL;
+ t->proc = rootproc;
+ t->func = func;
+ inserttimeout(t, delta);
return t;
}
***************
*** 82,87 ****
--- 175,181 ----
{
TIMEOUT *cur, **prev, *old;
long delta;
+ short sr = spl7 ();
cur = tlist;
prev = &tlist;
***************
*** 91,103 ****
--- 185,203 ----
old = cur;
*prev = cur = cur->next;
if (cur) cur->when += delta;
+ spl(sr);
disposetimeout(old);
+ sr = spl7();
+ /* ++kay: just in case an interrupt handler installed a
+ * timeout right after `prev' and before `cur' */
+ cur = *prev;
}
else {
prev = &cur->next;
cur = cur->next;
}
}
+ spl (sr);
}
/*
***************
*** 115,133 ****
TIMEOUT *this;
{
TIMEOUT *cur, **prev;
prev = &tlist;
for (cur = tlist; cur; cur = cur->next) {
! if (cur == this && cur->proc == curproc) {
*prev = cur->next;
if (cur->next) {
cur->next->when += this->when;
}
disposetimeout(this);
! break;
}
prev = &cur->next;
}
}
/*
--- 215,259 ----
TIMEOUT *this;
{
TIMEOUT *cur, **prev;
+ short sr = spl7();
+
+ prev = &tlist;
+ for (cur = tlist; cur; cur = cur->next) {
+ if (cur == this && (cur->proc == curproc)) {
+ *prev = cur->next;
+ if (cur->next) {
+ cur->next->when += this->when;
+ }
+ spl (sr);
+ disposetimeout(this);
+ return;
+ }
+ prev = &cur->next;
+ }
+ spl(sr);
+ }
+
+ void ARGS_ON_STACK
+ cancelroottimeout(this)
+ TIMEOUT *this;
+ {
+ TIMEOUT *cur, **prev;
+ short sr = spl7();
prev = &tlist;
for (cur = tlist; cur; cur = cur->next) {
! if (cur == this && (cur->proc == rootproc)) {
*prev = cur->next;
if (cur->next) {
cur->next->when += this->when;
}
+ spl (sr);
disposetimeout(this);
! return;
}
prev = &cur->next;
}
+ spl(sr);
}
/*
***************
*** 170,175 ****
--- 296,302 ----
long delta;
void (*evnt) P_((PROC *));
TIMEOUT *old;
+ short sr;
/* do the once per second things */
while (our_clock < 0) {
***************
*** 180,201 ****
reset_priorities();
}
/* see if there are outstanding timeout requests to do */
while (tlist && ((delta = tlist->when) <= 0)) {
p = tlist->proc;
- TRACE(("doing timeout code for pid %d", p->pid));
evnt = tlist->func;
old = tlist;
tlist = tlist->next;
- disposetimeout(old);
- /* call the timeout function */
- (*evnt)(p);
-
/* if delta < 0, it's possible that the time has come for the next timeout
! to occur */
if (tlist)
tlist->when += delta;
}
}
/*
--- 307,335 ----
reset_priorities();
}
+ sr = spl7();
/* see if there are outstanding timeout requests to do */
while (tlist && ((delta = tlist->when) <= 0)) {
p = tlist->proc;
evnt = tlist->func;
old = tlist;
tlist = tlist->next;
/* if delta < 0, it's possible that the time has come for the next timeout
! * to occur.
! * ++kay: moved this before the timeout fuction is called, in case the
! * timeout function installes a new timeout. */
if (tlist)
tlist->when += delta;
+ spl(sr);
+ /* ++kay: debug output at spl7 hangs the system, so moved it here */
+ TRACE(("doing timeout code for pid %d", p->pid));
+ disposetimeout(old);
+
+ /* call the timeout function */
+ (*evnt)(p);
+ sr = spl7();
}
+ spl(sr);
}
/*