Compare commits
12 commits
Project0
...
msgqueues-
Author | SHA1 | Date | |
---|---|---|---|
368b5fc155 | |||
8501cb7ed8 | |||
55d341bc54 | |||
d84b3d9248 | |||
0cc443d3c2 | |||
fe71ea4bc1 | |||
d2fb3a4b8a | |||
58ce9ca12b | |||
df5a0e339c | |||
63062e7e15 | |||
6f36b466f3 | |||
06b223febe |
30 changed files with 934 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
||||||
clear=1
|
clear=1
|
||||||
timeout=5
|
timeout=5
|
||||||
default=2
|
default=2
|
||||||
menu=Start MINIX 3:load_mods /boot/minix_default/mod*;multiboot /boot/minix_default/kernel rootdevname=$rootdevname $args
|
menu=Start MINIX 3 virtio:load_mods /boot/minix_default/mod*;multiboot /boot/minix_default/kernel rootdevname=$rootdevname $args virtio_blk=yes
|
||||||
menu=Start latest MINIX 3:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname $args
|
menu=Start latest MINIX 3:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname $args
|
||||||
menu=Start latest MINIX 3 in single user mode:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname bootopts=-s $args
|
menu=Start latest MINIX 3 in single user mode:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname bootopts=-s $args
|
||||||
menu=Edit menu option:edit
|
menu=Edit menu option:edit
|
||||||
|
|
|
@ -849,6 +849,13 @@ struct
|
||||||
{ "VMCTL", SYS_VMCTL },
|
{ "VMCTL", SYS_VMCTL },
|
||||||
{ "MEMSET", SYS_MEMSET },
|
{ "MEMSET", SYS_MEMSET },
|
||||||
{ "PADCONF", SYS_PADCONF },
|
{ "PADCONF", SYS_PADCONF },
|
||||||
|
{ "MQ_OPEN", SYS_MQ_OPEN},
|
||||||
|
{ "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},
|
||||||
|
{ "MQ_REQ_NOTIFY", SYS_MQ_REQ_NOTIFY},
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -262,8 +262,16 @@
|
||||||
|
|
||||||
# define SYS_PADCONF (KERNEL_CALL + 57) /* sys_padconf() */
|
# define SYS_PADCONF (KERNEL_CALL + 57) /* sys_padconf() */
|
||||||
|
|
||||||
|
# define SYS_MQ_OPEN (KERNEL_CALL + 58) /* sys_mq_open */
|
||||||
|
# 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 */
|
||||||
|
# define SYS_MQ_REQ_NOTIFY (KERNEL_CALL + 64) /* sys_mq_request_notify */
|
||||||
|
|
||||||
/* Total */
|
/* Total */
|
||||||
#define NR_SYS_CALLS 58 /* number of kernel calls */
|
#define NR_SYS_CALLS 65 /* number of kernel calls */
|
||||||
|
|
||||||
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
|
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
|
||||||
|
|
||||||
|
|
|
@ -1231,6 +1231,55 @@ typedef struct {
|
||||||
} mess_lsys_krn_sys_vumap;
|
} mess_lsys_krn_sys_vumap;
|
||||||
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_vumap);
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_vumap);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[32];
|
||||||
|
int oflag;
|
||||||
|
|
||||||
|
uint8_t padding[20];
|
||||||
|
} mess_lsys_krn_sys_mqueue_open;
|
||||||
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_open);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int mqdes;
|
||||||
|
|
||||||
|
uint8_t padding[52];
|
||||||
|
} mess_lsys_krn_sys_mqueue_close;
|
||||||
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_close);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int mqdes;
|
||||||
|
char msg[32];
|
||||||
|
unsigned int msg_prio;
|
||||||
|
endpoint_t dst[4];
|
||||||
|
} mess_lsys_krn_sys_mqueue_send;
|
||||||
|
_ASSERT_MSG_SIZE(mess_lsys_krn_sys_mqueue_send);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int mqdes;
|
||||||
|
char msg[32];
|
||||||
|
unsigned int msg_prio;
|
||||||
|
endpoint_t dst;
|
||||||
|
|
||||||
|
uint8_t padding[12];
|
||||||
|
} 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 {
|
||||||
|
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 {
|
typedef struct {
|
||||||
void *vec_addr;
|
void *vec_addr;
|
||||||
int vec_size;
|
int vec_size;
|
||||||
|
@ -2248,6 +2297,12 @@ typedef struct noxfer_message {
|
||||||
mess_vm_vfs_mmap m_vm_vfs_mmap;
|
mess_vm_vfs_mmap m_vm_vfs_mmap;
|
||||||
mess_vmmcp m_vmmcp;
|
mess_vmmcp m_vmmcp;
|
||||||
mess_vmmcp_reply m_vmmcp_reply;
|
mess_vmmcp_reply m_vmmcp_reply;
|
||||||
|
mess_lsys_krn_sys_mqueue_open m_lsys_krn_sys_mqueue_open;
|
||||||
|
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;
|
||||||
|
mess_lsys_krn_sys_mqueue_notify m_lsys_krn_sys_mqueue_notify;
|
||||||
|
|
||||||
u8_t size[56]; /* message payload may have 56 bytes at most */
|
u8_t size[56]; /* message payload may have 56 bytes at most */
|
||||||
};
|
};
|
||||||
|
|
|
@ -275,5 +275,14 @@ int copyfd(endpoint_t endpt, int fd, int what);
|
||||||
#define COPYFD_TO 1 /* copy file descriptor to remote process */
|
#define COPYFD_TO 1 /* copy file descriptor to remote process */
|
||||||
#define COPYFD_CLOSE 2 /* close file descriptor in remote process */
|
#define COPYFD_CLOSE 2 /* close file descriptor in remote process */
|
||||||
|
|
||||||
|
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_mq_request_notify(int notify_on_off);
|
||||||
|
int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint);
|
||||||
|
|
||||||
#endif /* _SYSLIB_H */
|
#endif /* _SYSLIB_H */
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ DBG=-O0
|
||||||
.include "arch/${MACHINE_ARCH}/Makefile.inc"
|
.include "arch/${MACHINE_ARCH}/Makefile.inc"
|
||||||
|
|
||||||
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
|
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
|
||||||
table.c utility.c usermapped_data.c
|
table.c utility.c usermapped_data.c mqueue.c
|
||||||
|
|
||||||
LDADD+= -ltimers -lsys -lexec
|
LDADD+= -ltimers -lsys -lexec
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#define USE_RUNCTL 1 /* control stop flags of a process */
|
#define USE_RUNCTL 1 /* control stop flags of a process */
|
||||||
#define USE_STATECTL 1 /* let a process control its state */
|
#define USE_STATECTL 1 /* let a process control its state */
|
||||||
#define USE_MCONTEXT 1 /* enable getting/setting of machine context */
|
#define USE_MCONTEXT 1 /* enable getting/setting of machine context */
|
||||||
|
#define USE_MQ_IPC 1 /* enable user space message queues IPC */
|
||||||
|
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
#define USE_PADCONF 1 /* configure pinmux */
|
#define USE_PADCONF 1 /* configure pinmux */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "direct_utils.h"
|
#include "direct_utils.h"
|
||||||
#include "hw_intr.h"
|
#include "hw_intr.h"
|
||||||
#include "arch_proto.h"
|
#include "arch_proto.h"
|
||||||
|
#include "mqueue.h"
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
|
@ -304,6 +305,8 @@ void kmain(kinfo_t *local_cbi)
|
||||||
*/
|
*/
|
||||||
add_memmap(&kinfo, kinfo.bootstrap_start, kinfo.bootstrap_len);
|
add_memmap(&kinfo, kinfo.bootstrap_start, kinfo.bootstrap_len);
|
||||||
|
|
||||||
|
initialize_message_queues();
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (config_no_apic) {
|
if (config_no_apic) {
|
||||||
DEBUGBASIC(("APIC disabled, disables SMP, using legacy PIC\n"));
|
DEBUGBASIC(("APIC disabled, disables SMP, using legacy PIC\n"));
|
||||||
|
@ -376,6 +379,8 @@ void minix_shutdown(minix_timer_t *tp)
|
||||||
*/
|
*/
|
||||||
int how;
|
int how;
|
||||||
|
|
||||||
|
deinitialize_message_queues();
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/*
|
/*
|
||||||
* FIXME
|
* FIXME
|
||||||
|
|
258
minix/kernel/mqueue.c
Normal file
258
minix/kernel/mqueue.c
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <minix/sysutil.h>
|
||||||
|
|
||||||
|
#include "mqueue.h"
|
||||||
|
|
||||||
|
#include "kernel/kernel.h"
|
||||||
|
#include <minix/endpoint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "clock.h"
|
||||||
|
#include "proto.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
notify = NOTIFY_OFF;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int deinitialize_message_queues(void)
|
||||||
|
{
|
||||||
|
mq.num_queues = -1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 >= number_of_queues)
|
||||||
|
return EMQUEUEFULL;
|
||||||
|
|
||||||
|
if (strlen(name) > NAME_SIZE)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
for (int i = 0; i < number_of_queues; i++)
|
||||||
|
if (mq.queue_slot_empty[i] == NOT_EMPTY)
|
||||||
|
if (strncmp(mq.msg[i].name, name, NAME_SIZE) == 0) {
|
||||||
|
mq.msg[i].num_users++;
|
||||||
|
return (mqd_t) 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;
|
||||||
|
mq.num_queues++;
|
||||||
|
mq.msg[i].num_users++;
|
||||||
|
memset(mq.msg[i].name, '\0', NAME_SIZE);
|
||||||
|
strncpy(mq.msg[i].name, name, strlen(name));
|
||||||
|
|
||||||
|
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++)
|
||||||
|
mq.msg[i].msge[j].dst[k] = EMPTY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mqd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mq_close(mqd_t mqdes)
|
||||||
|
{
|
||||||
|
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||||
|
return EMSGNOTFOUND;
|
||||||
|
|
||||||
|
mq.msg[mqdes].num_users--;
|
||||||
|
if (mq.msg[mqdes].num_users == 0) {
|
||||||
|
mq.msg[mqdes].num_msgs = 0;
|
||||||
|
mq.queue_slot_empty[mqdes] = EMPTY;
|
||||||
|
mq.num_queues--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mq_send(mqd_t mqdes, const char *msg_ptr, unsigned int msg_prio, endpoint_t src, endpoint_t dst[])
|
||||||
|
{
|
||||||
|
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||||
|
return EMSGNOTFOUND;
|
||||||
|
|
||||||
|
if (mq.msg[mqdes].num_msgs > number_of_messages)
|
||||||
|
return EMSGFULL;
|
||||||
|
|
||||||
|
int empty_slot_pos;
|
||||||
|
for (int i = 0; i < number_of_messages; i++)
|
||||||
|
if (mq.msg[mqdes].msg_slot_empty[i] == EMPTY) {
|
||||||
|
empty_slot_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mq.msg[mqdes].msge[empty_slot_pos].msg, 0, MAX_PAYLOAD);
|
||||||
|
memcpy(mq.msg[mqdes].msge[empty_slot_pos].msg,
|
||||||
|
msg_ptr, MAX_PAYLOAD);
|
||||||
|
mq.msg[mqdes].msge[empty_slot_pos].src = src;
|
||||||
|
mq.msg[mqdes].msge[empty_slot_pos].priority = msg_prio;
|
||||||
|
mq.msg[mqdes].msg_slot_empty[empty_slot_pos] = NOT_EMPTY;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RECEIVERS; i++)
|
||||||
|
mq.msg[mqdes].msge[empty_slot_pos].dst[i] = dst[i];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t mq_receive(mqd_t mqdes, char *msg_ptr, unsigned int msg_prio, endpoint_t dst)
|
||||||
|
{
|
||||||
|
if (mqdes < 0 || mqdes >= number_of_queues)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (mq.queue_slot_empty[mqdes] == EMPTY)
|
||||||
|
return EMSGNOTFOUND;
|
||||||
|
|
||||||
|
if (mq.msg[mqdes].num_msgs == 0)
|
||||||
|
return EMSGEMPTY;
|
||||||
|
|
||||||
|
int index = message_index_with_highprio(mqdes, dst);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return EMSGEMPTY;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RECEIVERS; i++) {
|
||||||
|
if (mq.msg[mqdes].msge[index].dst[i] == dst) {
|
||||||
|
memcpy(msg_ptr, mq.msg[mqdes].msge[index].msg, MAX_PAYLOAD);
|
||||||
|
mq.msg[mqdes].msge[index].dst[i] = EMPTY;
|
||||||
|
clean_message_queue(mqdes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int message_index_with_highprio(int mqdes, endpoint_t dst)
|
||||||
|
{
|
||||||
|
int prio;
|
||||||
|
int max_prio = -1;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
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++) {
|
||||||
|
if (mq.msg[mqdes].msge[i].dst[j] == dst) {
|
||||||
|
if (max_prio == prio) {
|
||||||
|
if (mq.msg[mqdes].msge[i].timestamp > mq.msg[mqdes].msge[index].timestamp)
|
||||||
|
index = i;
|
||||||
|
} else if (max_prio < MAX(max_prio, prio)) {
|
||||||
|
index = i;
|
||||||
|
max_prio = MAX(max_prio, prio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int clean_message_queue(mqd_t mqdes)
|
||||||
|
{
|
||||||
|
int flag = 1;
|
||||||
|
|
||||||
|
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)
|
||||||
|
flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
mq.msg[mqdes].msg_slot_empty[i] = EMPTY;
|
||||||
|
mq.msg[mqdes].num_msgs--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mq_notify(int notify_on_off)
|
||||||
|
{
|
||||||
|
if (notify_on_off)
|
||||||
|
notify = NOTIFY_ON;
|
||||||
|
else
|
||||||
|
notify = NOTIFY_OFF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
78
minix/kernel/mqueue.h
Normal file
78
minix/kernel/mqueue.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef MQUEUE_H
|
||||||
|
#define MQUEUE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header file defines constants and function declarations used for
|
||||||
|
* MINIX interprocess message queues. These are used primarily in file
|
||||||
|
* mqueue.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 MAX_LIMIT
|
||||||
|
#define MAX_QUEUES MAX_LIMIT
|
||||||
|
#define MAX_PAYLOAD 32
|
||||||
|
#define NAME_SIZE 32
|
||||||
|
#define DEFAULT_PRIO 0
|
||||||
|
|
||||||
|
#define EMPTY -1
|
||||||
|
#define NOT_EMPTY 1
|
||||||
|
|
||||||
|
#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 {
|
||||||
|
u64_t timestamp;
|
||||||
|
char msg[MAX_PAYLOAD];
|
||||||
|
endpoint_t src;
|
||||||
|
endpoint_t dst[MAX_RECEIVERS];
|
||||||
|
unsigned int priority;
|
||||||
|
} message_entity;
|
||||||
|
|
||||||
|
typedef struct messageq {
|
||||||
|
char name[NAME_SIZE];
|
||||||
|
int num_msgs;
|
||||||
|
int num_users;
|
||||||
|
message_entity msge[MAX_MESSAGES];
|
||||||
|
int msg_slot_empty[MAX_MESSAGES];
|
||||||
|
} messageq;
|
||||||
|
|
||||||
|
typedef struct message_queue {
|
||||||
|
int num_queues;
|
||||||
|
messageq msg[MAX_QUEUES];
|
||||||
|
int queue_slot_empty[MAX_QUEUES];
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
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 mq_notify(int notify_on_off);
|
||||||
|
|
||||||
|
int clean_message_queue(mqd_t mqdes);
|
||||||
|
int message_index_with_highprio(mqd_t mqdes, endpoint_t dst);
|
||||||
|
|
||||||
|
#endif /* MQUEUE_H */
|
|
@ -108,11 +108,11 @@ static int kernel_call_dispatch(struct proc * caller, message *msg)
|
||||||
printf("SYSTEM: illegal request %d from %d.\n",
|
printf("SYSTEM: illegal request %d from %d.\n",
|
||||||
call_nr,msg->m_source);
|
call_nr,msg->m_source);
|
||||||
result = EBADREQUEST; /* illegal message type */
|
result = EBADREQUEST; /* illegal message type */
|
||||||
}
|
// } /* We have to allow user processes to send messages to kernel */
|
||||||
else if (!GET_BIT(priv(caller)->s_k_call_mask, call_nr)) {
|
// else if (!GET_BIT(priv(caller)->s_k_call_mask, call_nr)) {
|
||||||
printf("SYSTEM: denied request %d from %d.\n",
|
// printf("SYSTEM: denied request %d from %d.\n",
|
||||||
call_nr,msg->m_source);
|
// call_nr,msg->m_source);
|
||||||
result = ECALLDENIED; /* illegal message type */
|
// result = ECALLDENIED; /* illegal message type */
|
||||||
} else {
|
} else {
|
||||||
/* handle the system call */
|
/* handle the system call */
|
||||||
if (call_vec[call_nr])
|
if (call_vec[call_nr])
|
||||||
|
@ -268,6 +268,15 @@ void system_init(void)
|
||||||
map(SYS_SCHEDULE, do_schedule); /* reschedule a process */
|
map(SYS_SCHEDULE, do_schedule); /* reschedule a process */
|
||||||
map(SYS_SCHEDCTL, do_schedctl); /* change process scheduler */
|
map(SYS_SCHEDCTL, do_schedctl); /* change process scheduler */
|
||||||
|
|
||||||
|
/* User space IPC */
|
||||||
|
map(SYS_MQ_OPEN, do_mq_open); /* open a message queue */
|
||||||
|
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 */
|
||||||
|
map(SYS_MQ_REQ_NOTIFY, do_mq_request_notify); /* request notification for receive */
|
||||||
|
|
||||||
}
|
}
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* get_priv *
|
* get_priv *
|
||||||
|
|
|
@ -206,5 +206,40 @@ int do_padconf(struct proc * caller, message *m_ptr);
|
||||||
#define do_padconf NULL
|
#define do_padconf NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int do_mq_open(struct proc * caller, message *m_ptr);
|
||||||
|
#if ! USE_MQ_IPC
|
||||||
|
#define do_mq_open NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int do_mq_close(struct proc * caller, message *m_ptr);
|
||||||
|
#if ! USE_MQ_IPC
|
||||||
|
#define do_mq_close NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int do_mq_send(struct proc * caller, message *m_ptr);
|
||||||
|
#if ! USE_MQ_IPC
|
||||||
|
#define do_mq_send NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int do_mq_rec(struct proc * caller, message *m_ptr);
|
||||||
|
#if ! USE_MQ_IPC
|
||||||
|
#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
|
||||||
|
|
||||||
|
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 */
|
#endif /* SYSTEM_H */
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,14 @@ SRCS+= \
|
||||||
do_mcontext.c \
|
do_mcontext.c \
|
||||||
do_schedule.c \
|
do_schedule.c \
|
||||||
do_schedctl.c \
|
do_schedctl.c \
|
||||||
do_statectl.c
|
do_statectl.c \
|
||||||
|
do_mq_open.c \
|
||||||
|
do_mq_close.c \
|
||||||
|
do_mq_send.c \
|
||||||
|
do_mq_rec.c \
|
||||||
|
do_mq_set_attribute.c \
|
||||||
|
do_mq_get_attribute.c \
|
||||||
|
do_mq_request_notify.c
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} == "i386"
|
.if ${MACHINE_ARCH} == "i386"
|
||||||
SRCS+= \
|
SRCS+= \
|
||||||
|
|
26
minix/kernel/system/do_mq_close.c
Normal file
26
minix/kernel/system/do_mq_close.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_MQ_CLOSE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_close *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_mq_close(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
return mq_close(m_ptr->m_lsys_krn_sys_mqueue_close.mqdes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_MQ_IPC */
|
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_open.c
Normal file
28
minix/kernel/system/do_mq_open.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_MQ_OPEN
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_open *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_mq_open(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
return mq_open(m_ptr->m_lsys_krn_sys_mqueue_open.name,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_open.oflag);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_MQ_IPC */
|
29
minix/kernel/system/do_mq_rec.c
Normal file
29
minix/kernel/system/do_mq_rec.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_MQ_REC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_rec *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_mq_rec(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
return mq_receive(m_ptr->m_lsys_krn_sys_mqueue_receive.mqdes,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_receive.msg,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_receive.msg_prio,
|
||||||
|
caller->p_endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* USE_MQ_IPC */
|
26
minix/kernel/system/do_mq_request_notify.c
Normal file
26
minix/kernel/system/do_mq_request_notify.c
Normal file
|
@ -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 <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <minix/endpoint.h>
|
||||||
|
#include <minix/u64.h>
|
||||||
|
|
||||||
|
#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 */
|
30
minix/kernel/system/do_mq_send.c
Normal file
30
minix/kernel/system/do_mq_send.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* The kernel call implemented in this file:
|
||||||
|
* m_type: SYS_MQ_SEND
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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_send *
|
||||||
|
*===========================================================================*/
|
||||||
|
int do_mq_send(struct proc * caller, message * m_ptr)
|
||||||
|
{
|
||||||
|
return mq_send(m_ptr->m_lsys_krn_sys_mqueue_send.mqdes,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_send.msg,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_send.msg_prio,
|
||||||
|
caller->p_endpoint,
|
||||||
|
m_ptr->m_lsys_krn_sys_mqueue_send.dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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 */
|
|
@ -88,6 +88,14 @@ SRCS+= \
|
||||||
sys_vsafecopy.c \
|
sys_vsafecopy.c \
|
||||||
sys_vtimer.c \
|
sys_vtimer.c \
|
||||||
sys_vumap.c \
|
sys_vumap.c \
|
||||||
|
sys_mq_open.c \
|
||||||
|
sys_mq_close.c \
|
||||||
|
sys_mq_send.c \
|
||||||
|
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 \
|
taskcall.c \
|
||||||
tickdelay.c \
|
tickdelay.c \
|
||||||
timers.c \
|
timers.c \
|
||||||
|
|
108
minix/lib/libsys/sys_endpoint_from_pid.c
Normal file
108
minix/lib/libsys/sys_endpoint_from_pid.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include <minix/procfs.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "syslib.h"
|
||||||
|
|
||||||
|
struct pstat { /* structure filled by pstat() */
|
||||||
|
struct pstat *ps_next; /* next in process list */
|
||||||
|
int ps_task; /* is this process a task or not? */
|
||||||
|
int ps_endpt; /* process endpoint (NONE means unused slot) */
|
||||||
|
dev_t ps_dev; /* major/minor of controlling tty */
|
||||||
|
uid_t ps_ruid; /* real uid */
|
||||||
|
uid_t ps_euid; /* effective uid */
|
||||||
|
pid_t ps_pid; /* process id */
|
||||||
|
pid_t ps_ppid; /* parent process id */
|
||||||
|
int ps_pgrp; /* process group id */
|
||||||
|
char ps_state; /* process state */
|
||||||
|
char ps_pstate; /* sleep state */
|
||||||
|
char ps_fstate; /* VFS block state */
|
||||||
|
int ps_ftask; /* VFS suspend task (endpoint) */
|
||||||
|
vir_bytes ps_memory; /* memory usage */
|
||||||
|
int ps_recv; /* process number to receive from (endpoint) */
|
||||||
|
unsigned int ps_utime; /* accumulated user time */
|
||||||
|
unsigned int ps_stime; /* accumulated system time */
|
||||||
|
char ps_name[PROC_NAME_LEN + 1];/* process name */
|
||||||
|
char *ps_args; /* concatenated argument string */
|
||||||
|
};
|
||||||
|
|
||||||
|
int pstat(struct pstat *ps, pid_t pid);
|
||||||
|
|
||||||
|
int sys_endpoint_from_pid(pid_t pid, endpoint_t *endpoint) {
|
||||||
|
struct pstat ps;
|
||||||
|
int ret = pstat(&ps, pid);
|
||||||
|
if(!ret)
|
||||||
|
*endpoint = ps.ps_endpt;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Taken from minix/commands/ps/ps.c */
|
||||||
|
int pstat(struct pstat *ps, pid_t pid) {
|
||||||
|
FILE *fp;
|
||||||
|
int version, ruid, euid, dev;
|
||||||
|
char type, path[PATH_MAX], name[256];
|
||||||
|
|
||||||
|
ps->ps_pid = pid;
|
||||||
|
ps->ps_next = NULL;
|
||||||
|
|
||||||
|
sprintf(path, "/proc/%d/psinfo", pid);
|
||||||
|
|
||||||
|
if ((fp = fopen(path, "r")) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (fscanf(fp, "%d", &version) != 1) {
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The psinfo file's version must match what we expect. */
|
||||||
|
if (version != PSINFO_VERSION) {
|
||||||
|
fputs("procfs version mismatch!\n", stderr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fscanf(fp, " %c %d %255s %c %d %*d %u %u %*u %*u", &type, &ps->ps_endpt,
|
||||||
|
name, &ps->ps_state, &ps->ps_recv, &ps->ps_utime, &ps->ps_stime)
|
||||||
|
!= 7) {
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(ps->ps_name, name, sizeof(ps->ps_name) - 1);
|
||||||
|
ps->ps_name[sizeof(ps->ps_name) - 1] = 0;
|
||||||
|
|
||||||
|
ps->ps_task = type == TYPE_TASK;
|
||||||
|
|
||||||
|
if (!ps->ps_task) {
|
||||||
|
if (fscanf(fp, " %lu %*u %*u %c %d %u %u %u %*d %c %d %u",
|
||||||
|
&ps->ps_memory, &ps->ps_pstate, &ps->ps_ppid, &ruid, &euid,
|
||||||
|
&ps->ps_pgrp, &ps->ps_fstate, &ps->ps_ftask, &dev) != 9) {
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->ps_ruid = ruid;
|
||||||
|
ps->ps_euid = euid;
|
||||||
|
ps->ps_dev = dev;
|
||||||
|
} else {
|
||||||
|
ps->ps_memory = 0L;
|
||||||
|
ps->ps_pstate = PSTATE_NONE;
|
||||||
|
ps->ps_ppid = 0;
|
||||||
|
ps->ps_ruid = 0;
|
||||||
|
ps->ps_euid = 0;
|
||||||
|
ps->ps_pgrp = 0;
|
||||||
|
ps->ps_fstate = FSTATE_NONE;
|
||||||
|
ps->ps_ftask = NONE;
|
||||||
|
ps->ps_dev = NO_DEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (ps->ps_state == STATE_ZOMBIE)
|
||||||
|
strncpy(ps->ps_args, "<defunct>", 9);
|
||||||
|
else
|
||||||
|
ps->ps_args = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
10
minix/lib/libsys/sys_mq_close.c
Normal file
10
minix/lib/libsys/sys_mq_close.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "syslib.h"
|
||||||
|
|
||||||
|
int sys_mq_close(int mqdes)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m_lsys_krn_sys_mqueue_close.mqdes = mqdes;
|
||||||
|
|
||||||
|
return _kernel_call(SYS_MQ_CLOSE, &m);
|
||||||
|
}
|
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;
|
||||||
|
}
|
14
minix/lib/libsys/sys_mq_open.c
Normal file
14
minix/lib/libsys/sys_mq_open.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# include "syslib.h"
|
||||||
|
# include <string.h>
|
||||||
|
|
||||||
|
#define MAX_PAYLOAD 32
|
||||||
|
|
||||||
|
int sys_mq_open(const char *name, int oflag)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m_lsys_krn_sys_mqueue_open.oflag = oflag;
|
||||||
|
strncpy(m.m_lsys_krn_sys_mqueue_open.name, name, MAX_PAYLOAD);
|
||||||
|
|
||||||
|
return _kernel_call(SYS_MQ_OPEN, &m);
|
||||||
|
}
|
24
minix/lib/libsys/sys_mq_receive.c
Normal file
24
minix/lib/libsys/sys_mq_receive.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "syslib.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <machine/archtypes.h>
|
||||||
|
#include <minix/timers.h>
|
||||||
|
#include <minix/sysutil.h>
|
||||||
|
#include <minix/vm.h>
|
||||||
|
|
||||||
|
#define MAX_PAYLOAD 32
|
||||||
|
|
||||||
|
int sys_mq_receive(int mqdes, char *msg_ptr, unsigned int msg_prio)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m_lsys_krn_sys_mqueue_receive.mqdes = mqdes;
|
||||||
|
m.m_lsys_krn_sys_mqueue_receive.msg_prio = msg_prio;
|
||||||
|
|
||||||
|
ret = _kernel_call(SYS_MQ_REC, &m);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
memcpy(msg_ptr, m.m_lsys_krn_sys_mqueue_receive.msg, MAX_PAYLOAD);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
15
minix/lib/libsys/sys_mq_request_notify.c
Normal file
15
minix/lib/libsys/sys_mq_request_notify.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#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_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));
|
||||||
|
}
|
32
minix/lib/libsys/sys_mq_send.c
Normal file
32
minix/lib/libsys/sys_mq_send.c
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "syslib.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <machine/archtypes.h>
|
||||||
|
#include <minix/timers.h>
|
||||||
|
#include <minix/sysutil.h>
|
||||||
|
#include <minix/vm.h>
|
||||||
|
|
||||||
|
#define MAX_RECEIVERS 4
|
||||||
|
#define MAX_PAYLOAD 32
|
||||||
|
|
||||||
|
int sys_mq_send(int mqdes, const char *msg_ptr, pid_t dst[], unsigned int msg_prio)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
m.m_lsys_krn_sys_mqueue_send.mqdes = mqdes;
|
||||||
|
m.m_lsys_krn_sys_mqueue_send.msg_prio = msg_prio;
|
||||||
|
for (int i = 0; i < MAX_RECEIVERS; i++) {
|
||||||
|
if (dst[i] == -1) {
|
||||||
|
m.m_lsys_krn_sys_mqueue_send.dst[i] = dst[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint_t endpoint;
|
||||||
|
int ret = sys_endpoint_from_pid(dst[i], &endpoint);
|
||||||
|
if (ret != 0)
|
||||||
|
endpoint = -1;
|
||||||
|
m.m_lsys_krn_sys_mqueue_send.dst[i] = endpoint;
|
||||||
|
}
|
||||||
|
memcpy(m.m_lsys_krn_sys_mqueue_send.msg, msg_ptr, MAX_PAYLOAD);
|
||||||
|
|
||||||
|
return (_kernel_call(SYS_MQ_SEND, &m));
|
||||||
|
}
|
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));
|
||||||
|
}
|
|
@ -172,7 +172,13 @@
|
||||||
#define ENOLINK (_SIGN 95 ) /* Link has been severed */
|
#define ENOLINK (_SIGN 95 ) /* Link has been severed */
|
||||||
#define EPROTO (_SIGN 96 ) /* Protocol error */
|
#define EPROTO (_SIGN 96 ) /* Protocol error */
|
||||||
|
|
||||||
#define ELAST (_SIGN 96 ) /* Must equal largest errno */
|
#define EMQUEUEFULL (_SIGN 97 ) /* Message queue is full */
|
||||||
|
#define EMSGNOTFOUND (_SIGN 98 ) /* Message queue descriptor does not exist */
|
||||||
|
#define EMSGFULL (_SIGN 99 ) /* Message queue with given descriptor is full */
|
||||||
|
#define EMSGNONE (_SIGN 100 ) /* No message for process to retrieve */
|
||||||
|
#define EMSGEMPTY (_SIGN 101 ) /* Message queue empty */
|
||||||
|
|
||||||
|
#define ELAST (_SIGN 101 ) /* Must equal largest errno */
|
||||||
|
|
||||||
#if defined(_KERNEL) || defined(_KMEMUSER)
|
#if defined(_KERNEL) || defined(_KMEMUSER)
|
||||||
/* pseudo-errors returned inside kernel to modify return to process */
|
/* pseudo-errors returned inside kernel to modify return to process */
|
||||||
|
|
Loading…
Reference in a new issue