[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);
  }
  
  /*