]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel: fix notification delivery to non-ANY receivers
authorDavid van Moolenbroek <david@minix3.org>
Fri, 7 Jan 2011 17:04:43 +0000 (17:04 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Fri, 7 Jan 2011 17:04:43 +0000 (17:04 +0000)
kernel/proc.c

index 80c7614c1e886239e4e3129f467ac00193c8a12f..871e04ecdf56d71435427b3ac608fb6f1076e821 100644 (file)
@@ -796,8 +796,7 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
  */
   register struct proc **xpp;
   sys_map_t *map;
-  bitchunk_t *chunk;
-  int i, r, src_id, src_proc_nr, src_p;
+  int i, r, src_id, found, src_proc_nr, src_p;
 
   assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
 
@@ -823,24 +822,38 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
 
     /* Check if there are pending notifications, except for SENDREC. */
     if (! (caller_ptr->p_misc_flags & MF_REPLY_PEND)) {
-
         map = &priv(caller_ptr)->s_notify_pending;
-        for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
-               endpoint_t hisep;
-
-            /* Find a pending notification from the requested source. */ 
-            if (! *chunk) continue;                    /* no bits in chunk */
-            for (i=0; ! (*chunk & (1<<i)); ++i) {}     /* look up the bit */
-            src_id = (chunk - &map->chunk[0]) * BITCHUNK_BITS + i;
-            if (src_id >= NR_SYS_PROCS) break;         /* out of range */
+
+        /* Either check a specific bit in the pending notifications mask, or
+         * find the first bit set in it (if any), depending on whether the
+         * receive was called on a specific source endpoint.
+         */
+        if (src_p != ANY) {
+            src_id = nr_to_id(src_p);
+
+            found = get_sys_bit(*map, src_id);
+        } else {
+            for (src_id = 0; src_id < NR_SYS_PROCS; src_id += BITCHUNK_BITS) {
+                if (get_sys_bits(*map, src_id) != 0) {
+                    while (!get_sys_bit(*map, src_id)) src_id++;
+
+                    break;
+                }
+            }
+
+            found = (src_id < NR_SYS_PROCS);
+        }
+
+        if (found) {
+            endpoint_t hisep;
+
             src_proc_nr = id_to_nr(src_id);            /* get source proc */
 #if DEBUG_ENABLE_IPC_WARNINGS
            if(src_proc_nr == NONE) {
                printf("mini_receive: sending notify from NONE\n");
            }
 #endif
-            if (src_e!=ANY && src_p != src_proc_nr) continue;/* source not ok */
-            *chunk &= ~(1 << i);                       /* no longer pending */
+            unset_sys_bit(*map, src_id);               /* no longer pending */
 
             /* Found a suitable source, deliver the notification message. */
            hisep = proc_addr(src_proc_nr)->p_endpoint;