#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/kernel.h>
#include <sys/proc_msg.h>

typedef
struct sync_msg {
    short unsigned type;
    void *res;
} sync_msg_t;

typedef
struct mutex_lock_msg {
    short unsigned type;
    pthread_mutex_t *m;
    int count;
} mutex_lock_msg_t;

typedef
struct mutex_unlock_msg {
    short unsigned type;
    pthread_mutex_t *m;
} mutex_unlock_msg_t;

typedef
union mutex_msg {
    short unsigned type;
    mutex_lock_msg_t	lock;
    mutex_unlock_msg_t	unlock;
} mutex_msg_t;

typedef
struct condvar_wait_msg {
    short unsigned type;
    pthread_cond_t *cv;
    pthread_mutex_t *mutex;
    TID tid;
} condvar_wait_msg_t;

typedef
struct condvar_signal_msg {
    short unsigned type;
    pthread_cond_t *cv;
    int	broadcast;
    TID tid;
} condvar_signal_msg_t;

typedef
union condvar_msg {
    short unsigned type;
    condvar_wait_msg_t		wait;
    condvar_signal_msg_t	signal;
} condvar_msg_t;

typedef
struct timer_create_msg {
    short unsigned type;
    struct sigevent notify;
    void *msg;
    int msglen;
} timer_create_msg_t;

typedef
struct timer_id_msg {
    short unsigned type;
    int id;
} timer_id_msg_t;

typedef
struct timer_settime_msg {
    short unsigned type;
    int id;
    unsigned long flags;
    struct itimerspec itime;
} timer_settime_msg_t;

typedef
struct timer_timeout_msg {
    short unsigned type;
    int kind;
    struct sigevent notify;
    struct timespec when;
    void *msg;
    int msglen;
} timer_timeout_msg_t;

typedef
struct timer_alarm_msg {
    short unsigned type;
    pid_t tid;
    struct sigevent notify;
    pid_t notify_tid;
} timer_alarm_msg_t;

typedef
union timer_msg {
    short unsigned type;
    timer_create_msg_t	create;
    timer_id_msg_t	destroy;
    timer_id_msg_t	gettime;
    timer_settime_msg_t	settime;
    timer_timeout_msg_t	timeout;
    timer_alarm_msg_t	alarm;
    timer_id_msg_t	getoverrun;
} timer_msg_t;

typedef
struct timer_create_reply {
    short status;
    int id;
} timer_create_reply_t;

typedef
struct timer_destroy_reply {
    short status;
    void *msg;
} timer_destroy_reply_t;

typedef
struct timer_status_reply {
    short status;
} timer_status_reply_t;

typedef
struct timer_time_reply {
    struct itimerspec otime;
} timer_time_reply_t;

typedef
struct timer_timeout_reply {
    short status;
    struct timespec when;
} timer_timeout_reply_t;

typedef
struct timer_getoverrun_reply {
    short status;
    int count;
} timer_getoverrun_reply_t;

typedef
union timer_reply {
    short status;
    timer_create_reply_t		create;
    timer_destroy_reply_t		destroy;
    timer_time_reply_t			settime;
    timer_time_reply_t			gettime;
    timer_timeout_reply_t		timeout;
    timer_getoverrun_reply_t		getoverrun;
} timer_reply_t;

typedef
struct sched_set_msg {
    short unsigned	 type;
    pid_t		 tid;
    int			 policy;
    struct sched_param	 param;
} sched_set_msg_t;

typedef
struct sched_get_msg {
    short unsigned	 type;
    pid_t		 tid;
} sched_get_msg_t;

typedef
union sched_msg {
    short unsigned type;
    sched_set_msg_t	set;
    sched_get_msg_t	get;
} sched_msg_t;

typedef
struct sched_get_reply {
    short status;
    int policy;
    struct sched_param param;
} sched_get_reply_t;

typedef
union sched_reply {
    short status;
    sched_get_reply_t		get;
} sched_reply_t;

typedef
struct thread_create_msg {
    short unsigned type;
    pid_t pid;
    void *(*start_routine)(void *);
    void *arg;
    pthread_attr_t attr;
} thread_create_msg_t;

typedef
struct thread_destroy_msg {
    short unsigned type;
    pid_t tid;
    void *value;
} thread_destroy_msg_t;

typedef
struct thread_cancel_msg {
    short status;
    pid_t tid;
    void (*stub)(void);
} thread_cancel_msg_t;

struct thread_tid_msg {
    short unsigned type;
    pid_t tid;
};
typedef struct thread_tid_msg thread_detach_msg_t;
typedef struct thread_tid_msg thread_join_msg_t;

typedef
struct thread_join_reply {
    short status;
    void *val;
} thread_join_reply_t;

typedef
struct thread_create_reply {
    short status;
    TID tid;
} thread_create_reply_t;

typedef
union thread_msg {
    short unsigned type;
    thread_create_msg_t		create;
    thread_destroy_msg_t	destroy;
    thread_detach_msg_t		detach;
    thread_join_msg_t		join;
    thread_cancel_msg_t		cancel;
} thread_msg_t;

typedef
union thread_reply {
    short status;
    thread_join_reply_t		join;
    thread_create_reply_t	create;
} thread_reply_t;

typedef
struct proc_exit_msg {
    short status;
    int   value;
    void (*stub)(void);
} proc_exit_msg_t;

typedef
union proc_msg {
    short unsigned type;
    proc_exit_msg_t		exit;
} proc_msg_t;

typedef
union proc_reply {
    short status;
} proc_reply_t;

struct ker_msg;
#define __KER_MAX_CONTINUATIONS	2

typedef
struct ker_continuation_reply {
    short	 status;
    int		 parts;
    pid_t	 services[__KER_MAX_CONTINUATIONS];
} ker_continuation_reply_t;

typedef
struct ker_msg {
    union {
	msg_t func;
	sync_msg_t sync;
	mutex_msg_t mutex;
	condvar_msg_t condvar;
	thread_msg_t thread;
	proc_msg_t proc;
	timer_msg_t timer;
	sched_msg_t sched;
	short status;
	thread_reply_t thread_reply;
	proc_reply_t proc_reply;
	timer_reply_t timer_reply;
	sched_reply_t sched_reply;
	struct _proc_mmap map;
	struct _proc_priority priority;
	struct _proc_priority_reply priority_reply;
	ker_continuation_reply_t continuation_reply;
    };
} ker_msg_t;
