diff -ruN kozos36/Makefile kozos37/Makefile --- kozos36/Makefile Wed Jan 21 23:58:16 2009 +++ kozos37/Makefile Fri Jan 23 22:25:33 2009 @@ -1,4 +1,5 @@ -OBJS += thread.o syscall.o memory.o outlog.o timerd.o extintr.o idle.o +OBJS += thread.o syscall.o memory.o outlog.o timerd.o idle.o +OBJS += extintr.o extcont.o extsub.o OBJS += stubd.o stublib.o i386-stub.o OBJS += main.o clock.o clock2.o clock3.o command.o TARGET ?= koz diff -ruN kozos36/clock.c kozos37/clock.c --- kozos36/clock.c Wed Jan 21 23:58:16 2009 +++ kozos37/clock.c Fri Jan 23 22:05:03 2009 @@ -4,24 +4,31 @@ #include #include "kozos.h" +#include "extintr.h" + +#define TIMER_NO 0 int clock_id; -static void send_use(int num) +static void send_use() { char *p; - p = kz_kmalloc(2); - p[0] = 't'; - p[1] = '0' + num; - kz_send(extintr_id, 2, p); + p = kz_kmalloc(3); + p[0] = EXTINTR_CMD_TIMER; + p[1] = '0' + TIMER_NO; + p[2] = EXTINTR_CMD_TIMER_USE; + kz_send(extintr_id, 3, p); } static void send_enable() { char *p; - p = kz_kmalloc(10); - strcpy(p, "s1;;;0;;;"); - kz_send(extintr_id, 9, p); + p = kz_kmalloc(12); + p[0] = EXTINTR_CMD_TIMER; + p[1] = '0' + TIMER_NO; + p[2] = EXTINTR_CMD_TIMER_START; + strcpy(&p[3], "1;;;0;;;"); + kz_send(extintr_id, 11, p); } int clock_main(int argc, char *argv[]) @@ -29,7 +36,7 @@ time_t t; char *p; - send_use(0); + send_use(); while (1) { send_enable(); diff -ruN kozos36/clock2.c kozos37/clock2.c --- kozos36/clock2.c Wed Jan 21 23:58:16 2009 +++ kozos37/clock2.c Thu Jan 22 20:58:16 2009 @@ -11,7 +11,7 @@ { char *p; p = kz_kmalloc(7); - strcpy(p, "s1500;"); + strcpy(p, "1500;"); kz_send(timerd_id, 7, p); } diff -ruN kozos36/clock3.c kozos37/clock3.c --- kozos36/clock3.c Wed Jan 21 23:58:16 2009 +++ kozos37/clock3.c Thu Jan 22 20:58:22 2009 @@ -11,7 +11,7 @@ { char *p; p = kz_kmalloc(7); - strcpy(p, "s1800;"); + strcpy(p, "1800;"); kz_send(timerd_id, 7, p); } diff -ruN kozos36/command.c kozos37/command.c --- kozos36/command.c Wed Jan 21 23:58:16 2009 +++ kozos37/command.c Fri Jan 23 22:07:01 2009 @@ -5,6 +5,9 @@ #include "kozos.h" #include "thread.h" +#include "extintr.h" + +#define CONSOLE_NO 0 int command_id; int command_dummy; @@ -19,30 +22,35 @@ return sum; } -static void send_use(int num) +static void send_use() { char *p; - p = kz_kmalloc(2); - p[0] = 'u'; - p[1] = '0' + num; - kz_send(extintr_id, 2, p); + p = kz_kmalloc(3); + p[0] = EXTINTR_CMD_CONSOLE; + p[1] = '0' + CONSOLE_NO; + p[2] = EXTINTR_CMD_CONSOLE_USE; + kz_send(extintr_id, 3, p); } static void send_enable() { char *p; - p = kz_kmalloc(1); - p[0] = 'e'; - kz_send(extintr_id, 1, p); + p = kz_kmalloc(3); + p[0] = EXTINTR_CMD_CONSOLE; + p[1] = '0' + CONSOLE_NO; + p[2] = EXTINTR_CMD_CONSOLE_ENABLE; + kz_send(extintr_id, 3, p); } #if 0 static void send_disable() { char *p; - p = kz_kmalloc(1); - p[0] = 'd'; - kz_send(extintr_id, 1, p); + p = kz_kmalloc(3); + p[0] = EXTINTR_CMD_CONSOLE; + p[1] = '0' + CONSOLE_NO; + p[2] = EXTINTR_CMD_CONSOLE_DISABLE; + kz_send(extintr_id, 3, p); } #endif @@ -51,10 +59,12 @@ char *p; int len; len = strlen(str); - p = kz_kmalloc(len + 1); - p[0] = 'w'; - memcpy(&p[1], str, len); - kz_send(extintr_id, len + 1, p); + p = kz_kmalloc(len + 3); + p[0] = EXTINTR_CMD_CONSOLE; + p[1] = '0' + CONSOLE_NO; + p[2] = EXTINTR_CMD_CONSOLE_WRITE; + memcpy(&p[3], str, len); + kz_send(extintr_id, len + 3, p); } static int command_proc() @@ -120,7 +130,7 @@ int command_main(int argc, char *argv[]) { - send_use(0); + send_use(); while (1) { command_proc(); diff -ruN kozos36/extcont.c kozos37/extcont.c --- kozos36/extcont.c Thu Jan 1 09:00:00 1970 +++ kozos37/extcont.c Mon Jan 26 21:37:19 2009 @@ -0,0 +1,467 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kozos.h" +#include "thread.h" +#include "extintr.h" +#include "extsub.h" + +#define EXTINTR_CONSOLE_SOCKET_PORT 12345 + +static int control_fd; /* 親プロセスからの制御用 */ + +static struct timerbuf { + struct timeval tm; + int write_fd; /* 親プロセスへの転送用 */ + int cnt_fd; /* 親プロセスからの制御用 */ + unsigned int flags; +#define TIMERBUF_FLAG_ENABLE (1<<0) +#define TIMERBUF_FLAG_MASKED (1<<1) +#define TIMERBUF_FLAG_EXPIRED (1<<2) +} timerbuf[EXTINTR_TIMER_NUM]; + +static struct consbuf { + int accept_socket; + int rw_socket; + int read_fd; /* 親プロセスからの転送用 */ + int write_fd; /* 親プロセスへの転送用 */ + int cnt_fd; /* 親プロセスからの制御用 */ + struct sockaddr addr; + unsigned int flags; +#define CONSBUF_FLAG_ENABLE (1<<0) +} consbuf[EXTINTR_CONSOLE_NUM]; + +static pid_t parent_pid; + +static int timecmp(struct timeval *tm1, struct timeval *tm2) +{ + if (tm1->tv_sec > tm2->tv_sec ) return 1; + if (tm1->tv_sec < tm2->tv_sec ) return -1; + if (tm1->tv_usec > tm2->tv_usec) return 1; + if (tm1->tv_usec < tm2->tv_usec) return -1; + return 0; +} + +static int timeadd(struct timeval *add, struct timeval *tm1, struct timeval *tm2) +{ + add->tv_sec = tm1->tv_sec + tm2->tv_sec; + add->tv_usec = tm1->tv_usec + tm2->tv_usec; + while (add->tv_usec >= 1000000) { + add->tv_sec++; + add->tv_usec -= 1000000; + } + return 0; +} + +static int timesub(struct timeval *sub, struct timeval *tm1, struct timeval *tm2) +{ + int s = 0; + if (tm1->tv_usec < tm2->tv_usec) s = 1; + sub->tv_sec = -s + tm1->tv_sec - tm2->tv_sec; + sub->tv_usec = s * 1000000 + tm1->tv_usec - tm2->tv_usec; + return 0; +} + +static int check_timer(struct timeval *now) +{ + int i; + struct timerbuf *tbp; + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) + continue; + if (tbp->flags & TIMERBUF_FLAG_EXPIRED) + continue; + if (timecmp(now, &tbp->tm) >= 0) { + tbp->flags |= TIMERBUF_FLAG_EXPIRED; + } + } + return 0; +} + +static int expire_timer() +{ + int i; + char c = EXTCONT_INT_TIMER_EXPIRE; + struct timerbuf *tbp; + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) + continue; + if ((tbp->flags & TIMERBUF_FLAG_EXPIRED) && + !(tbp->flags & TIMERBUF_FLAG_MASKED)) { + write(tbp->write_fd, &c, 1); + kill(parent_pid, SIGHUP); + tbp->flags &= ~(TIMERBUF_FLAG_ENABLE | TIMERBUF_FLAG_EXPIRED); + } + } + return 0; +} + +static struct timerbuf *search_recent_timer() +{ + int i; + struct timerbuf *tbp; + struct timerbuf *recent_timer = NULL; + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) + continue; + if (tbp->flags & TIMERBUF_FLAG_EXPIRED) + continue; + if (!recent_timer || (timecmp(&recent_timer->tm, &tbp->tm) > 0)) + recent_timer = tbp; + } + return recent_timer; +} + +static int socket_init_addr() +{ + char hostname[256]; + struct hostent *host; + struct sockaddr_in address; + int i, port; + struct consbuf *cbp; + +#if 1 + gethostname(hostname, sizeof(hostname)); +#else + strcpy(hostname, "localhost"); +#endif + + host = gethostbyname(hostname); + if (host == NULL) { + fprintf(stderr, "gethostbyname() failed.\n"); + exit (-1); + } + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + port = EXTINTR_CONSOLE_SOCKET_PORT + i; + + memset(&address, 0, sizeof(address)); + address.sin_family = AF_INET; + address.sin_len = sizeof(address); + address.sin_port = htons(port); + memcpy(&(address.sin_addr), host->h_addr, host->h_length); + + memcpy(&cbp->addr, &address, sizeof(cbp->addr)); + } + + return 0; +} + +static int socket_init() +{ + int i, s, ret, backlog = 5; + struct consbuf *cbp; + + socket_init_addr(); + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + + s = socket(cbp->addr.sa_family, SOCK_STREAM, 0); + if (s < 0) { + fprintf(stderr, "socket() failed.\n"); + exit (-1); + } + + ret = bind(s, &cbp->addr, cbp->addr.sa_len); + if (ret < 0) { + fprintf(stderr, "bind() failed.\n"); + exit (-1); + } + + ret = listen(s, backlog); + if (ret < 0) { + fprintf(stderr, "listen() failed.\n"); + exit (-1); + } + + cbp->accept_socket = s; + } + + return 0; +} + +static int timerbuf_init() +{ + int i; + struct timerbuf *tbp; + + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + memset(tbp, 0, sizeof(*tbp)); + tbp->write_fd = -1; + tbp->cnt_fd = -1; + } + + return 0; +} + +static int consbuf_init() +{ + int i; + struct consbuf *cbp; + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + memset(cbp, 0, sizeof(*cbp)); + cbp->accept_socket = -1; + cbp->rw_socket = -1; + cbp->read_fd = -1; + cbp->write_fd = -1; + cbp->cnt_fd = -1; + } + + return 0; +} + +static int controller_init() +{ + control_fd = -1; + timerbuf_init(); + consbuf_init(); + return 0; +} + +static int intr_controller() +{ + int i, s, ret, size; + int maxfd; + fd_set readfds; + fd_set fds; + char buf[128]; + struct timerbuf *tbp; + struct consbuf *cbp; + socklen_t len; + struct timeval now, tm; + struct timeval *tp; + struct timerbuf *recent_timer; + + socket_init(); + + maxfd = -1; + FD_ZERO(&readfds); + + extintr_set_readfds(control_fd, &maxfd, &readfds); + + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + extintr_set_readfds(tbp->cnt_fd, &maxfd, &readfds); + } + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + extintr_set_readfds(cbp->accept_socket, &maxfd, &readfds); + extintr_set_readfds(cbp->read_fd, &maxfd, &readfds); + extintr_set_readfds(cbp->cnt_fd, &maxfd, &readfds); + } + + /* + * 子プロセスなので,この中で kz_ システムコールを利用してはいけない. + */ + + gettimeofday(&now, NULL); + + while (1) { + + check_timer(&now); + expire_timer(); + + recent_timer = search_recent_timer(); + if (!recent_timer) { + tp = NULL; + } else { + timesub(&tm, &recent_timer->tm, &now); + tp = &tm; + } + + fds = readfds; + ret = select(maxfd + 1, &fds, NULL, NULL, tp); + + gettimeofday(&now, NULL); + + if (ret < 0) { + /* none */ + } else if (ret == 0) { + continue; + } else { + if ((control_fd >= 0) && FD_ISSET(control_fd, &fds)) { + size = read(control_fd, buf, sizeof(buf)); + if (size <= 0) { + goto end; + } else { + for (i = 0; i < size; i++) { + switch (buf[i]) { + case EXTCONT_CMD_CONTROL_DUMMY: + goto end; + default: + break; + } + } + } + } + + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + + if ((tbp->cnt_fd >= 0) && FD_ISSET(tbp->cnt_fd, &fds)) { + size = read(tbp->cnt_fd, buf, sizeof(buf)); + if (size > 0) { + for (i = 0; i < size; i++) { + switch (buf[i]) { + case EXTCONT_CMD_TIMER_START: + tbp->flags |= TIMERBUF_FLAG_ENABLE; + tbp->tm.tv_sec = strtol(&buf[i + 1], NULL, 0); + tbp->tm.tv_usec = strtol(&buf[i + 5], NULL, 0) * 1000; + timeadd(&tbp->tm, &now, &tbp->tm); + i += 8; + break; + + case EXTCONT_CMD_TIMER_MASK: + tbp->flags |= TIMERBUF_FLAG_MASKED; + break; + + case EXTCONT_CMD_TIMER_UNMASK: + tbp->flags &= ~TIMERBUF_FLAG_MASKED; + break; + + default: + break; + } + } + } + } + } + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + + if ((cbp->accept_socket >= 0) && FD_ISSET(cbp->accept_socket, &fds)) { + len = cbp->addr.sa_len; + s = accept(cbp->accept_socket, &cbp->addr, &len); + if (s >= 0) { + if (cbp->rw_socket >= 0) { + close(s); + } else { + cbp->rw_socket = s; + if (cbp->flags & CONSBUF_FLAG_ENABLE) + extintr_set_readfds(cbp->rw_socket, &maxfd, &readfds); + } + } + } + + if ((cbp->rw_socket >= 0) && FD_ISSET(cbp->rw_socket, &fds)) { + cbp->flags &= ~CONSBUF_FLAG_ENABLE; + extintr_reset_readfds(cbp->rw_socket, &maxfd, &readfds); + size = read(cbp->rw_socket, buf, sizeof(buf)); + if (size <= 0) { + shutdown(cbp->rw_socket, SHUT_RDWR); + cbp->rw_socket = -1; + } else { + write(cbp->write_fd, buf, size); + kill(parent_pid, SIGHUP); + } + } + + if ((cbp->read_fd >= 0) && FD_ISSET(cbp->read_fd, &fds)) { + size = read(cbp->read_fd, buf, sizeof(buf)); + if (size > 0) { + write(cbp->rw_socket, buf, size); + } + } + + if ((cbp->cnt_fd >= 0) && FD_ISSET(cbp->cnt_fd, &fds)) { + size = read(cbp->cnt_fd, buf, sizeof(buf)); + if (size > 0) { + for (i = 0; i < size; i++) { + switch (buf[i]) { + case EXTCONT_CMD_CONSOLE_ENABLE: + cbp->flags |= CONSBUF_FLAG_ENABLE; + if (cbp->rw_socket >= 0) + extintr_set_readfds(cbp->rw_socket, &maxfd, &readfds); + break; + + case EXTCONT_CMD_CONSOLE_DISABLE: + cbp->flags &= ~CONSBUF_FLAG_ENABLE; + if (cbp->rw_socket >= 0) + extintr_reset_readfds(cbp->rw_socket, &maxfd, &readfds); + break; + default: + break; + } + } + } + } + } + } + } + +end: + return 0; +} + +int extchild_main(int pid, + int cnt_fildes[2], + int timer_r_fildes[EXTINTR_TIMER_NUM][2], + int timer_cnt_fildes[EXTINTR_TIMER_NUM][2], + int cons_r_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_w_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_cnt_fildes[EXTINTR_CONSOLE_NUM][2]) +{ + int i; + struct timerbuf *tbp; + struct consbuf *cbp; + + parent_pid = pid; + + /* + * 子プロセスはシグナル設定を引き継ぐらしいので,シグナル無効にする. + * (man sigaction に以下の記述あり) + * After a fork(2) or vfork(2) all signals, the signal mask, the signal + * stack, and the restart/interrupt flags are inherited by the child. + */ + sigprocmask(SIG_BLOCK, &block, NULL); + + controller_init(); + + close(cnt_fildes[1]); /* 書き込み端 */ + control_fd = cnt_fildes[0]; /* 読み込み端 */ + + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + tbp = &timerbuf[i]; + + close(timer_r_fildes[i][0]); /* 読み込み端 */ + tbp->write_fd = timer_r_fildes[i][1]; /* 書き込み端 */ + + close(timer_cnt_fildes[i][1]); /* 書き込み端 */ + tbp->cnt_fd = timer_cnt_fildes[i][0]; /* 読み込み端 */ + } + + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + cbp = &consbuf[i]; + + close(cons_r_fildes[i][0]); /* 読み込み端 */ + cbp->write_fd = cons_r_fildes[i][1]; /* 書き込み端 */ + + close(cons_w_fildes[i][1]); /* 書き込み端 */ + cbp->read_fd = cons_w_fildes[i][0]; /* 読み込み端 */ + + close(cons_cnt_fildes[i][1]); /* 書き込み端 */ + cbp->cnt_fd = cons_cnt_fildes[i][0]; /* 読み込み端 */ + } + + intr_controller(); + + return 0; +} diff -ruN kozos36/extintr.c kozos37/extintr.c --- kozos36/extintr.c Wed Jan 21 23:58:16 2009 +++ kozos37/extintr.c Mon Jan 26 21:44:44 2009 @@ -1,623 +1,306 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include #include "kozos.h" #include "thread.h" +#include "extintr.h" +#include "extsub.h" #define BUFFER_SIZE 1024 -#define TIMER_NUM 4 -#define INTERRUPT_NUM 4 -#define PORT 12345 int extintr_id; -static int control_fd; /* 親プロセスからの制御用 */ +static int control_fd; /* 子プロセスへの制御用 */ -struct timerbuf { - struct timeval tm; - int write_fd; /* 親プロセスへの転送用 */ - int cnt_fd; /* 親プロセスからの制御用 */ - unsigned int flags; -#define TIMERBUF_FLAG_ENABLE (1<<0) -#define TIMERBUF_FLAG_MASKED (1<<1) -#define TIMERBUF_FLAG_EXPIRED (1<<2) -} timerbuf[TIMER_NUM]; +static struct timerreg { + int read_fd; /* 子プロセスからの転送用 */ + int cnt_fd; /* 子プロセスへの制御用 */ + struct interrupts *interrupt; +} timerreg[EXTINTR_TIMER_NUM]; -struct intrbuf { - int accept_socket; - int rw_socket; - int read_fd; /* 親プロセスからの転送用 */ - int write_fd; /* 親プロセスへの転送用 */ - int cnt_fd; /* 親プロセスからの制御用 */ - struct sockaddr addr; - unsigned int flags; -#define INTRBUF_FLAG_ENABLE (1<<0) -} intrbuf[INTERRUPT_NUM]; +static struct consreg { + int read_fd; /* 子プロセスからの転送用 */ + int write_fd; /* 子プロセスへの転送用 */ + int cnt_fd; /* 子プロセスへの制御用 */ + struct interrupts *interrupt; +} consreg[EXTINTR_CONSOLE_NUM]; -static pid_t pid; +static struct interrupts { -static int timecmp(struct timeval *tm1, struct timeval *tm2) -{ - if (tm1->tv_sec > tm2->tv_sec ) return 1; - if (tm1->tv_sec < tm2->tv_sec ) return -1; - if (tm1->tv_usec > tm2->tv_usec) return 1; - if (tm1->tv_usec < tm2->tv_usec) return -1; - return 0; -} + int id; -static int timeadd(struct timeval *add, struct timeval *tm1, struct timeval *tm2) -{ - add->tv_sec = tm1->tv_sec + tm2->tv_sec; - add->tv_usec = tm1->tv_usec + tm2->tv_usec; - while (add->tv_usec >= 1000000) { - add->tv_sec++; - add->tv_usec -= 1000000; - } - return 0; -} + enum { + INTERRUPTS_TYPE_UNKNOWN = 0, + INTERRUPTS_TYPE_TIMER, + INTERRUPTS_TYPE_CONSOLE, + } type; + + union { + void *reg; + struct timerreg *timer; + struct consreg *cons; + } regs; + + int (*checkintr)(struct interrupts *intp); + int (*intr)(struct interrupts *intp); + int (*command)(struct interrupts *intp, int id, int size, char *command); -static int timesub(struct timeval *sub, struct timeval *tm1, struct timeval *tm2) -{ - int s = 0; - if (tm1->tv_usec < tm2->tv_usec) s = 1; - sub->tv_sec = -s + tm1->tv_sec - tm2->tv_sec; - sub->tv_usec = s * 1000000 + tm1->tv_usec - tm2->tv_usec; - return 0; -} +} interrupts[EXTINTR_INTERRUPTS_NUM]; -static int check_timer(struct timeval *now) -{ - int i; - struct timerbuf *tbp; - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) - continue; - if (tbp->flags & TIMERBUF_FLAG_EXPIRED) - continue; - if (timecmp(now, &tbp->tm) >= 0) { - tbp->flags |= TIMERBUF_FLAG_EXPIRED; - } - } - return 0; -} +typedef int (*initfunc)(struct interrupts *intp); -static int expire_timer() +static int timerreg_init() { int i; - struct timerbuf *tbp; - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) - continue; - if ((tbp->flags & TIMERBUF_FLAG_EXPIRED) && - !(tbp->flags & TIMERBUF_FLAG_MASKED)) { - write(tbp->write_fd, "e", 1); - kill(pid, SIGHUP); - tbp->flags &= ~(TIMERBUF_FLAG_ENABLE | TIMERBUF_FLAG_EXPIRED); - } + struct timerreg *trp; + + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + trp = &timerreg[i]; + memset(trp, 0, sizeof(*trp)); + trp->read_fd = -1; + trp->cnt_fd = -1; } + return 0; } -static struct timerbuf *search_recent_timer() +static int consreg_init() { int i; - struct timerbuf *tbp; - struct timerbuf *recent_timer = NULL; - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - if (!(tbp->flags & TIMERBUF_FLAG_ENABLE)) - continue; - if (tbp->flags & TIMERBUF_FLAG_EXPIRED) - continue; - if (!recent_timer || (timecmp(&recent_timer->tm, &tbp->tm) > 0)) - recent_timer = tbp; - } - return recent_timer; -} + struct consreg *crp; -static void set_readfds(int fd, int *maxfd, fd_set *fds) -{ - if (fd >= 0) { - FD_SET(fd, fds); - if (*maxfd < fd) *maxfd = fd; + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + crp = &consreg[i]; + memset(crp, 0, sizeof(*crp)); + crp->read_fd = -1; + crp->write_fd = -1; + crp->cnt_fd = -1; } + + return 0; } -static void reset_readfds(int fd, int *maxfd, fd_set *fds) +static int regs_init() { - if (fd >= 0) { - FD_CLR(fd, fds); - if ((*maxfd == fd) && (fd > 0)) *maxfd = fd - 1; - } + timerreg_init(); + consreg_init(); + return 0; } -static int socket_init_addr() +static int extregs_init(int cnt_fildes[2], + int timer_r_fildes[EXTINTR_TIMER_NUM][2], + int timer_cnt_fildes[EXTINTR_TIMER_NUM][2], + int cons_r_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_w_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_cnt_fildes[EXTINTR_CONSOLE_NUM][2]) { - char hostname[256]; - struct hostent *host; - struct sockaddr_in address; - int i, port; - struct intrbuf *ibp; - -#if 1 - gethostname(hostname, sizeof(hostname)); -#else - strcpy(hostname, "localhost"); -#endif - - host = gethostbyname(hostname); - if (host == NULL) { - fprintf(stderr, "gethostbyname() failed.\n"); - exit (-1); - } - - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; - port = PORT + i; + int i; + struct timerreg *trp; + struct consreg *crp; - memset(&address, 0, sizeof(address)); - address.sin_family = AF_INET; - address.sin_len = sizeof(address); - address.sin_port = htons(port); - memcpy(&(address.sin_addr), host->h_addr, host->h_length); + regs_init(); - memcpy(&ibp->addr, &address, sizeof(ibp->addr)); - } + close(cnt_fildes[0]); /* 読み込み端 */ + control_fd = cnt_fildes[1]; /* 書き込み端 */ - return 0; -} + kz_setsig(SIGHUP); -static int socket_init() -{ - int i, s, ret, backlog = 5; - struct intrbuf *ibp; + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { + trp = &timerreg[i]; - socket_init_addr(); + close(timer_r_fildes[i][1]); /* 書き込み端 */ + trp->read_fd = timer_r_fildes[i][0]; /* 読み込み端 */ - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; + close(timer_cnt_fildes[i][0]); /* 読み込み端 */ + trp->cnt_fd = timer_cnt_fildes[i][1]; /* 書き込み端 */ + } - s = socket(ibp->addr.sa_family, SOCK_STREAM, 0); - if (s < 0) { - fprintf(stderr, "socket() failed.\n"); - exit (-1); - } + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + crp = &consreg[i]; - ret = bind(s, &ibp->addr, ibp->addr.sa_len); - if (ret < 0) { - fprintf(stderr, "bind() failed.\n"); - exit (-1); - } + close(cons_r_fildes[i][1]); /* 書き込み端 */ + crp->read_fd = cons_r_fildes[i][0]; /* 読み込み端 */ - ret = listen(s, backlog); - if (ret < 0) { - fprintf(stderr, "listen() failed.\n"); - exit (-1); - } + close(cons_w_fildes[i][0]); /* 読み込み端 */ + crp->write_fd = cons_w_fildes[i][1]; /* 書き込み端 */ - ibp->accept_socket = s; + close(cons_cnt_fildes[i][0]); /* 読み込み端 */ + crp->cnt_fd = cons_cnt_fildes[i][1]; /* 書き込み端 */ } return 0; } -static int timerbuf_init() +static int interrupts_init() { - int i; - struct timerbuf *tbp; - - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - memset(tbp, 0, sizeof(*tbp)); - tbp->write_fd = -1; - tbp->cnt_fd = -1; - } - + memset(interrupts, 0, sizeof(interrupts)); return 0; } -static int intrbuf_init() +static int timer_checkintr(struct interrupts *intp) { - int i; - struct intrbuf *ibp; - - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; - memset(ibp, 0, sizeof(*ibp)); - ibp->accept_socket = -1; - ibp->rw_socket = -1; - ibp->read_fd = -1; - ibp->write_fd = -1; - ibp->cnt_fd = -1; - } - - return 0; + return extintr_checkfd(intp->regs.timer->read_fd); } -static int controller_init() +static int timer_intr(struct interrupts *intp) { - control_fd = -1; - timerbuf_init(); - intrbuf_init(); + int size; + char c; + size = read(intp->regs.timer->read_fd, &c, 1); + if ((size >= 0) && intp->id) { + kz_send(intp->id, 0, NULL); + } return 0; } -static int intr_controller() +static int timer_command(struct interrupts *intp, int id, int size, char *command) { - int i, s, ret, size; - int maxfd; - fd_set readfds; - fd_set fds; - char buf[128]; - struct timerbuf *tbp; - struct intrbuf *ibp; - socklen_t len; - struct timeval now, tm; - struct timeval *tp; - struct timerbuf *recent_timer; + switch (command[0]) { + case EXTINTR_CMD_TIMER_USE: + intp->id = id; + break; - socket_init(); + case EXTINTR_CMD_TIMER_START: + command[0] = EXTCONT_CMD_TIMER_START; + write(intp->regs.timer->cnt_fd, &command[0], 9); + break; - maxfd = -1; - FD_ZERO(&readfds); + case EXTINTR_CMD_TIMER_MASK: + command[0] = EXTCONT_CMD_TIMER_MASK; + write(intp->regs.timer->cnt_fd, &command[0], 1); + break; - set_readfds(control_fd, &maxfd, &readfds); + case EXTINTR_CMD_TIMER_UNMASK: + command[0] = EXTCONT_CMD_TIMER_UNMASK; + write(intp->regs.timer->cnt_fd, &command[0], 1); + break; - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - set_readfds(tbp->cnt_fd, &maxfd, &readfds); + default: + break; } - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; - set_readfds(ibp->accept_socket, &maxfd, &readfds); - set_readfds(ibp->read_fd, &maxfd, &readfds); - set_readfds(ibp->cnt_fd, &maxfd, &readfds); - } - - /* - * 子プロセスなので,この中で kz_ システムコールを利用してはいけない. - */ - - while (1) { - gettimeofday(&now, NULL); - - check_timer(&now); - expire_timer(); - - recent_timer = search_recent_timer(); - if (!recent_timer) { - tp = NULL; - } else { - timesub(&tm, &recent_timer->tm, &now); - tp = &tm; - } - - fds = readfds; - ret = select(maxfd + 1, &fds, NULL, NULL, tp); - - if (ret < 0) { - /* none */ - } else if (ret == 0) { - continue; - } else { - if ((control_fd >= 0) && FD_ISSET(control_fd, &fds)) { - size = read(control_fd, buf, sizeof(buf)); - if (size <= 0) { - goto end; - } else { - for (i = 0; i < size; i++) { - switch (buf[i]) { - case 'e': - goto end; - default: - break; - } - } - } - } - - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - - if ((tbp->cnt_fd >= 0) && FD_ISSET(tbp->cnt_fd, &fds)) { - size = read(tbp->cnt_fd, buf, sizeof(buf)); - if (size > 0) { - for (i = 0; i < size; i++) { - switch (buf[i]) { - case 's': - tbp->flags |= INTRBUF_FLAG_ENABLE; - tbp->tm.tv_sec = strtol(&buf[1], NULL, 0); - tbp->tm.tv_usec = strtol(&buf[5], NULL, 0) * 1000; - timeadd(&tbp->tm, &now, &tbp->tm); - i += 8; - break; - - case 'm': - tbp->flags |= TIMERBUF_FLAG_MASKED; - break; - - default: - break; - } - } - } - } - } - - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; - - if ((ibp->accept_socket >= 0) && FD_ISSET(ibp->accept_socket, &fds)) { - len = ibp->addr.sa_len; - s = accept(ibp->accept_socket, &ibp->addr, &len); - if (s >= 0) { - if (ibp->rw_socket >= 0) { - close(s); - } else { - ibp->rw_socket = s; - if (ibp->flags & INTRBUF_FLAG_ENABLE) - set_readfds(ibp->rw_socket, &maxfd, &readfds); - } - } - } - - if ((ibp->rw_socket >= 0) && FD_ISSET(ibp->rw_socket, &fds)) { - ibp->flags &= ~INTRBUF_FLAG_ENABLE; - reset_readfds(ibp->rw_socket, &maxfd, &readfds); - size = read(ibp->rw_socket, buf, sizeof(buf)); - if (size <= 0) { - shutdown(ibp->rw_socket, SHUT_RDWR); - ibp->rw_socket = -1; - } else { - write(ibp->write_fd, buf, size); - kill(pid, SIGHUP); - } - } - - if ((ibp->read_fd >= 0) && FD_ISSET(ibp->read_fd, &fds)) { - size = read(ibp->read_fd, buf, sizeof(buf)); - if (size > 0) { - write(ibp->rw_socket, buf, size); - } - } - - if ((ibp->cnt_fd >= 0) && FD_ISSET(ibp->cnt_fd, &fds)) { - size = read(ibp->cnt_fd, buf, sizeof(buf)); - if (size > 0) { - for (i = 0; i < size; i++) { - switch (buf[i]) { - case 'e': - ibp->flags |= INTRBUF_FLAG_ENABLE; - if (ibp->rw_socket >= 0) - set_readfds(ibp->rw_socket, &maxfd, &readfds); - break; - - case 'd': - ibp->flags &= ~INTRBUF_FLAG_ENABLE; - if (ibp->rw_socket >= 0) - reset_readfds(ibp->rw_socket, &maxfd, &readfds); - break; - default: - break; - } - } - } - } - } - } - } - -end: return 0; } -/* - * ここから下は親プロセスの処理 - */ - -static int control_intr_fd; /* 子プロセスへの制御用 */ - -struct timerreg { - int read_fd; /* 子プロセスからの転送用 */ - int cnt_fd; /* 子プロセスへの制御用 */ - int id; -} timerreg[TIMER_NUM]; +static int timer_init(struct interrupts *intp) +{ + intp->type = INTERRUPTS_TYPE_TIMER; + intp->checkintr = timer_checkintr; + intp->intr = timer_intr; + intp->command = timer_command; + intp->regs.timer->interrupt = intp; + return 0; +} -struct intrreg { - int read_fd; /* 子プロセスからの転送用 */ - int write_fd; /* 子プロセスへの転送用 */ - int cnt_fd; /* 子プロセスへの制御用 */ - int id; -} intrreg[INTERRUPT_NUM]; +static int cons_checkintr(struct interrupts *intp) +{ + return extintr_checkfd(intp->regs.cons->read_fd); +} -static struct timerreg *timerreg_search(int id) +static int cons_intr(struct interrupts *intp) { - int i; - struct timerreg *trp; + int size; + char *buffer; - if (id) { - for (i = 0; i < TIMER_NUM; i++) { - trp = &timerreg[i]; - if (trp->id == id) return trp; - } - } + buffer = kz_kmalloc(BUFFER_SIZE); + size = read(intp->regs.cons->read_fd, buffer, BUFFER_SIZE); + if ((size >= 0) && intp->id) + kz_send(intp->id, size, buffer); + else + kz_kmfree(buffer); - return NULL; + return 0; } -static struct intrreg *intrreg_search(int id) +static int cons_command(struct interrupts *intp, int id, int size, char *command) { - int i; - struct intrreg *irp; + switch (command[0]) { + case EXTINTR_CMD_CONSOLE_USE: /* コンソールの利用 */ + intp->id = id; + break; - if (id) { - for (i = 0; i < INTERRUPT_NUM; i++) { - irp = &intrreg[i]; - if (irp->id == id) return irp; - } - } + case EXTINTR_CMD_CONSOLE_ENABLE: + command[0] = EXTCONT_CMD_CONSOLE_ENABLE; + write(intp->regs.cons->cnt_fd, &command[0], 1); + break; - return NULL; -} + case EXTINTR_CMD_CONSOLE_DISABLE: + command[0] = EXTCONT_CMD_CONSOLE_DISABLE; + write(intp->regs.cons->cnt_fd, &command[0], 1); + break; -static int timerreg_init() -{ - int i; - struct timerreg *trp; + case EXTINTR_CMD_CONSOLE_WRITE: + write(intp->regs.cons->write_fd, &command[1], size - 1); + break; - for (i = 0; i < TIMER_NUM; i++) { - trp = &timerreg[i]; - memset(trp, 0, sizeof(*trp)); - trp->read_fd = -1; - trp->cnt_fd = -1; + default: + break; } return 0; } -static int intrreg_init() +static int cons_init(struct interrupts *intp) { - int i; - struct intrreg *irp; - - for (i = 0; i < INTERRUPT_NUM; i++) { - irp = &intrreg[i]; - memset(irp, 0, sizeof(*irp)); - irp->read_fd = -1; - irp->write_fd = -1; - irp->cnt_fd = -1; - irp->id = 0; - } - + intp->type = INTERRUPTS_TYPE_CONSOLE; + intp->checkintr = cons_checkintr; + intp->intr = cons_intr; + intp->command = cons_command; + intp->regs.cons->interrupt = intp; return 0; } -static int extintr_init() +static int extintr_intr_regist(struct interrupts *intp, void *regs, initfunc init) { - timerreg_init(); - intrreg_init(); + intp->regs.reg = regs; + init(intp); return 0; } -static void extintr_handler(int maxfd, fd_set *readfds) +static void extintr_handler() { - fd_set fds; - char *buffer; - int ret, size, i; - char c; - struct timeval tm = {0, 0}; - struct timerreg *trp; - struct intrreg *irp; - - fds = *readfds; - - ret = select(maxfd + 1, &fds, NULL, NULL, &tm); - if (ret > 0) { - for (i = 0; i < TIMER_NUM; i++) { - trp = &timerreg[i]; - if ((trp->read_fd >= 0) && FD_ISSET(trp->read_fd, &fds)) { - size = read(trp->read_fd, &c, 1); - if ((size >= 0) && trp->id) - kz_send(trp->id, 0, NULL); - } - } - for (i = 0; i < INTERRUPT_NUM; i++) { - irp = &intrreg[i]; - if ((irp->read_fd >= 0) && FD_ISSET(irp->read_fd, &fds)) { - - /* - * 現状ではスレッドからハンドラが呼ばれているのでシステムコールを - * 呼んでも問題は無いが,割り込みハンドラにした場合には - * システムコールを呼ぶと問題あるかも... - */ - buffer = kz_kmalloc(BUFFER_SIZE); - - size = read(irp->read_fd, buffer, BUFFER_SIZE); - if ((size >= 0) && irp->id) - kz_send(irp->id, size, buffer); - else - kz_kmfree(buffer); - } + int i; + struct interrupts *intp; + for (i = 0; i < EXTINTR_INTERRUPTS_NUM; i++) { + intp = &interrupts[i]; + if (intp->type == INTERRUPTS_TYPE_UNKNOWN) + continue; + if (intp->checkintr(intp)) { + intp->intr(intp); } } - return; } static int extintr_mainloop() { - int i, size, id; + int size, id; char *p; - struct timerreg *trp; - struct intrreg *irp; - int maxfd; - fd_set readfds; - - maxfd = -1; - FD_ZERO(&readfds); - - for (i = 0; i < TIMER_NUM; i++) { - trp = &timerreg[i]; - set_readfds(trp->read_fd, &maxfd, &readfds); - } - for (i = 0; i < INTERRUPT_NUM; i++) { - irp = &intrreg[i]; - set_readfds(irp->read_fd, &maxfd, &readfds); - } + struct interrupts *intp; while (1) { size = kz_recv(&id, &p); if (!id) { /* 子プロセスからの割り込み通知 */ - extintr_handler(maxfd, &readfds); + extintr_handler(); } else { + intp = NULL; switch (p[0]) { - case 't': /* タイマの利用 */ - trp = &timerreg[p[1] - '0']; - trp->id = id; - break; - - case 's': /* タイマ起動 */ - trp = timerreg_search(id); - write(trp->cnt_fd, &p[0], 9); - break; - - case 'm': /* タイマ割り込みのマスク */ - trp = timerreg_search(id); - write(trp->cnt_fd, &p[0], 1); + case EXTINTR_CMD_TIMER: + intp = timerreg[p[1] - '0'].interrupt; break; - - case 'u': /* コンソールの利用 */ - irp = &intrreg[p[1] - '0']; - irp->id = id; - break; - - case 'e': /* コンソール割り込み有効化 */ - case 'd': /* コンソール割り込み無効化 */ - irp = intrreg_search(id); - write(irp->cnt_fd, &p[0], 1); + case EXTINTR_CMD_CONSOLE: + intp = consreg[p[1] - '0'].interrupt; break; - - case 'w': /* 出力 */ - irp = intrreg_search(id); - write(irp->write_fd, &p[1], size - 1); - break; - default: break; } + if (intp) { + intp->command(intp, id, size - 2, p + 2); + } kz_kmfree(p); } @@ -630,102 +313,47 @@ { int i; int cnt_fildes[2]; - int timer_r_fildes[TIMER_NUM][2]; - int timer_cnt_fildes[TIMER_NUM][2]; - int intr_r_fildes[INTERRUPT_NUM][2]; - int intr_w_fildes[INTERRUPT_NUM][2]; - int intr_cnt_fildes[INTERRUPT_NUM][2]; - struct timerbuf *tbp; - struct timerreg *trp; - struct intrbuf *ibp; - struct intrreg *irp; + int timer_r_fildes[EXTINTR_TIMER_NUM][2]; + int timer_cnt_fildes[EXTINTR_TIMER_NUM][2]; + int cons_r_fildes[EXTINTR_CONSOLE_NUM][2]; + int cons_w_fildes[EXTINTR_CONSOLE_NUM][2]; + int cons_cnt_fildes[EXTINTR_CONSOLE_NUM][2]; + pid_t pid; pid = getpid(); pipe(cnt_fildes); - for (i = 0; i < TIMER_NUM; i++) { + for (i = 0; i < EXTINTR_TIMER_NUM; i++) { pipe(timer_r_fildes[i]); pipe(timer_cnt_fildes[i]); } - for (i = 0; i < INTERRUPT_NUM; i++) { - pipe(intr_r_fildes[i]); - pipe(intr_w_fildes[i]); - pipe(intr_cnt_fildes[i]); + for (i = 0; i < EXTINTR_CONSOLE_NUM; i++) { + pipe(cons_r_fildes[i]); + pipe(cons_w_fildes[i]); + pipe(cons_cnt_fildes[i]); } if (fork() == 0) { /* 子プロセス */ - /* - * 子プロセスはシグナル設定を引き継ぐらしいので,シグナル無効にする. - * (man sigaction に以下の記述あり) - * After a fork(2) or vfork(2) all signals, the signal mask, the signal - * stack, and the restart/interrupt flags are inherited by the child. - */ - sigprocmask(SIG_BLOCK, &block, NULL); - - controller_init(); - - close(cnt_fildes[1]); /* 書き込み端 */ - control_fd = cnt_fildes[0]; /* 読み込み端 */ - - for (i = 0; i < TIMER_NUM; i++) { - tbp = &timerbuf[i]; - - close(timer_r_fildes[i][0]); /* 読み込み端 */ - tbp->write_fd = timer_r_fildes[i][1]; /* 書き込み端 */ - - close(timer_cnt_fildes[i][1]); /* 書き込み端 */ - tbp->cnt_fd = timer_cnt_fildes[i][0]; /* 読み込み端 */ - } - - for (i = 0; i < INTERRUPT_NUM; i++) { - ibp = &intrbuf[i]; - - close(intr_r_fildes[i][0]); /* 読み込み端 */ - ibp->write_fd = intr_r_fildes[i][1]; /* 書き込み端 */ - - close(intr_w_fildes[i][1]); /* 書き込み端 */ - ibp->read_fd = intr_w_fildes[i][0]; /* 読み込み端 */ - - close(intr_cnt_fildes[i][1]); /* 書き込み端 */ - ibp->cnt_fd = intr_cnt_fildes[i][0]; /* 読み込み端 */ - } - - intr_controller(); - + extchild_main(pid, cnt_fildes, timer_r_fildes, timer_cnt_fildes, + cons_r_fildes, cons_w_fildes, cons_cnt_fildes); exit(0); } /* 親プロセス */ - extintr_init(); - - close(cnt_fildes[0]); /* 読み込み端 */ - control_intr_fd = cnt_fildes[1]; /* 書き込み端 */ - - kz_setsig(SIGHUP); + extregs_init(cnt_fildes, timer_r_fildes, timer_cnt_fildes, + cons_r_fildes, cons_w_fildes, cons_cnt_fildes); - for (i = 0; i < TIMER_NUM; i++) { - trp = &timerreg[i]; + interrupts_init(); - close(timer_r_fildes[i][1]); /* 書き込み端 */ - trp->read_fd = timer_r_fildes[i][0]; /* 読み込み端 */ - - close(timer_cnt_fildes[i][0]); /* 読み込み端 */ - trp->cnt_fd = timer_cnt_fildes[i][1]; /* 書き込み端 */ - } - - for (i = 0; i < INTERRUPT_NUM; i++) { - irp = &intrreg[i]; - - close(intr_r_fildes[i][1]); /* 書き込み端 */ - irp->read_fd = intr_r_fildes[i][0]; /* 読み込み端 */ - - close(intr_w_fildes[i][0]); /* 読み込み端 */ - irp->write_fd = intr_w_fildes[i][1]; /* 書き込み端 */ - - close(intr_cnt_fildes[i][0]); /* 読み込み端 */ - irp->cnt_fd = intr_cnt_fildes[i][1]; /* 書き込み端 */ - } + extintr_intr_regist(&interrupts[0], &timerreg[0], timer_init); + extintr_intr_regist(&interrupts[1], & consreg[0], cons_init); + extintr_intr_regist(&interrupts[2], &timerreg[1], timer_init); + extintr_intr_regist(&interrupts[3], & consreg[1], cons_init); + extintr_intr_regist(&interrupts[4], &timerreg[2], timer_init); + extintr_intr_regist(&interrupts[5], & consreg[2], cons_init); + extintr_intr_regist(&interrupts[6], &timerreg[3], timer_init); + extintr_intr_regist(&interrupts[7], & consreg[3], cons_init); extintr_mainloop(); diff -ruN kozos36/extintr.h kozos37/extintr.h --- kozos36/extintr.h Thu Jan 1 09:00:00 1970 +++ kozos37/extintr.h Mon Jan 26 21:33:41 2009 @@ -0,0 +1,37 @@ +#ifndef _KOZOS_EXTINTR_H_INCLUDED_ +#define _KOZOS_EXTINTR_H_INCLUDED_ + +#define EXTINTR_TIMER_NUM 4 +#define EXTINTR_CONSOLE_NUM 4 +#define EXTINTR_CONSOLE_SOCKET_PORT 12345 +#define EXTINTR_INTERRUPTS_NUM 8 + +#define EXTINTR_CMD_TIMER 't' +#define EXTINTR_CMD_CONSOLE 'c' + +#define EXTINTR_CMD_TIMER_USE 'u' +#define EXTINTR_CMD_TIMER_START 's' +#define EXTINTR_CMD_TIMER_MASK 'm' +#define EXTINTR_CMD_TIMER_UNMASK 'M' +#define EXTINTR_CMD_CONSOLE_USE 'u' +#define EXTINTR_CMD_CONSOLE_ENABLE 'e' +#define EXTINTR_CMD_CONSOLE_DISABLE 'd' +#define EXTINTR_CMD_CONSOLE_WRITE 'w' + +#define EXTCONT_CMD_CONTROL_DUMMY '0' +#define EXTCONT_CMD_TIMER_START 's' +#define EXTCONT_CMD_TIMER_MASK 'm' +#define EXTCONT_CMD_TIMER_UNMASK 'M' +#define EXTCONT_CMD_CONSOLE_ENABLE 'e' +#define EXTCONT_CMD_CONSOLE_DISABLE 'd' +#define EXTCONT_INT_TIMER_EXPIRE 'e' + +int extchild_main(int pid, + int cnt_fildes[2], + int timer_r_fildes[EXTINTR_TIMER_NUM][2], + int timer_cnt_fildes[EXTINTR_TIMER_NUM][2], + int cons_r_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_w_fildes[EXTINTR_CONSOLE_NUM][2], + int cons_cnt_fildes[EXTINTR_CONSOLE_NUM][2]); + +#endif diff -ruN kozos36/extsub.c kozos37/extsub.c --- kozos36/extsub.c Thu Jan 1 09:00:00 1970 +++ kozos37/extsub.c Mon Jan 26 21:35:34 2009 @@ -0,0 +1,46 @@ +#include +#include +#include + +#include "kozos.h" +#include "extintr.h" +#include "extsub.h" + +void extintr_set_readfds(int fd, int *maxfd, fd_set *fds) +{ + if (fd >= 0) { + FD_SET(fd, fds); + if (*maxfd < fd) *maxfd = fd; + } +} + +void extintr_reset_readfds(int fd, int *maxfd, fd_set *fds) +{ + if (fd >= 0) { + FD_CLR(fd, fds); + if ((*maxfd == fd) && (fd > 0)) *maxfd = fd - 1; + } +} + +int extintr_checkfd(int fd) +{ + fd_set fds; + int r; + struct timeval zero; + + if (fd < 0) return 0; + + FD_ZERO(&fds); + FD_SET(fd, &fds); + zero.tv_sec = 0; + zero.tv_usec = 0; + + r = select(fd + 1, &fds, NULL, NULL, &zero); + if (r > 0) { + if (FD_ISSET(fd, &fds)) { + return 1; + } + } + + return 0; +} diff -ruN kozos36/extsub.h kozos37/extsub.h --- kozos36/extsub.h Thu Jan 1 09:00:00 1970 +++ kozos37/extsub.h Thu Jan 22 23:09:09 2009 @@ -0,0 +1,8 @@ +#ifndef _KOZOS_EXTSUB_H_INCLUDED_ +#define _KOZOS_EXTSUB_H_INCLUDED_ + +void extintr_set_readfds(int fd, int *maxfd, fd_set *fds); +void extintr_reset_readfds(int fd, int *maxfd, fd_set *fds); +int extintr_checkfd(int fd); + +#endif diff -ruN kozos36/timerd.c kozos37/timerd.c --- kozos36/timerd.c Wed Jan 21 23:58:16 2009 +++ kozos37/timerd.c Fri Jan 23 22:04:58 2009 @@ -3,6 +3,9 @@ #include #include "kozos.h" +#include "extintr.h" + +#define TIMER_NO 3 int timerd_id; @@ -14,29 +17,32 @@ static timebuf *timers = NULL; -static void send_use(int num) +static void send_use() { char *p; - p = kz_kmalloc(2); - p[0] = 't'; - p[1] = '0' + num; - kz_send(extintr_id, 2, p); + p = kz_kmalloc(3); + p[0] = EXTINTR_CMD_TIMER; + p[1] = '0' + TIMER_NO; + p[2] = EXTINTR_CMD_TIMER_USE; + kz_send(extintr_id, 3, p); } static void send_enable(int sec, int msec) { char *p; - p = kz_kmalloc(9); - p[0] = 's'; - p[1] = '0' + ( sec / 100) % 10; - p[2] = '0' + ( sec / 10) % 10; - p[3] = '0' + sec % 10; - p[4] = ';'; - p[5] = '0' + (msec / 100) % 10; - p[6] = '0' + (msec / 10) % 10; - p[7] = '0' + msec % 10; - p[8] = ';'; - kz_send(extintr_id, 9, p); + p = kz_kmalloc(11); + p[ 0] = EXTINTR_CMD_TIMER; + p[ 1] = '0' + TIMER_NO; + p[ 2] = EXTINTR_CMD_TIMER_START; + p[ 3] = '0' + ( sec / 100) % 10; + p[ 4] = '0' + ( sec / 10) % 10; + p[ 5] = '0' + sec % 10; + p[ 6] = ';'; + p[ 7] = '0' + (msec / 100) % 10; + p[ 8] = '0' + (msec / 10) % 10; + p[ 9] = '0' + msec % 10; + p[10] = ';'; + kz_send(extintr_id, 11, p); } static struct timeval alarm_tm; @@ -103,21 +109,15 @@ int size, id, msec; char *p; - send_use(3); + send_use(); while (1) { size = kz_recv(&id, &p); if (p == NULL) { expire_timer(); } else { - switch (p[0]) { - case 's': /* タイマ設定 */ - msec = strtol(&p[1], NULL, 0); - set_timer(id, msec); - break; - default: - break; - } + msec = strtol(p, NULL, 0); + set_timer(id, msec); kz_kmfree(p); } }