[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MiNT device drivers, first try at iwake(), and a 1-liner



> 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