From 55d341bc54075c17d74f1b3e8b55106c03a0843d Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Tue, 22 Mar 2016 15:57:53 +0530 Subject: [PATCH] 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. --- minix/commands/service/parse.c | 2 + minix/include/minix/com.h | 4 +- minix/include/minix/ipc.h | 10 +++++ minix/include/minix/syslib.h | 2 + minix/kernel/mqueue.c | 53 +++++++++++++++++------ minix/kernel/mqueue.h | 20 ++++++++- minix/kernel/system.c | 2 + minix/kernel/system.h | 10 +++++ minix/kernel/system/Makefile.inc | 4 +- minix/kernel/system/do_mq_get_attribute.c | 28 ++++++++++++ minix/kernel/system/do_mq_set_attribute.c | 28 ++++++++++++ minix/lib/libsys/Makefile | 2 + minix/lib/libsys/sys_mq_get_attr.c | 23 ++++++++++ minix/lib/libsys/sys_mq_set_attr.c | 17 ++++++++ 14 files changed, 188 insertions(+), 17 deletions(-) create mode 100644 minix/kernel/system/do_mq_get_attribute.c create mode 100644 minix/kernel/system/do_mq_set_attribute.c create mode 100644 minix/lib/libsys/sys_mq_get_attr.c create mode 100644 minix/lib/libsys/sys_mq_set_attr.c diff --git a/minix/commands/service/parse.c b/minix/commands/service/parse.c index f4eeab39f..df7d925bb 100644 --- a/minix/commands/service/parse.c +++ b/minix/commands/service/parse.c @@ -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 } }; diff --git a/minix/include/minix/com.h b/minix/include/minix/com.h index 3ea2ba3b5..2be5b8876 100644 --- a/minix/include/minix/com.h +++ b/minix/include/minix/com.h @@ -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) diff --git a/minix/include/minix/ipc.h b/minix/include/minix/ipc.h index 79251953d..7501b57db 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -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 */ }; diff --git a/minix/include/minix/syslib.h b/minix/include/minix/syslib.h index 5f6ec6c3d..49d4784dc 100644 --- a/minix/include/minix/syslib.h +++ b/minix/include/minix/syslib.h @@ -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); diff --git a/minix/kernel/mqueue.c b/minix/kernel/mqueue.c index be84f5b99..9854a242f 100644 --- a/minix/kernel/mqueue.c +++ b/minix/kernel/mqueue.c @@ -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) diff --git a/minix/kernel/mqueue.h b/minix/kernel/mqueue.h index 180e7dc79..226869031 100644 --- a/minix/kernel/mqueue.h +++ b/minix/kernel/mqueue.h @@ -9,9 +9,16 @@ #include +/* + * 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); diff --git a/minix/kernel/system.c b/minix/kernel/system.c index 95c79e341..166073790 100644 --- a/minix/kernel/system.c +++ b/minix/kernel/system.c @@ -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 */ } /*===========================================================================* diff --git a/minix/kernel/system.h b/minix/kernel/system.h index 31224d897..4e39fdf48 100644 --- a/minix/kernel/system.h +++ b/minix/kernel/system.h @@ -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 */ diff --git a/minix/kernel/system/Makefile.inc b/minix/kernel/system/Makefile.inc index 8a31c94d2..95a94a4ba 100644 --- a/minix/kernel/system/Makefile.inc +++ b/minix/kernel/system/Makefile.inc @@ -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+= \ diff --git a/minix/kernel/system/do_mq_get_attribute.c b/minix/kernel/system/do_mq_get_attribute.c new file mode 100644 index 000000000..5df84f00d --- /dev/null +++ b/minix/kernel/system/do_mq_get_attribute.c @@ -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 +#include +#include + +#include +#include + +#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 */ diff --git a/minix/kernel/system/do_mq_set_attribute.c b/minix/kernel/system/do_mq_set_attribute.c new file mode 100644 index 000000000..8671dac86 --- /dev/null +++ b/minix/kernel/system/do_mq_set_attribute.c @@ -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 +#include +#include + +#include +#include + +#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 */ diff --git a/minix/lib/libsys/Makefile b/minix/lib/libsys/Makefile index b5e9fab9f..18c470d8c 100644 --- a/minix/lib/libsys/Makefile +++ b/minix/lib/libsys/Makefile @@ -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 \ diff --git a/minix/lib/libsys/sys_mq_get_attr.c b/minix/lib/libsys/sys_mq_get_attr.c new file mode 100644 index 000000000..c80d2eb6a --- /dev/null +++ b/minix/lib/libsys/sys_mq_get_attr.c @@ -0,0 +1,23 @@ +#include "syslib.h" +#include +#include +#include +#include +#include + +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; +} diff --git a/minix/lib/libsys/sys_mq_set_attr.c b/minix/lib/libsys/sys_mq_set_attr.c new file mode 100644 index 000000000..d621751e5 --- /dev/null +++ b/minix/lib/libsys/sys_mq_set_attr.c @@ -0,0 +1,17 @@ +#include "syslib.h" +#include +#include +#include +#include +#include + +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)); +}