pkgin_all: script to auto-install all packages
[minix.git] / lib / libddekit / src / msg_queue.c
blob3ea82708b348322bc9f4b517d558461542d48691
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... inform the sender. */
97 int result;
98 DDEBUG_MSG_WARN("Receive queue is full. Ommiting ingoing msg.\n");
100 m->m_type = TASK_REPLY;
101 m->REP_STATUS = EAGAIN;
102 result = asynsend(m->m_source, m);
104 if (result != 0) {
105 ddekit_panic("unable to send reply to %d: %d\n",
106 m->m_source, result);
109 } else {
110 /* queue the message */
111 memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
112 mq->ipc_status[mq->msg_w_pos] = ipc_status;
113 if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
114 mq->msg_w_pos = 0;
116 DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
117 m->m_type);
118 ddekit_sem_up(mq->msg_r_sem);
122 /*****************************************************************************
123 * ddekit_minix_queue_msg *
124 ****************************************************************************/
125 void ddekit_minix_queue_msg(message *m, int ipc_status)
127 struct ddekit_minix_msg_q *it, *mq = NULL;
129 for (it = _list; it !=NULL ; it = it->next) {
130 if (m->m_type >= it->from && m->m_type <= it->to) {
131 mq = it;
132 break;
135 if (mq == NULL) {
136 DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
137 return;
139 _ddekit_minix_queue_msg(mq, m, ipc_status);
142 /*****************************************************************************
143 * ddekit_minix_rcv *
144 ****************************************************************************/
145 void ddekit_minix_rcv (
146 struct ddekit_minix_msg_q *mq,
147 message *m,
148 int *ipc_status
151 DDEBUG_MSG_VERBOSE("waiting for message");
153 ddekit_sem_down(mq->msg_r_sem);
155 memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
156 *ipc_status = mq->ipc_status[mq->msg_r_pos];
157 if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
158 mq->msg_r_pos = 0;
161 DDEBUG_MSG_VERBOSE("unqueing message");
163 ddekit_sem_up(mq->msg_w_sem);