diff --git a/minix/commands/service/parse.c b/minix/commands/service/parse.c index df7d925bb..158930911 100644 --- a/minix/commands/service/parse.c +++ b/minix/commands/service/parse.c @@ -855,6 +855,7 @@ struct { "MQ_REC", SYS_MQ_REC}, { "MQ_SET_ATTR", SYS_MQ_SET_ATTR}, { "MQ_GET_ATTR", SYS_MQ_GET_ATTR}, + { "MQ_REQ_NOTIFY", SYS_MQ_REQ_NOTIFY}, { NULL, 0 } }; diff --git a/minix/include/minix/com.h b/minix/include/minix/com.h index 2be5b8876..3162c1693 100644 --- a/minix/include/minix/com.h +++ b/minix/include/minix/com.h @@ -268,9 +268,10 @@ # 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 */ +# define SYS_MQ_REQ_NOTIFY (KERNEL_CALL + 64) /* sys_mq_request_notify */ /* Total */ -#define NR_SYS_CALLS 64 /* number of kernel calls */ +#define NR_SYS_CALLS 65 /* 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 7501b57db..134cf4e46 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -1273,6 +1273,13 @@ typedef struct { } mess_lsys_krn_sys_mqueue_attribute; _ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_attribute); +typedef struct { + int notify_on_off; + + uint8_t padding[52]; +} mess_lsys_krn_sys_mqueue_notify; +_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_notify); + typedef struct { void *vec_addr; int vec_size; @@ -2295,6 +2302,7 @@ typedef struct noxfer_message { 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; + mess_lsys_krn_sys_mqueue_notify m_lsys_krn_sys_mqueue_notify; 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 49d4784dc..a35bd6263 100644 --- a/minix/include/minix/syslib.h +++ b/minix/include/minix/syslib.h @@ -281,6 +281,7 @@ 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_mq_request_notify(int notify_on_off); int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint); #endif /* _SYSLIB_H */ diff --git a/minix/kernel/mqueue.c b/minix/kernel/mqueue.c index 9854a242f..4b8e050d2 100644 --- a/minix/kernel/mqueue.c +++ b/minix/kernel/mqueue.c @@ -21,6 +21,7 @@ int initialize_message_queues(void) number_of_queues = MAX_QUEUES; number_of_messages = MAX_MESSAGES; mq_blocking = MQ_NON_BLOCKING; + notify = NOTIFY_OFF; for (int i = 0; i < number_of_queues; i++) { mq.queue_slot_empty[i] = EMPTY; @@ -154,6 +155,21 @@ int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t mq.msg[mqdes].msge[empty_slot_pos].timestamp = get_monotonic(); mq.msg[mqdes].num_msgs++; + if (notify) { + proc_nr_t proc_nr; + + for (int i = 0; i < MAX_RECEIVERS; i++) { + if (dst[i] != -1) { + /* Translate endpoint to process number */ + if (!isokendpt(dst[i], &proc_nr)) + goto exit; + else + cause_sig(proc_nr, SIGALRM); + } + } + } + + exit: return 0; } @@ -229,3 +245,13 @@ int clean_message_queue(mqd_t mqdes) return 0; } + +int mq_notify(int notify_on_off) +{ + if (notify_on_off) + notify = NOTIFY_ON; + else + notify = NOTIFY_OFF; + + return 0; +} diff --git a/minix/kernel/mqueue.h b/minix/kernel/mqueue.h index 226869031..56bd79ece 100644 --- a/minix/kernel/mqueue.h +++ b/minix/kernel/mqueue.h @@ -29,6 +29,9 @@ #define MQ_BLOCKING 0 #define MQ_NON_BLOCKING 1 +#define NOTIFY_ON 1 +#define NOTIFY_OFF 0 + typedef int mqd_t; typedef struct message_entity { @@ -56,6 +59,7 @@ typedef struct message_queue { int number_of_messages; int number_of_queues; int mq_blocking; +int notify; int initialize_message_queues(void); int deinitialize_message_queues(void); @@ -66,6 +70,7 @@ size_t mq_receive(mqd_t mqdes, char *msg_ptr, unsigned int msg_prio, endpoint_t 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 mq_notify(int notify_on_off); int clean_message_queue(mqd_t mqdes); int message_index_with_highprio(mqd_t mqdes, endpoint_t dst); diff --git a/minix/kernel/system.c b/minix/kernel/system.c index 166073790..0b3e7a1c5 100644 --- a/minix/kernel/system.c +++ b/minix/kernel/system.c @@ -275,6 +275,7 @@ void system_init(void) 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 */ + map(SYS_MQ_REQ_NOTIFY, do_mq_request_notify); /* request notification for receive */ } /*===========================================================================* diff --git a/minix/kernel/system.h b/minix/kernel/system.h index 4e39fdf48..a551ae244 100644 --- a/minix/kernel/system.h +++ b/minix/kernel/system.h @@ -236,5 +236,10 @@ int do_mq_get_attr(struct proc * caller, message *m_ptr); #define do_mq_get_attr NULL #endif +int do_mq_request_notify(struct proc * caller, message *m_ptr); +#if ! USE_MQ_IPC +#define do_mq_request_notify NULL +#endif + #endif /* SYSTEM_H */ diff --git a/minix/kernel/system/Makefile.inc b/minix/kernel/system/Makefile.inc index 95a94a4ba..2fc61a6f3 100644 --- a/minix/kernel/system/Makefile.inc +++ b/minix/kernel/system/Makefile.inc @@ -43,7 +43,8 @@ SRCS+= \ do_mq_send.c \ do_mq_rec.c \ do_mq_set_attribute.c \ - do_mq_get_attribute.c + do_mq_get_attribute.c \ + do_mq_request_notify.c .if ${MACHINE_ARCH} == "i386" SRCS+= \ diff --git a/minix/kernel/system/do_mq_request_notify.c b/minix/kernel/system/do_mq_request_notify.c new file mode 100644 index 000000000..06139272d --- /dev/null +++ b/minix/kernel/system/do_mq_request_notify.c @@ -0,0 +1,26 @@ +/* The kernel call implemented in this file: + * m_type: SYS_MQ_REQUEST_NOTIFY + * + */ + +#include "kernel/mqueue.h" +#include "kernel/system.h" +#include "kernel/vm.h" +#include +#include +#include + +#include +#include + +#if USE_MQ_IPC + +/*===========================================================================* + * do_mq_request_notify * + *===========================================================================*/ +int do_mq_request_notify(struct proc * caller, message * m_ptr) +{ + return mq_notify(m_ptr->m_lsys_krn_sys_mqueue_notify.notify_on_off); +} + +#endif /* USE_MQ_IPC */ diff --git a/minix/lib/libsys/Makefile b/minix/lib/libsys/Makefile index 18c470d8c..d5f84d002 100644 --- a/minix/lib/libsys/Makefile +++ b/minix/lib/libsys/Makefile @@ -94,6 +94,7 @@ SRCS+= \ sys_mq_receive.c \ sys_mq_set_attr.c \ sys_mq_get_attr.c \ + sys_mq_request_notify.c \ sys_endpoint_from_pid.c \ taskcall.c \ tickdelay.c \ diff --git a/minix/lib/libsys/sys_mq_request_notify.c b/minix/lib/libsys/sys_mq_request_notify.c new file mode 100644 index 000000000..719984bfa --- /dev/null +++ b/minix/lib/libsys/sys_mq_request_notify.c @@ -0,0 +1,15 @@ +#include "syslib.h" +#include +#include +#include +#include +#include + +int sys_mq_request_notify(int notify_on_off) +{ + message m; + + m.m_lsys_krn_sys_mqueue_notify.notify_on_off = notify_on_off; + + return (_kernel_call(SYS_MQ_REQ_NOTIFY, &m)); +}