Allow users to get and set attributes
Currently we only allow users to get and set number of queues. The operation is always non blocking. There is no provision for non blocking operation at the moment. The queue sizes are set to MAX 256 by default. If a user changes the attributes and sets the queue size or number of messages in a queue to less than 256, it is the responsibility of the user to close any queues which were opened with a descriptor greater than the value currently set. For example, by default queue sizes are 256. If 150 queues are opened and then the user sets the number of queues to 32, all open descriptors and queues from 32 to 150 must be closed. Note that descriptor number allocation starts with zero and not one.
This commit is contained in:
parent
d84b3d9248
commit
55d341bc54
14 changed files with 188 additions and 17 deletions
|
@ -853,6 +853,8 @@ struct
|
|||
{ "MQ_CLOSE", SYS_MQ_CLOSE},
|
||||
{ "MQ_SEND", SYS_MQ_SEND},
|
||||
{ "MQ_REC", SYS_MQ_REC},
|
||||
{ "MQ_SET_ATTR", SYS_MQ_SET_ATTR},
|
||||
{ "MQ_GET_ATTR", SYS_MQ_GET_ATTR},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -266,9 +266,11 @@
|
|||
# define SYS_MQ_CLOSE (KERNEL_CALL + 59) /* sys_mq_close */
|
||||
# define SYS_MQ_SEND (KERNEL_CALL + 60) /* sys_mq_send */
|
||||
# define SYS_MQ_REC (KERNEL_CALL + 61) /* sys_mq_rec */
|
||||
# define SYS_MQ_SET_ATTR (KERNEL_CALL + 62) /* sys_mq_set_attributes */
|
||||
# define SYS_MQ_GET_ATTR (KERNEL_CALL + 63) /* sys_mq_get_attributes */
|
||||
|
||||
/* Total */
|
||||
#define NR_SYS_CALLS 62 /* number of kernel calls */
|
||||
#define NR_SYS_CALLS 64 /* number of kernel calls */
|
||||
|
||||
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
|
||||
|
||||
|
|
|
@ -1264,6 +1264,15 @@ typedef struct {
|
|||
} mess_lsys_krn_sys_mqueue_receive;
|
||||
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_receive);
|
||||
|
||||
typedef struct {
|
||||
int no_of_messages;
|
||||
int no_of_queues;
|
||||
int blocking;
|
||||
|
||||
uint8_t padding[44];
|
||||
} mess_lsys_krn_sys_mqueue_attribute;
|
||||
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_attribute);
|
||||
|
||||
typedef struct {
|
||||
void *vec_addr;
|
||||
int vec_size;
|
||||
|
@ -2285,6 +2294,7 @@ typedef struct noxfer_message {
|
|||
mess_lsys_krn_sys_mqueue_close m_lsys_krn_sys_mqueue_close;
|
||||
mess_lsys_krn_sys_mqueue_send m_lsys_krn_sys_mqueue_send;
|
||||
mess_lsys_krn_sys_mqueue_receive m_lsys_krn_sys_mqueue_receive;
|
||||
mess_lsys_krn_sys_mqueue_attribute m_lsys_krn_sys_mqueue_attribute;
|
||||
|
||||
u8_t size[56]; /* message payload may have 56 bytes at most */
|
||||
};
|
||||
|
|
|
@ -278,6 +278,8 @@ int copyfd(endpoint_t endpt, int fd, int what);
|
|||
int sys_mq_open(const char *name, int oflag);
|
||||
int sys_mq_send(int mqdes, const char *msg_ptr, pid_t dst[], unsigned int msg_prio);
|
||||
int sys_mq_receive(int mqdes, char *msg_ptr, unsigned int msg_prio);
|
||||
int sys_mq_get_attr(int *no_of_messages, int *no_of_queues, int *blocking);
|
||||
int sys_mq_set_attr(int no_of_messages, int no_of_queues, int blocking);
|
||||
int sys_mq_close(int mqdes);
|
||||
int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint);
|
||||
|
||||
|
|
|
@ -18,8 +18,11 @@ message_queue mq;
|
|||
int initialize_message_queues(void)
|
||||
{
|
||||
mq.num_queues = 0;
|
||||
number_of_queues = MAX_QUEUES;
|
||||
number_of_messages = MAX_MESSAGES;
|
||||
mq_blocking = MQ_NON_BLOCKING;
|
||||
|
||||
for (int i = 0; i < MAX_QUEUES; i++) {
|
||||
for (int i = 0; i < number_of_queues; i++) {
|
||||
mq.queue_slot_empty[i] = EMPTY;
|
||||
mq.msg[i].num_users = 0;
|
||||
mq.msg[i].num_msgs = 0;
|
||||
|
@ -31,7 +34,7 @@ int initialize_message_queues(void)
|
|||
int deinitialize_message_queues(void)
|
||||
{
|
||||
mq.num_queues = -1;
|
||||
for (int i = 0; i < MAX_QUEUES; i++) {
|
||||
for (int i = 0; i < number_of_queues; i++) {
|
||||
mq.msg[i].num_msgs = -1;
|
||||
mq.msg[i].num_users = -1;
|
||||
mq.queue_slot_empty[i] = EMPTY;
|
||||
|
@ -40,24 +43,48 @@ int deinitialize_message_queues(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mq_get_attributes(int *no_of_msgs, int *no_of_queues, int *blocking)
|
||||
{
|
||||
*no_of_msgs = number_of_messages;
|
||||
*no_of_queues = number_of_queues;
|
||||
*blocking = MQ_NON_BLOCKING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mq_set_attributes(int no_of_msgs, int no_of_queues, int blocking)
|
||||
{
|
||||
if (no_of_msgs <= MIN_LIMIT || no_of_msgs > MAX_LIMIT)
|
||||
return EINVAL;
|
||||
|
||||
if (no_of_queues <= MIN_LIMIT || no_of_queues > MAX_LIMIT)
|
||||
return EINVAL;
|
||||
|
||||
number_of_messages = no_of_msgs;
|
||||
number_of_queues = no_of_queues;
|
||||
mq_blocking = NON_BLOCKING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mq_open(const char *name, int oflag)
|
||||
{
|
||||
mqd_t mqd;
|
||||
|
||||
if (mq.num_queues >= MAX_QUEUES)
|
||||
if (mq.num_queues >= number_of_queues)
|
||||
return EMQUEUEFULL;
|
||||
|
||||
if (strlen(name) > NAME_SIZE)
|
||||
return EINVAL;
|
||||
|
||||
for (int i = 0; i < MAX_QUEUES; i++)
|
||||
for (int i = 0; i < number_of_queues; i++)
|
||||
if (mq.queue_slot_empty[i] == NOT_EMPTY)
|
||||
if (strcmp(mq.msg[i].name, name) == 0) {
|
||||
mq.msg[i].num_users++;
|
||||
return (mqd_t) i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_QUEUES; i++) {
|
||||
for (int i = 0; i < number_of_queues; i++) {
|
||||
if (mq.queue_slot_empty[i] == EMPTY) {
|
||||
mqd = i;
|
||||
mq.queue_slot_empty[i] = NOT_EMPTY;
|
||||
|
@ -65,7 +92,7 @@ int mq_open(const char *name, int oflag)
|
|||
mq.msg[i].num_users++;
|
||||
strncpy(mq.msg[i].name, name, strlen(name));
|
||||
|
||||
for (int j = 0; j < MAX_MESSAGES; j++) {
|
||||
for (int j = 0; j < number_of_messages; j++) {
|
||||
mq.msg[i].msg_slot_empty[j] = EMPTY;
|
||||
mq.msg[i].msge[j].priority = DEFAULT_PRIO;
|
||||
for (int k = 0; k < MAX_RECEIVERS; k++)
|
||||
|
@ -80,7 +107,7 @@ int mq_open(const char *name, int oflag)
|
|||
|
||||
int mq_close(mqd_t mqdes)
|
||||
{
|
||||
if (mqdes < 0 || mqdes >= MAX_QUEUES)
|
||||
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||
return EINVAL;
|
||||
|
||||
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||
|
@ -98,17 +125,17 @@ int mq_close(mqd_t mqdes)
|
|||
|
||||
int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t src, endpoint_t dst[])
|
||||
{
|
||||
if (mqdes < 0 || mqdes >= MAX_QUEUES)
|
||||
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||
return EINVAL;
|
||||
|
||||
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||
return EMSGNOTFOUND;
|
||||
|
||||
if (mq.msg[mqdes].num_msgs > MAX_MESSAGES)
|
||||
if (mq.msg[mqdes].num_msgs > number_of_messages)
|
||||
return EMSGFULL;
|
||||
|
||||
int empty_slot_pos;
|
||||
for (int i = 0; i < MAX_MESSAGES; i++)
|
||||
for (int i = 0; i < number_of_messages; i++)
|
||||
if (mq.msg[mqdes].msg_slot_empty[i] == EMPTY) {
|
||||
empty_slot_pos = i;
|
||||
break;
|
||||
|
@ -132,7 +159,7 @@ int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t
|
|||
|
||||
size_t mq_receive(mqd_t mqdes, char *msg_ptr, unsigned int msg_prio, endpoint_t dst)
|
||||
{
|
||||
if (mqdes < 0 || mqdes >= MAX_QUEUES)
|
||||
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||
return EINVAL;
|
||||
|
||||
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||
|
@ -163,7 +190,7 @@ int message_index_with_highprio(int mqdes, endpoint_t dst)
|
|||
int max_prio = -1;
|
||||
int index = -1;
|
||||
|
||||
for (int i = 0; i < MAX_MESSAGES; i++) {
|
||||
for (int i = 0; i < number_of_messages; i++) {
|
||||
if (mq.msg[mqdes].msg_slot_empty[i] == NOT_EMPTY) {
|
||||
prio = mq.msg[mqdes].msge[i].priority;
|
||||
for (int j = 0; j < MAX_RECEIVERS; j++) {
|
||||
|
@ -187,7 +214,7 @@ int clean_message_queue(mqd_t mqdes)
|
|||
{
|
||||
int flag = 1;
|
||||
|
||||
for (int i = 0; i < MAX_MESSAGES; i++) {
|
||||
for (int i = 0; i < number_of_messages; i++) {
|
||||
if (mq.msg[mqdes].msg_slot_empty[i] == NOT_EMPTY) {
|
||||
for (int j = 0; j < MAX_RECEIVERS; j++)
|
||||
if (mq.msg[mqdes].msge[i].dst[j] != EMPTY)
|
||||
|
|
|
@ -9,9 +9,16 @@
|
|||
|
||||
#include <minix/type.h>
|
||||
|
||||
/*
|
||||
* This provides a maximum limit beyond which we do not allow changing
|
||||
* number of queues or number of messages in queue.
|
||||
*/
|
||||
#define MAX_LIMIT 256
|
||||
#define MIN_LIMIT 16
|
||||
|
||||
#define MAX_RECEIVERS 4
|
||||
#define MAX_MESSAGES 16
|
||||
#define MAX_QUEUES 16
|
||||
#define MAX_MESSAGES MAX_LIMIT
|
||||
#define MAX_QUEUES MAX_LIMIT
|
||||
#define MAX_PAYLOAD 32
|
||||
#define NAME_SIZE 32
|
||||
#define DEFAULT_PRIO 0
|
||||
|
@ -19,6 +26,9 @@
|
|||
#define EMPTY -1
|
||||
#define NOT_EMPTY 1
|
||||
|
||||
#define MQ_BLOCKING 0
|
||||
#define MQ_NON_BLOCKING 1
|
||||
|
||||
typedef int mqd_t;
|
||||
|
||||
typedef struct message_entity {
|
||||
|
@ -43,12 +53,18 @@ typedef struct message_queue {
|
|||
int queue_slot_empty[MAX_QUEUES];
|
||||
} message_queue;
|
||||
|
||||
int number_of_messages;
|
||||
int number_of_queues;
|
||||
int mq_blocking;
|
||||
|
||||
int initialize_message_queues(void);
|
||||
int deinitialize_message_queues(void);
|
||||
|
||||
mqd_t mq_open(const char *name, int oflag);
|
||||
int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t src, endpoint_t dst[]);
|
||||
size_t mq_receive(mqd_t mqdes, char *msg_ptr, unsigned int msg_prio, endpoint_t dst);
|
||||
int mq_get_attributes(int *no_of_msgs, int *no_of_queues, int *blocking);
|
||||
int mq_set_attributes(int no_of_msgs, int no_of_queues, int blocking);
|
||||
int mq_close(mqd_t mqdes);
|
||||
|
||||
int clean_message_queue(mqd_t mqdes);
|
||||
|
|
|
@ -273,6 +273,8 @@ void system_init(void)
|
|||
map(SYS_MQ_CLOSE, do_mq_close); /* close a message queue */
|
||||
map(SYS_MQ_SEND, do_mq_send); /* send to a message queue */
|
||||
map(SYS_MQ_REC, do_mq_rec); /* receive from a message queue */
|
||||
map(SYS_MQ_SET_ATTR, do_mq_set_attr); /* set message queue attributes */
|
||||
map(SYS_MQ_GET_ATTR, do_mq_get_attr); /* get message queue attributes */
|
||||
|
||||
}
|
||||
/*===========================================================================*
|
||||
|
|
|
@ -226,5 +226,15 @@ int do_mq_rec(struct proc * caller, message *m_ptr);
|
|||
#define do_mq_rec NULL
|
||||
#endif
|
||||
|
||||
int do_mq_set_attr(struct proc * caller, message *m_ptr);
|
||||
#if ! USE_MQ_IPC
|
||||
#define do_mq_set_attr NULL
|
||||
#endif
|
||||
|
||||
int do_mq_get_attr(struct proc * caller, message *m_ptr);
|
||||
#if ! USE_MQ_IPC
|
||||
#define do_mq_get_attr NULL
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_H */
|
||||
|
||||
|
|
|
@ -41,7 +41,9 @@ SRCS+= \
|
|||
do_mq_open.c \
|
||||
do_mq_close.c \
|
||||
do_mq_send.c \
|
||||
do_mq_rec.c
|
||||
do_mq_rec.c \
|
||||
do_mq_set_attribute.c \
|
||||
do_mq_get_attribute.c
|
||||
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
SRCS+= \
|
||||
|
|
28
minix/kernel/system/do_mq_get_attribute.c
Normal file
28
minix/kernel/system/do_mq_get_attribute.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* The kernel call implemented in this file:
|
||||
* m_type: SYS_MQ_GET_ATTRIBUTE
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/mqueue.h"
|
||||
#include "kernel/system.h"
|
||||
#include "kernel/vm.h"
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/u64.h>
|
||||
|
||||
#if USE_MQ_IPC
|
||||
|
||||
/*===========================================================================*
|
||||
* do_mq_get_attribute *
|
||||
*===========================================================================*/
|
||||
int do_mq_get_attr(struct proc *caller, message * m_ptr)
|
||||
{
|
||||
return mq_get_attributes(&m_ptr->m_lsys_krn_sys_mqueue_attribute.no_of_messages,
|
||||
&m_ptr->m_lsys_krn_sys_mqueue_attribute.no_of_queues,
|
||||
&m_ptr->m_lsys_krn_sys_mqueue_attribute.blocking);
|
||||
}
|
||||
|
||||
#endif /* USE_MQ_IPC */
|
28
minix/kernel/system/do_mq_set_attribute.c
Normal file
28
minix/kernel/system/do_mq_set_attribute.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* The kernel call implemented in this file:
|
||||
* m_type: SYS_MQ_SET_ATTRIBUTE
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/mqueue.h"
|
||||
#include "kernel/system.h"
|
||||
#include "kernel/vm.h"
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/u64.h>
|
||||
|
||||
#if USE_MQ_IPC
|
||||
|
||||
/*===========================================================================*
|
||||
* do_mq_set_attribute *
|
||||
*===========================================================================*/
|
||||
int do_mq_set_attr(struct proc *caller, message * m_ptr)
|
||||
{
|
||||
return mq_set_attributes(m_ptr->m_lsys_krn_sys_mqueue_attribute.no_of_messages,
|
||||
m_ptr->m_lsys_krn_sys_mqueue_attribute.no_of_queues,
|
||||
m_ptr->m_lsys_krn_sys_mqueue_attribute.blocking);
|
||||
}
|
||||
|
||||
#endif /* USE_MQ_IPC */
|
|
@ -92,6 +92,8 @@ SRCS+= \
|
|||
sys_mq_close.c \
|
||||
sys_mq_send.c \
|
||||
sys_mq_receive.c \
|
||||
sys_mq_set_attr.c \
|
||||
sys_mq_get_attr.c \
|
||||
sys_endpoint_from_pid.c \
|
||||
taskcall.c \
|
||||
tickdelay.c \
|
||||
|
|
23
minix/lib/libsys/sys_mq_get_attr.c
Normal file
23
minix/lib/libsys/sys_mq_get_attr.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "syslib.h"
|
||||
#include <string.h>
|
||||
#include <machine/archtypes.h>
|
||||
#include <minix/timers.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include <minix/vm.h>
|
||||
|
||||
int sys_mq_get_attr(int *no_of_messages, int *no_of_queues, int *blocking)
|
||||
{
|
||||
message m;
|
||||
|
||||
m.m_lsys_krn_sys_mqueue_attribute.no_of_messages = 0;
|
||||
m.m_lsys_krn_sys_mqueue_attribute.no_of_queues = 0;
|
||||
m.m_lsys_krn_sys_mqueue_attribute.blocking = 0;
|
||||
|
||||
_kernel_call(SYS_MQ_GET_ATTR, &m);
|
||||
|
||||
*no_of_messages = m.m_lsys_krn_sys_mqueue_attribute.no_of_messages;
|
||||
*no_of_queues = m.m_lsys_krn_sys_mqueue_attribute.no_of_queues;
|
||||
*blocking = m.m_lsys_krn_sys_mqueue_attribute.blocking;
|
||||
|
||||
return 0;
|
||||
}
|
17
minix/lib/libsys/sys_mq_set_attr.c
Normal file
17
minix/lib/libsys/sys_mq_set_attr.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "syslib.h"
|
||||
#include <string.h>
|
||||
#include <machine/archtypes.h>
|
||||
#include <minix/timers.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include <minix/vm.h>
|
||||
|
||||
int sys_mq_set_attr(int no_of_messages, int no_of_queues, int blocking)
|
||||
{
|
||||
message m;
|
||||
|
||||
m.m_lsys_krn_sys_mqueue_attribute.no_of_messages = no_of_messages;
|
||||
m.m_lsys_krn_sys_mqueue_attribute.no_of_queues = no_of_queues;
|
||||
m.m_lsys_krn_sys_mqueue_attribute.blocking = blocking;
|
||||
|
||||
return (_kernel_call(SYS_MQ_SET_ATTR, &m));
|
||||
}
|
Loading…
Reference in a new issue