1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
#include "common.h"
#include <ddekit/memory.h>
#include <ddekit/minix/msg_queue.h>
#include <ddekit/panic.h>
#include <ddekit/semaphore.h>
#define MESSAGE_QUEUE_SIZE 16
#ifdef DDEBUG_LEVEL_MSG_Q
#undef DDEBUG
#define DDEBUG DDEBUG_LEVEL_MSG_Q
#endif
#include "debug.h"
struct ddekit_minix_msg_q {
unsigned from, to;
message messages[MESSAGE_QUEUE_SIZE];
int ipc_status[MESSAGE_QUEUE_SIZE];
ddekit_sem_t *msg_w_sem, *msg_r_sem;
int msg_r_pos, msg_w_pos;
struct ddekit_minix_msg_q *next;
};
static struct ddekit_minix_msg_q * _list = NULL;
static void _ddekit_minix_queue_msg
(struct ddekit_minix_msg_q *mq, message *m, int ipc_status);
/*****************************************************************************
* ddekit_minix_create_msg_q *
****************************************************************************/
struct ddekit_minix_msg_q *
ddekit_minix_create_msg_q(unsigned from, unsigned to)
{
struct ddekit_minix_msg_q *mq = (struct ddekit_minix_msg_q *)
ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q));
mq->from = from;
mq->to = to;
mq->msg_w_pos = 0;
mq->msg_r_pos = 0;
mq->msg_r_sem = ddekit_sem_init(0);
mq->msg_w_sem = ddekit_sem_init(MESSAGE_QUEUE_SIZE);
/* TODO: check for overlapping message ranges */
mq->next = _list;
_list = mq;
DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from , to);
return mq;
}
/*****************************************************************************
* ddekit_minix_deregister_msg_q *
****************************************************************************/
void ddekit_minix_deregister_msg_q(struct ddekit_minix_msg_q *mq)
{
struct ddekit_minix_msg_q *prev =_list, *it;
for (it = _list->next; it != NULL ; it = it->next) {
if (it == mq) {
prev->next = it->next;
break;
}
prev=it;
}
ddekit_sem_deinit(mq->msg_r_sem);
ddekit_sem_deinit(mq->msg_w_sem);
ddekit_simple_free(mq);
DDEBUG_MSG_VERBOSE("destroyed msg_q from \n");
}
/*****************************************************************************
* _ddekit_minix_queue_msg *
****************************************************************************/
static void
_ddekit_minix_queue_msg (
struct ddekit_minix_msg_q *mq,
message *m,
int ipc_status
)
{
int full;
full = ddekit_sem_down_try(mq->msg_w_sem);
if (full) {
/* Our message queue is full... */
int result;
DDEBUG_MSG_WARN("Receive queue is full. Dropping request.\n");
/* XXX should reply to the sender with EIO or so, but for that
* we would need to look at the request and find a suitable
* reply code..
*/
} else {
/* queue the message */
memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
mq->ipc_status[mq->msg_w_pos] = ipc_status;
if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
mq->msg_w_pos = 0;
}
DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
m->m_type);
ddekit_sem_up(mq->msg_r_sem);
}
}
/*****************************************************************************
* ddekit_minix_queue_msg *
****************************************************************************/
void ddekit_minix_queue_msg(message *m, int ipc_status)
{
struct ddekit_minix_msg_q *it, *mq = NULL;
for (it = _list; it !=NULL ; it = it->next) {
if (m->m_type >= it->from && m->m_type <= it->to) {
mq = it;
break;
}
}
if (mq == NULL) {
DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
return;
}
_ddekit_minix_queue_msg(mq, m, ipc_status);
}
/*****************************************************************************
* ddekit_minix_rcv *
****************************************************************************/
void ddekit_minix_rcv (
struct ddekit_minix_msg_q *mq,
message *m,
int *ipc_status
)
{
DDEBUG_MSG_VERBOSE("waiting for message");
ddekit_sem_down(mq->msg_r_sem);
memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
*ipc_status = mq->ipc_status[mq->msg_r_pos];
if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
mq->msg_r_pos = 0;
}
DDEBUG_MSG_VERBOSE("unqueing message");
ddekit_sem_up(mq->msg_w_sem);
}
|