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
12 #define DDEBUG DDEBUG_LEVEL_MSG_Q
17 struct ddekit_minix_msg_q
{
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
));
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 */
54 DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from
, to
);
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
) {
68 prev
->next
= it
->next
;
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 ****************************************************************************/
86 _ddekit_minix_queue_msg (
87 struct ddekit_minix_msg_q
*mq
,
93 full
= ddekit_sem_down_try(mq
->msg_w_sem
);
96 /* Our message queue is full... inform the sender. */
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
);
105 ddekit_panic("unable to send reply to %d: %d\n",
106 m
->m_source
, result
);
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
) {
116 DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
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
) {
136 DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m
->m_type
);
139 _ddekit_minix_queue_msg(mq
, m
, ipc_status
);
142 /*****************************************************************************
144 ****************************************************************************/
145 void ddekit_minix_rcv (
146 struct ddekit_minix_msg_q
*mq
,
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
) {
161 DDEBUG_MSG_VERBOSE("unqueing message");
163 ddekit_sem_up(mq
->msg_w_sem
);