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;