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)); +}