From: George Anzinger <george@mvista.com>

- Removes C++ comment in favor of C style.

- Removes the special treatment for MIPS SIGEV values.  We only require
  (and error if this fails) that the SIGEV_THREAD_ID value not share bits
  with the other SIGEV values.  Note that mips has yet to define this value
  so when they do...

- Corrects the check for the signal range to be from 1 to SIGRTMAX
  inclusive.

- Adds a check to verify that kmem_cache_alloc() actually returned a timer,
  error if not.

- Fixes a bug in timer_gettime() where the incorrect value was returned if
  a signal was pending on the timer OR the timer was a SIGEV_NONE timer.



---

 25-akpm/kernel/posix-timers.c |   71 ++++++++++++++++++++++++++----------------
 1 files changed, 45 insertions(+), 26 deletions(-)

diff -puN kernel/posix-timers.c~posix-timers-fixes kernel/posix-timers.c
--- 25/kernel/posix-timers.c~posix-timers-fixes	Tue Jan 27 14:58:16 2004
+++ 25-akpm/kernel/posix-timers.c	Tue Jan 27 14:58:16 2004
@@ -2,8 +2,26 @@
  * linux/kernel/posix_timers.c
  *
  *
- * 2002-10-15  Posix Clocks & timers by George Anzinger
- *			     Copyright (C) 2002 by MontaVista Software.
+ * 2002-10-15  Posix Clocks & timers
+ *                           by George Anzinger george@mvista.com
+ *
+ *			     Copyright (C) 2002 2003 by MontaVista Software.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MontaVista Software | 1237 East Arques Avenue | Sunnyvale | CA 94085 | USA
  */
 
 /* These are all the functions necessary to implement
@@ -33,7 +51,7 @@
 		       result; })
 
 #endif
-#define CLOCK_REALTIME_RES TICK_NSEC  // In nano seconds.
+#define CLOCK_REALTIME_RES TICK_NSEC  /* In nano seconds. */
 
 static inline u64  mpy_l_X_l_ll(unsigned long mpy1,unsigned long mpy2)
 {
@@ -82,17 +100,15 @@ static spinlock_t idr_lock = SPIN_LOCK_U
 # define timer_active(tmr) BARFY	// error to use outside of SMP
 # define set_timer_inactive(tmr) do { } while (0)
 #endif
-
 /*
- * For some reason mips/mips64 define the SIGEV constants plus 128.
- * Here we define a mask to get rid of the common bits.	 The
- * optimizer should make this costless to all but mips.
- * Note that no common bits (the non-mips case) will give 0xffffffff.
- */
-#define MIPS_SIGEV ~(SIGEV_NONE & \
-		      SIGEV_SIGNAL & \
-		      SIGEV_THREAD &  \
-		      SIGEV_THREAD_ID)
+ * we assume that the new SIGEV_THREAD_ID shares no bits with the other
+ * SIGEV values.  Here we put out an error if this assumption fails.
+ */
+#if SIGEV_THREAD_ID != (SIGEV_THREAD_ID & \
+                       ~(SIGEV_SIGNAL | SIGEV_NONE | SIGEV_THREAD))
+#error "SIGEV_THREAD_ID must not share bit with other SIGEV values!"
+#endif
+
 
 #define REQUEUE_PENDING 1
 /*
@@ -301,7 +317,7 @@ static void timer_notify_task(struct k_i
 	if (timr->it_incr)
 		timr->sigq->info.si_sys_private = ++timr->it_requeue_pending;
 
-	if (timr->it_sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV)
+	if (timr->it_sigev_notify & SIGEV_THREAD_ID )
 		ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
 			timr->it_process);
 	else
@@ -338,14 +354,14 @@ static inline struct task_struct * good_
 {
 	struct task_struct *rtn = current;
 
-	if ((event->sigev_notify & SIGEV_THREAD_ID & MIPS_SIGEV) &&
+	if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
 		(!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
-			rtn->tgid != current->tgid))
+		 rtn->tgid != current->tgid ||
+		 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
 		return NULL;
 
-	if ((event->sigev_notify & ~SIGEV_NONE & MIPS_SIGEV) &&
-			event->sigev_signo &&
-			((unsigned) (event->sigev_signo > SIGRTMAX)))
+	if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) &&
+	    ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX)))
 		return NULL;
 
 	return rtn;
@@ -365,6 +381,8 @@ static struct k_itimer * alloc_posix_tim
 {
 	struct k_itimer *tmr;
 	tmr = kmem_cache_alloc(posix_timers_cache, GFP_KERNEL);
+	if (!tmr)
+		return tmr;
 	memset(tmr, 0, sizeof (struct k_itimer));
 	tmr->it_id = (timer_t)-1;
 	if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
@@ -586,14 +604,18 @@ do_timer_gettime(struct k_itimer *timr, 
 
 	posix_get_now(&now);
 
-	if (expires && (timr->it_sigev_notify & SIGEV_NONE) && !timr->it_incr &&
-			posix_time_before(&timr->it_timer, &now))
+	if (expires &&
+	    ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) &&
+	    !timr->it_incr &&
+	    posix_time_before(&timr->it_timer, &now))
 		timr->it_timer.expires = expires = 0;
 	if (expires) {
 		if (timr->it_requeue_pending & REQUEUE_PENDING ||
-		    (timr->it_sigev_notify & SIGEV_NONE))
+		    (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
 			while (posix_time_before(&timr->it_timer, &now))
 				posix_bump_timer(timr);
+			expires = timr->it_timer.expires;
+		}
 		else
 			if (!timer_pending(&timr->it_timer))
 				expires = 0;
@@ -804,7 +826,7 @@ do_timer_settime(struct k_itimer *timr, 
 	 * equal to jiffies, so the timer notify function is called directly.
 	 * We do not even queue SIGEV_NONE timers!
 	 */
-	if (!(timr->it_sigev_notify & SIGEV_NONE)) {
+	if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE)) {
 		if (timr->it_timer.expires == jiffies)
 			timer_notify_task(timr);
 		else
@@ -967,9 +989,6 @@ static int do_posix_gettime(struct k_clo
  * if we are interrupted since we don't take lock that will stall us or
  * any other cpu. Voila, no irq lock is needed.
  *
- * Note also that the while loop assures that the sub_jiff_offset
- * will be less than a jiffie, thus no need to normalize the result.
- * Well, not really, if called with ints off :(
  */
 
 static u64 do_posix_clock_monotonic_gettime_parts(

_