Module Name:    src
Committed By:   rmind
Date:           Sun Jul 19 02:26:49 UTC 2009

Modified Files:
        src/sys/kern: sys_mqueue.c
        src/sys/sys: mqueue.h

Log Message:
Fix previous, so that it actually works, correctly.


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/kern/sys_mqueue.c
cvs rdiff -u -r1.8 -r1.9 src/sys/sys/mqueue.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sys_mqueue.c
diff -u src/sys/kern/sys_mqueue.c:1.22 src/sys/kern/sys_mqueue.c:1.23
--- src/sys/kern/sys_mqueue.c:1.22	Mon Jul 13 02:37:12 2009
+++ src/sys/kern/sys_mqueue.c	Sun Jul 19 02:26:49 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_mqueue.c,v 1.22 2009/07/13 02:37:12 rmind Exp $	*/
+/*	$NetBSD: sys_mqueue.c,v 1.23 2009/07/19 02:26:49 rmind Exp $	*/
 
 /*
  * Copyright (c) 2007-2009 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.22 2009/07/13 02:37:12 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.23 2009/07/19 02:26:49 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -136,7 +136,8 @@
 	size_t msz;
 	u_int i;
 
-	for (i = 0; i < (MQ_PQSIZE + 1); i++) {
+	/* Note MQ_PQSIZE + 1. */
+	for (i = 0; i <= MQ_PQSIZE; i++) {
 		while ((msg = TAILQ_FIRST(&mq->mq_head[i])) != NULL) {
 			TAILQ_REMOVE(&mq->mq_head[i], msg, msg_queue);
 			msz = sizeof(struct mq_msg) + msg->msg_len;
@@ -199,20 +200,20 @@
 
 /*
  * mqueue_linear_insert: perform linear insert according to the message
- * priority into the reserved queue (note MQ_PQSIZE + 1).  Reserved queue
- * is a sorted list used only when mq_prio_max is increased via sysctl.
+ * priority into the reserved queue (MQ_PQRESQ).  Reserved queue is a
+ * sorted list used only when mq_prio_max is increased via sysctl.
  */
 static inline void
 mqueue_linear_insert(struct mqueue *mq, struct mq_msg *msg)
 {
 	struct mq_msg *mit;
 
-	TAILQ_FOREACH(mit, &mq->mq_head[MQ_PQSIZE], msg_queue) {
+	TAILQ_FOREACH(mit, &mq->mq_head[MQ_PQRESQ], msg_queue) {
 		if (msg->msg_prio > mit->msg_prio)
 			break;
 	}
 	if (mit == NULL) {
-		TAILQ_INSERT_TAIL(&mq->mq_head[MQ_PQSIZE], msg, msg_queue);
+		TAILQ_INSERT_TAIL(&mq->mq_head[MQ_PQRESQ], msg, msg_queue);
 	} else {
 		TAILQ_INSERT_BEFORE(mit, msg, msg_queue);
 	}
@@ -543,7 +544,7 @@
 	struct mqueue *mq;
 	struct mq_msg *msg = NULL;
 	struct mq_attr *mqattr;
-	u_int prio;
+	u_int idx;
 	int error;
 
 	/* Get the message queue */
@@ -588,22 +589,24 @@
 		}
 	}
 
-	/* Find the highest priority message */
-	prio = ffs(mq->mq_bitmap);
-	if (__predict_false(prio == 0)) {
-		/* Must be in reserved queue then */
-		prio = MQ_PQSIZE;
-	}
-
-	/* Remove it from the queue */
-	msg = TAILQ_FIRST(&mq->mq_head[prio]);
-	KASSERT(msg != NULL);
-	TAILQ_REMOVE(&mq->mq_head[prio], msg, msg_queue);
-
-	/* Unmark the bit, if last message */
-	if (__predict_true(prio != MQ_PQSIZE) &&
-	    TAILQ_EMPTY(&mq->mq_head[prio])) {
-		mq->mq_bitmap &= ~(MQ_PQMSB >> prio);
+	/*
+	 * Find the highest priority message, and remove it from the queue.
+	 * At first, reserved queue is checked, bitmap is next.
+	 */
+	msg = TAILQ_FIRST(&mq->mq_head[MQ_PQRESQ]);
+	if (__predict_true(msg == NULL)) {
+		idx = ffs(mq->mq_bitmap);
+		msg = TAILQ_FIRST(&mq->mq_head[idx]);
+		KASSERT(msg != NULL);
+	} else {
+		idx = MQ_PQRESQ;
+	}
+	TAILQ_REMOVE(&mq->mq_head[idx], msg, msg_queue);
+
+	/* Unmark the bit, if last message. */
+	if (__predict_true(idx) && TAILQ_EMPTY(&mq->mq_head[idx])) {
+		KASSERT((MQ_PQSIZE - idx) == msg->msg_prio);
+		mq->mq_bitmap &= ~(1 << --idx);
 	}
 
 	/* Decrement the counter and signal waiter, if any */
@@ -767,10 +770,16 @@
 	}
 	KASSERT(mqattr->mq_curmsgs < mqattr->mq_maxmsg);
 
-	/* Insert message into the queue, according to the priority */
+	/*
+	 * Insert message into the queue, according to the priority.
+	 * Note the difference between index and priority.
+	 */
 	if (__predict_true(msg_prio < MQ_PQSIZE)) {
-		TAILQ_INSERT_TAIL(&mq->mq_head[msg_prio], msg, msg_queue);
-		mq->mq_bitmap |= (MQ_PQMSB >> msg_prio);
+		u_int idx = MQ_PQSIZE - msg_prio;
+
+		KASSERT(idx != MQ_PQRESQ);
+		TAILQ_INSERT_TAIL(&mq->mq_head[idx], msg, msg_queue);
+		mq->mq_bitmap |= (1 << --idx);
 	} else {
 		mqueue_linear_insert(mq, msg);
 	}

Index: src/sys/sys/mqueue.h
diff -u src/sys/sys/mqueue.h:1.8 src/sys/sys/mqueue.h:1.9
--- src/sys/sys/mqueue.h:1.8	Mon Jul 13 02:37:13 2009
+++ src/sys/sys/mqueue.h	Sun Jul 19 02:26:49 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: mqueue.h,v 1.8 2009/07/13 02:37:13 rmind Exp $	*/
+/*	$NetBSD: mqueue.h,v 1.9 2009/07/19 02:26:49 rmind Exp $	*/
 
 /*
  * Copyright (c) 2007-2009 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -67,9 +67,9 @@
 /* Default size of the message */
 #define	MQ_DEF_MSGSIZE		1024
 
-/* Size/bits and MSB for the queue array */
+/* Size/bits and index of reserved queue */
 #define	MQ_PQSIZE		32
-#define	MQ_PQMSB		0x80000000U
+#define	MQ_PQRESQ		0
 
 /* Structure of the message queue */
 struct mqueue {
@@ -89,7 +89,7 @@
 	gid_t			mq_egid;
 	/* Reference counter, queue array and bitmap */
 	u_int			mq_refcnt;
-	TAILQ_HEAD(, mq_msg)	mq_head[MQ_PQSIZE + 1];
+	TAILQ_HEAD(, mq_msg)	mq_head[1 + MQ_PQSIZE];
 	uint32_t		mq_bitmap;
 	/* Entry of the global list */
 	LIST_ENTRY(mqueue)	mq_list;

Reply via email to