worldstone: add -s for statistical profiling
[minix.git] / lib / libblockdriver / mq.c
blobaf2fcc5ecf14c99f648fb142ccda117f3f3d638c
1 /* This file contains a simple message queue implementation to support both
2 * the singlethread and the multithreaded driver implementation.
4 * Changes:
5 * Oct 27, 2011 rewritten to use sys/queue.h (D.C. van Moolenbroek)
6 * Aug 27, 2011 integrated into libblockdriver (A. Welzel)
7 */
9 #include <minix/blockdriver_mt.h>
10 #include <sys/queue.h>
11 #include <assert.h>
13 #include "const.h"
14 #include "mq.h"
16 #define MQ_SIZE 128
18 struct mq_cell {
19 message mess;
20 int ipc_status;
21 STAILQ_ENTRY(mq_cell) next;
24 static struct mq_cell pool[MQ_SIZE];
25 static STAILQ_HEAD(queue, mq_cell) queue[MAX_DEVICES];
26 static STAILQ_HEAD(free_list, mq_cell) free_list;
28 /*===========================================================================*
29 * mq_init *
30 *===========================================================================*/
31 void mq_init(void)
33 /* Initialize the message queues and message cells.
35 int i;
37 STAILQ_INIT(&free_list);
39 for (i = 0; i < MAX_DEVICES; i++)
40 STAILQ_INIT(&queue[i]);
42 for (i = 0; i < MQ_SIZE; i++)
43 STAILQ_INSERT_HEAD(&free_list, &pool[i], next);
46 /*===========================================================================*
47 * mq_enqueue *
48 *===========================================================================*/
49 int mq_enqueue(device_id_t device_id, const message *mess,
50 int ipc_status)
52 /* Add a message, including its IPC status, to the message queue of a device.
53 * Return TRUE iff the message was added successfully.
55 struct mq_cell *cell;
57 assert(device_id >= 0 && device_id < MAX_DEVICES);
59 if (STAILQ_EMPTY(&free_list))
60 return FALSE;
62 cell = STAILQ_FIRST(&free_list);
63 STAILQ_REMOVE_HEAD(&free_list, next);
65 cell->mess = *mess;
66 cell->ipc_status = ipc_status;
68 STAILQ_INSERT_TAIL(&queue[device_id], cell, next);
70 return TRUE;
73 /*===========================================================================*
74 * mq_dequeue *
75 *===========================================================================*/
76 int mq_dequeue(device_id_t device_id, message *mess, int *ipc_status)
78 /* Return and remove a message, including its IPC status, from the message
79 * queue of a thread. Return TRUE iff a message was available.
81 struct mq_cell *cell;
83 assert(device_id >= 0 && device_id < MAX_DEVICES);
85 if (STAILQ_EMPTY(&queue[device_id]))
86 return FALSE;
88 cell = STAILQ_FIRST(&queue[device_id]);
89 STAILQ_REMOVE_HEAD(&queue[device_id], next);
91 *mess = cell->mess;
92 *ipc_status = cell->ipc_status;
94 STAILQ_INSERT_HEAD(&free_list, cell, next);
96 return TRUE;