[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: MiNT device drivers, first try at iwake(), and a 1-liner
- Subject: Re: MiNT device drivers, first try at iwake(), and a 1-liner
- From: Juergen Lock <nox@jelal.north.de>
- Date: Mon, 5 Sep 94 0:19:58 CDT
> In-Reply-To: <9408282342.AA10480@topo.matups.fr>; from "Thierry Bousch" at Aug 29, 94 1:42 am
ctrl-alt-f6 listed me some 2000 processes running...
Index: proc.c
@@ -761,7 +821,7 @@
#ifdef DEBUG_INFO
PROC *p = curproc;
- FORCE("Uptime: %ld seconds Loads: %ld %ld %ld Processes running: %ld",
+ FORCE("Uptime: %ld seconds Loads: %ld %ld %ld Processes running: %d",
uptime,
(avenrun[0]*100)/2048 , (avenrun[1]*100)/2048, (avenrun[2]*100/2048),
number_running);
now is there anyone just writing a device driver who can test this out? :)
Index: file.h
@@ -282,9 +282,10 @@
/* miscellaneous other things */
long ARGS_ON_STACK (*ikill) P_((int, int));
+ void ARGS_ON_STACK (*iwake) P_((int que, long cond, short pid));
/* reserved for future use */
- long res2[4];
+ long res2[3];
};
/* flags for open() modes */
Index: proto.h
@@ -279,6 +279,7 @@
void ARGS_ON_STACK preempt P_((void));
int ARGS_ON_STACK sleep P_((int que, long cond));
void ARGS_ON_STACK wake P_((int que, long cond));
+void ARGS_ON_STACK iwake P_((int que, long cond, short pid));
void ARGS_ON_STACK wakeselect P_((long param));
void DUMPPROC P_((void));
void calc_load_average P_((void));
Index: main.c
@@ -198,7 +198,7 @@
nap, sleep, wake, wakeselect,
denyshare, denylock, addtimeout, canceltimeout,
addroottimeout, cancelroottimeout,
- ikill
+ ikill, iwake
};
/* table of processor frame sizes in _words_ (not used on MC68000) */
Index: proc.c
@@ -481,7 +481,7 @@
}
}
-static long sleepcond;
+static long sleepcond, iwakecond;
/*
* sleep: returns 1 if no signals have happened since our last sleep, 0
@@ -541,9 +541,11 @@
*/
if ((que == READY_Q && !sys_q[READY_Q]) ||
((sleepcond != cond ||
+ (iwakecond == cond && cond) ||
(_que & 0x100 && curproc->wait_cond != cond)) &&
(!sys_q[READY_Q] || (newslice = 0, proc_clock)))) {
/* we're just going to wake up again right away! */
+ iwakecond = 0;
spl(sr);
do_wakeup_things(sr, newslice);
return (onsigs != curproc->nsigs);
@@ -552,6 +554,7 @@
* unless our time slice has expired (proc_clock == 0) and other
* processes are ready...
*/
+ iwakecond = 0;
if (!newslice)
que = READY_Q;
else
@@ -663,19 +666,12 @@
* for the indicated condition
*/
-void ARGS_ON_STACK
-wake(que, cond)
+INLINE static void
+do_wake(que, cond)
int que;
long cond;
{
PROC *p;
-
- if (que == READY_Q) {
- ALERT("wake: why wake up ready processes??");
- return;
- }
- if (sleepcond == cond)
- sleepcond = 0;
top:
for(p = sys_q[que]; p;) {
short s = spl7();
@@ -696,6 +692,70 @@
}
}
+void ARGS_ON_STACK
+wake(que, cond)
+ int que;
+ long cond;
+{
+ if (que == READY_Q) {
+ ALERT("wake: why wake up ready processes??");
+ return;
+ }
+ if (sleepcond == cond)
+ sleepcond = 0;
+ do_wake(que, cond);
+}
+
+/*
+ * iwake(que, cond, pid): special version of wake() for IO interrupt
+ * handlers and such. the normal wake() would lose when its
+ * interrupt goes off just before a process is calling sleep() on the
+ * same condition (similar problem like with wakeselect...)
+ *
+ * use like this:
+ * static ipid = -1;
+ * static sleepers = 0; (optional, to save useless calls)
+ * ...
+ * device_read(...)
+ * {
+ * ipid = curproc->pid; (p_getpid() for device drivers...)
+ * while (not ready for IO...) {
+ * ++sleepers;
+ * sleep(IO_Q, cond);
+ * --sleepers;
+ * }
+ * ipid = -1;
+ * ...
+ * }
+ *
+ * and in the interrupt handler:
+ * if (sleepers)
+ * iwake(IO_Q, cond, ipid);
+ *
+ * caller is responsible for not trying to wake READY_Q or other nonsense :)
+ * and making sure the passed pid is always -1 when curproc is calling
+ * sleep() for another than the waked que/condition.
+ */
+
+void ARGS_ON_STACK
+iwake(que, cond, pid)
+ int que;
+ long cond;
+ short pid;
+{
+ if (pid >= 0) {
+ short s = spl7();
+ if (iwakecond == cond) {
+ spl(s);
+ return;
+ }
+ if (curproc->pid == pid && !curproc->wait_q)
+ iwakecond = cond;
+ spl(s);
+ }
+ do_wake(que, cond);
+}
+
/*
* wakeselect(p): wake process p from a select() system call
* may be called by an interrupt handler or whatever
all the best
Juergen
--
J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
...ohne Gewehr
PGP public key fingerprint = 8A 18 58 54 03 7B FC 12 1F 8B 63 C7 19 27 CF DA