etc/services - sync with NetBSD-8
[minix.git] / minix / lib / libddekit / src / msg_queue.c
bloba68e6cf10f699def2a0df2c56f264b830de070b3
1 #include "common.h"
3 #include <ddekit/memory.h>
4 #include <ddekit/minix/msg_queue.h>
5 #include <ddekit/panic.h>
6 #include <ddekit/semaphore.h>
8 #define MESSAGE_QUEUE_SIZE 16
10 #ifdef DDEBUG_LEVEL_MSG_Q
11 #undef DDEBUG
12 #define DDEBUG DDEBUG_LEVEL_MSG_Q
13 #endif
15 #include "debug.h"
17 struct ddekit_minix_msg_q {
19 unsigned from, to;
21 message messages[MESSAGE_QUEUE_SIZE];
22 int ipc_status[MESSAGE_QUEUE_SIZE];
23 ddekit_sem_t *msg_w_sem, *msg_r_sem;
24 int msg_r_pos, msg_w_pos;
26 struct ddekit_minix_msg_q *next;
29 static struct ddekit_minix_msg_q * _list = NULL;
30 static void _ddekit_minix_queue_msg
31 (struct ddekit_minix_msg_q *mq, message *m, int ipc_status);
33 /*****************************************************************************
34 * ddekit_minix_create_msg_q *
35 ****************************************************************************/
36 struct ddekit_minix_msg_q *
37 ddekit_minix_create_msg_q(unsigned from, unsigned to)
39 struct ddekit_minix_msg_q *mq = (struct ddekit_minix_msg_q *)
40 ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q));
42 mq->from = from;
43 mq->to = to;
44 mq->msg_w_pos = 0;
45 mq->msg_r_pos = 0;
47 mq->msg_r_sem = ddekit_sem_init(0);
48 mq->msg_w_sem = ddekit_sem_init(MESSAGE_QUEUE_SIZE);
50 /* TODO: check for overlapping message ranges */
51 mq->next = _list;
52 _list = mq;
54 DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from , to);
56 return mq;
59 /*****************************************************************************
60 * ddekit_minix_deregister_msg_q *
61 ****************************************************************************/
62 void ddekit_minix_deregister_msg_q(struct ddekit_minix_msg_q *mq)
64 struct ddekit_minix_msg_q *prev =_list, *it;
66 for (it = _list->next; it != NULL ; it = it->next) {
67 if (it == mq) {
68 prev->next = it->next;
69 break;
71 prev=it;
74 ddekit_sem_deinit(mq->msg_r_sem);
75 ddekit_sem_deinit(mq->msg_w_sem);
77 ddekit_simple_free(mq);
79 DDEBUG_MSG_VERBOSE("destroyed msg_q from \n");
82 /*****************************************************************************
83 * _ddekit_minix_queue_msg *
84 ****************************************************************************/
85 static void
86 _ddekit_minix_queue_msg (
87 struct ddekit_minix_msg_q *mq,
88 message *m,
89 int ipc_status
92 int full;
93 full = ddekit_sem_down_try(mq->msg_w_sem);
95 if (full) {
96 /* Our message queue is full... */
97 int result;
98 DDEBUG_MSG_WARN("Receive queue is full. Dropping request.\n");
100 /* XXX should reply to the sender with EIO or so, but for that
101 * we would need to look at the request and find a suitable
102 * reply code..
104 } else {
105 /* queue the message */
106 memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
107 mq->ipc_status[mq->msg_w_pos] = ipc_status;
108 if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
109 mq->msg_w_pos = 0;
111 DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
112 m->m_type);
113 ddekit_sem_up(mq->msg_r_sem);
117 /*****************************************************************************
118 * ddekit_minix_queue_msg *
119 ****************************************************************************/
120 void ddekit_minix_queue_msg(message *m, int ipc_status)
122 struct ddekit_minix_msg_q *it, *mq = NULL;
124 for (it = _list; it !=NULL ; it = it->next) {
125 if (m->m_type >= it->from && m->m_type <= it->to) {
126 mq = it;
127 break;
130 if (mq == NULL) {
131 DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
132 return;
134 _ddekit_minix_queue_msg(mq, m, ipc_status);
137 /*****************************************************************************
138 * ddekit_minix_rcv *
139 ****************************************************************************/
140 void ddekit_minix_rcv (
141 struct ddekit_minix_msg_q *mq,
142 message *m,
143 int *ipc_status
146 DDEBUG_MSG_VERBOSE("waiting for message");
148 ddekit_sem_down(mq->msg_r_sem);
150 memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
151 *ipc_status = mq->ipc_status[mq->msg_r_pos];
152 if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
153 mq->msg_r_pos = 0;
156 DDEBUG_MSG_VERBOSE("unqueing message");
158 ddekit_sem_up(mq->msg_w_sem);