merge of 'a7f61676c8d04ecf082be8ae39a40b4e7bba3462'
and 'e36d05aec1b58ab05b8602bed8ed5faf304fe45f'
This commit is contained in:
@@ -140,7 +140,7 @@ void output_functions_action(struct hashentry *ptr)
|
|||||||
pad = (4 - (len % 4)) % 4;
|
pad = (4 - (len % 4)) % 4;
|
||||||
output_int(len+pad);
|
output_int(len+pad);
|
||||||
output_int(0); /* type */
|
output_int(0); /* type */
|
||||||
output_int(get_label(ptr->value) + 8);
|
output_int(get_label(ptr->value) + 28);
|
||||||
output_int(0); /* nargs */
|
output_int(0); /* nargs */
|
||||||
output_string(ptr->name);
|
output_string(ptr->name);
|
||||||
output_byte(0); /* terminator */
|
output_byte(0); /* terminator */
|
||||||
@@ -1267,6 +1267,7 @@ void output_code(void)
|
|||||||
if (!lookup_constant_string(x, &abiver)) \
|
if (!lookup_constant_string(x, &abiver)) \
|
||||||
printf("%s not defined\n", x); \
|
printf("%s not defined\n", x); \
|
||||||
output_int(abiver); \
|
output_int(abiver); \
|
||||||
|
printf("ABIVERSION(%s) = %x\n", x, abiver); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
pc = (pc + 3) & ~3; /* Align table */
|
pc = (pc + 3) & ~3; /* Align table */
|
||||||
|
|||||||
@@ -105,8 +105,10 @@ return return TOKRETURN;
|
|||||||
|
|
||||||
[0-9]+ yylval.Tinteger = atoi(yytext); return NUMBER;
|
[0-9]+ yylval.Tinteger = atoi(yytext); return NUMBER;
|
||||||
-[0-9]+ yylval.Tinteger = atoi(yytext); return NUMBER;
|
-[0-9]+ yylval.Tinteger = atoi(yytext); return NUMBER;
|
||||||
0x[0-9]+ yylval.Tinteger = strtol(yytext+2, (char **)NULL, 16); return NUMBER;
|
/* Cater for the possibility that things might be signed or
|
||||||
-0x[0-9]+ yylval.Tinteger = strtol(yytext+2, (char **)NULL, 16); return NUMBER;
|
unsigned. This is horrible and ugly, but might just work. */
|
||||||
|
0x[0-9a-fA-F]+ yylval.Tinteger = strtoul(yytext+2, (char **)NULL, 16); return NUMBER;
|
||||||
|
-0x[0-9a-fA-F]+ yylval.Tinteger = strtol(yytext+2, (char **)NULL, 16); return NUMBER;
|
||||||
[0-9]+\.[0-9]+ yylval.Treal = atof(yytext); return REAL;
|
[0-9]+\.[0-9]+ yylval.Treal = atof(yytext); return REAL;
|
||||||
-[0-9]+\.[0-9]+ yylval.Treal = atof(yytext); return REAL;
|
-[0-9]+\.[0-9]+ yylval.Treal = atof(yytext); return REAL;
|
||||||
[_a-zA-Z0-9]+ yylval.Tstring = strdup(yytext); return IDENTIFIER;
|
[_a-zA-Z0-9]+ yylval.Tstring = strdup(yytext); return IDENTIFIER;
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
PREFIX?= /usr/local
|
PREFIX?= /usr/local
|
||||||
|
|
||||||
OBJS= main.o vm.o plugins.o dmx.o midi.o beatdetect.o fft.o map3d.o mouse.o
|
OBJS= main.o vm.o plugins.o dmx.o midi.o beatdetect.o fft.o map3d.o mouse.o \
|
||||||
SRCS= main.c vm.c plugins.c dmx.c midi.c beatdetect.c fft.c map3d.c mouse.c
|
cmdsocket.o
|
||||||
|
SRCS= main.c vm.c plugins.c dmx.c midi.c beatdetect.c fft.c map3d.c mouse.c \
|
||||||
|
cmdsocket.c
|
||||||
|
|
||||||
OBJS+= abi.o
|
OBJS+= abi.o
|
||||||
SRCS+= abi.c
|
SRCS+= abi.c
|
||||||
|
|||||||
@@ -44,3 +44,7 @@ int vm_intfn_sin(void);
|
|||||||
int vm_intfn_cos(void);
|
int vm_intfn_cos(void);
|
||||||
int vm_intfn_random(void);
|
int vm_intfn_random(void);
|
||||||
int vm_intfn_mouse_read(void);
|
int vm_intfn_mouse_read(void);
|
||||||
|
int vm_intfn_cmdsocket_listen(void);
|
||||||
|
int vm_intfn_cmdsocket_accept(void);
|
||||||
|
int vm_intfn_cmdsocket_read(void);
|
||||||
|
int vm_intfn_cmdsocket_prefix(void);
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ function sin
|
|||||||
function cos
|
function cos
|
||||||
function random
|
function random
|
||||||
function mouse_read
|
function mouse_read
|
||||||
|
function cmdsocket_listen
|
||||||
|
function cmdsocket_accept
|
||||||
|
function cmdsocket_read
|
||||||
|
function cmdsocket_prefix
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ABI should be identified by a SHA1 hash of this file
|
* The ABI should be identified by a SHA1 hash of this file
|
||||||
|
|||||||
204
src/lsi/cmdsocket.c
Normal file
204
src/lsi/cmdsocket.c
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
/* cmdsocket.c */
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <dev/wscons/wsconsio.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
|
#define PORT 15674
|
||||||
|
#define CMD_MAXSIZE 1024
|
||||||
|
#define PREFIX_MAXSIZE 1024
|
||||||
|
|
||||||
|
#define CMDSOCKET_BANNER "lightscript cmdsocket ready\r\n"
|
||||||
|
|
||||||
|
int cmd_sock = 0;
|
||||||
|
int cmd_active = 0;
|
||||||
|
int cmd_ignore;
|
||||||
|
int cmd_bytes;
|
||||||
|
int cmdsocket_initialised = 0;
|
||||||
|
char cmd_buf[CMD_MAXSIZE];
|
||||||
|
char cmd_prefix[PREFIX_MAXSIZE];
|
||||||
|
|
||||||
|
int cmdsocket_init(void)
|
||||||
|
{
|
||||||
|
cmdsocket_initialised = 1;
|
||||||
|
cmd_bytes = 0;
|
||||||
|
cmd_ignore = 0;
|
||||||
|
cmd_prefix[0] = '\0';
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmdsocket_close(void)
|
||||||
|
{
|
||||||
|
if (cmd_active)
|
||||||
|
close(cmd_active);
|
||||||
|
if (cmd_sock)
|
||||||
|
close(cmd_sock);
|
||||||
|
cmdsocket_initialised = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmdsocket_prefix(char *prefix)
|
||||||
|
{
|
||||||
|
if (!cmdsocket_initialised)
|
||||||
|
return;
|
||||||
|
if (strlen(prefix) >= PREFIX_MAXSIZE-1)
|
||||||
|
return;
|
||||||
|
strncpy(cmd_prefix, prefix, PREFIX_MAXSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ERROR(x) do { warn((x)); goto error; } while (0)
|
||||||
|
|
||||||
|
#define BACKLOG 0
|
||||||
|
|
||||||
|
int cmdsocket_listen(int port) {
|
||||||
|
int sockopt_on = 1;
|
||||||
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
|
cmd_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (cmd_sock == -1)
|
||||||
|
ERROR("can't open socket");
|
||||||
|
if (setsockopt(cmd_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt_on,
|
||||||
|
sizeof(int)) == -1)
|
||||||
|
ERROR("can't set socket options");
|
||||||
|
memset((char *) &my_addr, 0, sizeof(my_addr));
|
||||||
|
my_addr.sin_family = PF_INET;
|
||||||
|
my_addr.sin_port = htons(port);
|
||||||
|
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
if (bind(cmd_sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
|
||||||
|
ERROR("can't bind socket");
|
||||||
|
if (listen(cmd_sock, BACKLOG) == -1)
|
||||||
|
ERROR("can't listen");
|
||||||
|
vm_register_signal_fd(cmd_sock, VM_CMDLISTENQ);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (cmd_sock)
|
||||||
|
close(cmd_sock);
|
||||||
|
cmd_sock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmdsocket_accept(void) {
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
socklen_t client_addr_size = sizeof(client_addr);
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (!cmdsocket_initialised)
|
||||||
|
return 0;
|
||||||
|
if (cmd_sock == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* We only accept one active connection at a time */
|
||||||
|
/* XXX can't just return here */
|
||||||
|
if (cmd_active)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
c = accept(cmd_sock, (struct sockaddr *)&client_addr,
|
||||||
|
&client_addr_size);
|
||||||
|
if (c == -1) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
return 0;
|
||||||
|
warn("Error accepting connection");
|
||||||
|
close(cmd_sock);
|
||||||
|
cmd_sock = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_active = c;
|
||||||
|
write(cmd_active, CMDSOCKET_BANNER, sizeof(CMDSOCKET_BANNER));
|
||||||
|
|
||||||
|
vm_register_signal_fd(cmd_active, VM_CMDREADQ);
|
||||||
|
vm_wakeup(VM_CMDREADQ);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_parse(char *cmd) {
|
||||||
|
char *sp;
|
||||||
|
int arg = 0;
|
||||||
|
char function[CMD_MAXSIZE + PREFIX_MAXSIZE];
|
||||||
|
|
||||||
|
*strchr(cmd, '\n') = '\0';
|
||||||
|
printf("DEBUG: Received command: %s\n", cmd);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
sp = strtok(cmd, " \t\r");
|
||||||
|
sp = strtok(NULL, " \t\r");
|
||||||
|
if (sp) {
|
||||||
|
arg = atoi(sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cmd_prefix is guaranteed to be terminated */
|
||||||
|
strcpy(function, cmd_prefix);
|
||||||
|
strncat(function, cmd, CMD_MAXSIZE);
|
||||||
|
|
||||||
|
printf("DEBUG: function: %s, arg %d\n", function, arg);
|
||||||
|
fflush(stdout);
|
||||||
|
if (vm_spawn_args(function, 1, arg)) {
|
||||||
|
/* Write an ack here, once a proper function exists */
|
||||||
|
} else {
|
||||||
|
/* Write an error, if it's possible. Don't worry about
|
||||||
|
missing characters and buffering for now, but we
|
||||||
|
should eventually */
|
||||||
|
write(cmd_active, "ERROR\n", strlen("ERROR\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Received command: %s\n", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmdsocket_read(void)
|
||||||
|
{
|
||||||
|
if (!cmdsocket_initialised)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int rv;
|
||||||
|
int left = sizeof(cmd_buf) - cmd_bytes;
|
||||||
|
char *p;
|
||||||
|
if (!cmd_active)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rv = recv(cmd_active, ((char *)&cmd_buf) + cmd_bytes, left, 0);
|
||||||
|
if (rv == -1) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
return 0;
|
||||||
|
printf("Error reading from socket\n");
|
||||||
|
vm_unregister_signal_fd(cmd_active);
|
||||||
|
close(cmd_active);
|
||||||
|
cmd_active = 0;
|
||||||
|
vm_wakeup(VM_CMDLISTENQ);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rv == 0) {
|
||||||
|
vm_unregister_signal_fd(cmd_active);
|
||||||
|
close(cmd_active);
|
||||||
|
cmd_active = 0;
|
||||||
|
vm_wakeup(VM_CMDLISTENQ);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cmd_bytes += rv;
|
||||||
|
if ((p = memchr(cmd_buf, '\n', cmd_bytes))) {
|
||||||
|
if (!cmd_ignore)
|
||||||
|
cmd_parse(cmd_buf);
|
||||||
|
memmove(cmd_buf, p+1, cmd_bytes - (p - cmd_buf - 1));
|
||||||
|
cmd_bytes = 0;
|
||||||
|
cmd_ignore = 0;
|
||||||
|
}
|
||||||
|
if (cmd_bytes == sizeof(cmd_buf)) {
|
||||||
|
cmd_bytes = 0;
|
||||||
|
cmd_ignore = 1;
|
||||||
|
/* Overflow */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/lsi/cmdsocket.h
Normal file
8
src/lsi/cmdsocket.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* cmdsocket.h */
|
||||||
|
|
||||||
|
int cmdsocket_init(void);
|
||||||
|
void cmdsocket_close(void);
|
||||||
|
int cmdsocket_listen(int port);
|
||||||
|
int cmdsocket_accept(void);
|
||||||
|
int cmdsocket_read(void);
|
||||||
|
int cmdsocket_prefix(char *);
|
||||||
@@ -55,6 +55,7 @@ int mouse_init(void)
|
|||||||
mouse_x = 0;
|
mouse_x = 0;
|
||||||
mouse_y = 0;
|
mouse_y = 0;
|
||||||
mouse_z = 0;
|
mouse_z = 0;
|
||||||
|
mouse_bytes = 0;
|
||||||
|
|
||||||
mouse_fd = open(MOUSEDEVICE, O_RDONLY);
|
mouse_fd = open(MOUSEDEVICE, O_RDONLY);
|
||||||
if (mouse_fd < 0) {
|
if (mouse_fd < 0) {
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
#include "dmx.h"
|
#include "dmx.h"
|
||||||
#include "beatdetect.h"
|
#include "beatdetect.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
#include "cmdsocket.h"
|
||||||
|
|
||||||
struct plugin plugins_table[] = {
|
struct plugin plugins_table[] = {
|
||||||
{"midi", midi_init, midi_close, 0},
|
{"midi", midi_init, midi_close, 0},
|
||||||
{"dmx", dmx_init, dmx_close, 0},
|
{"dmx", dmx_init, dmx_close, 0},
|
||||||
{"beatdetect", beatdetect_init, beatdetect_close, 0},
|
{"beatdetect", beatdetect_init, beatdetect_close, 0},
|
||||||
{"mouse", mouse_init, mouse_close, 0},
|
{"mouse", mouse_init, mouse_close, 0},
|
||||||
|
{"cmdsocket", cmdsocket_init, cmdsocket_close, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
int nplugins = (sizeof(plugins_table) / sizeof(struct plugin));
|
int nplugins = (sizeof(plugins_table) / sizeof(struct plugin));
|
||||||
|
|||||||
102
src/lsi/vm.c
102
src/lsi/vm.c
@@ -11,6 +11,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "code.h"
|
#include "code.h"
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
#include "beatdetect.h"
|
#include "beatdetect.h"
|
||||||
#include "map3d.h"
|
#include "map3d.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
|
#include "cmdsocket.h"
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
@@ -41,6 +43,9 @@ struct vm_thread {
|
|||||||
|
|
||||||
#define ARRAYBLOCKSIZE 512
|
#define ARRAYBLOCKSIZE 512
|
||||||
|
|
||||||
|
#define SLEEPTIME_SEC 60
|
||||||
|
#define SLEEPTIME_NSEC 0
|
||||||
|
|
||||||
struct pollfd vm_pollfd[VM_MAXPOLLFD];
|
struct pollfd vm_pollfd[VM_MAXPOLLFD];
|
||||||
int vm_pollfdqueue[VM_MAXPOLLFD];
|
int vm_pollfdqueue[VM_MAXPOLLFD];
|
||||||
|
|
||||||
@@ -55,6 +60,7 @@ struct vm_thread *vm_current = NULL;
|
|||||||
|
|
||||||
instr *vm_codearea = NULL;
|
instr *vm_codearea = NULL;
|
||||||
size_t vm_codesize = 0;
|
size_t vm_codesize = 0;
|
||||||
|
int vm_threads = 0;
|
||||||
|
|
||||||
struct hashentry *fnhash[HASHSIZE];
|
struct hashentry *fnhash[HASHSIZE];
|
||||||
struct hashentry *globhash[HASHSIZE];
|
struct hashentry *globhash[HASHSIZE];
|
||||||
@@ -418,6 +424,46 @@ int vm_intfn_mouse_read(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vm_intfn_cmdsocket_listen(void)
|
||||||
|
{
|
||||||
|
stack_poke(vm_current, 0,
|
||||||
|
cmdsocket_listen(stack_get(vm_current, 1)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vm_intfn_cmdsocket_prefix(void)
|
||||||
|
{
|
||||||
|
char buf[VM_STRING_MAX];
|
||||||
|
int len = stack_get(vm_current, 1);
|
||||||
|
|
||||||
|
strncpy(buf, stack_getstr(vm_current, len, 1), len);
|
||||||
|
buf[len] = '\0';
|
||||||
|
|
||||||
|
cmdsocket_prefix(buf);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vm_intfn_cmdsocket_accept(void)
|
||||||
|
{
|
||||||
|
if (!cmdsocket_accept()) {
|
||||||
|
vm_queue(vm_current, VM_CMDLISTENQ);
|
||||||
|
vm_current = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vm_intfn_cmdsocket_read(void)
|
||||||
|
{
|
||||||
|
if (!cmdsocket_read()) {
|
||||||
|
vm_queue(vm_current, VM_CMDREADQ);
|
||||||
|
vm_current = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int vm_intfn_beatdetect_read(void)
|
int vm_intfn_beatdetect_read(void)
|
||||||
{
|
{
|
||||||
if (!beatdetect_read()) {
|
if (!beatdetect_read()) {
|
||||||
@@ -570,6 +616,7 @@ void vm_init(void)
|
|||||||
vm_npollfds = 0;
|
vm_npollfds = 0;
|
||||||
vm_caughtsignal = 0;
|
vm_caughtsignal = 0;
|
||||||
signal(SIGIO, vm_sighandler);
|
signal(SIGIO, vm_sighandler);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_load_file(char *filename)
|
void vm_load_file(char *filename)
|
||||||
@@ -673,10 +720,11 @@ void vm_queue(struct vm_thread *thread, int queue)
|
|||||||
vm_queues[queue] = thread;
|
vm_queues[queue] = thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vm_spawn(char *fn)
|
int vm_spawn_args(char *fn, int n, ...)
|
||||||
{
|
{
|
||||||
struct vm_thread *newt;
|
struct vm_thread *newt;
|
||||||
struct hashentry *ptr;
|
struct hashentry *ptr;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
ptr = hash_lookup(fnhash, fn, 0);
|
ptr = hash_lookup(fnhash, fn, 0);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
@@ -705,6 +753,12 @@ int vm_spawn(char *fn)
|
|||||||
/* Push return address here, to point to some special thread exit
|
/* Push return address here, to point to some special thread exit
|
||||||
routine */
|
routine */
|
||||||
|
|
||||||
|
/* Push optional arguments */
|
||||||
|
va_start(ap, n);
|
||||||
|
while (n--)
|
||||||
|
stack_push(newt, va_arg(ap, int));
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
stack_push(newt, 0); /* Return value */
|
stack_push(newt, 0); /* Return value */
|
||||||
stack_push(newt, 0); /* Return address */
|
stack_push(newt, 0); /* Return address */
|
||||||
|
|
||||||
@@ -712,15 +766,26 @@ int vm_spawn(char *fn)
|
|||||||
newt->prev = NULL;
|
newt->prev = NULL;
|
||||||
newt->queue = VM_NOQUEUE;
|
newt->queue = VM_NOQUEUE;
|
||||||
vm_queue(newt, VM_RUNQ);
|
vm_queue(newt, VM_RUNQ);
|
||||||
|
vm_threads++;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vm_spawn(char *fn)
|
||||||
|
{
|
||||||
|
return vm_spawn_args(fn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void vm_destroy(struct vm_thread *thread)
|
void vm_destroy(struct vm_thread *thread)
|
||||||
{
|
{
|
||||||
vm_unqueue(thread);
|
vm_unqueue(thread);
|
||||||
free(thread->stackbase);
|
free(thread->stackbase);
|
||||||
free(thread);
|
free(thread);
|
||||||
|
vm_threads--;
|
||||||
|
if (vm_threads == 0) {
|
||||||
|
printf("No threads left\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int vm_runnable(struct vm_thread *thread)
|
int vm_runnable(struct vm_thread *thread)
|
||||||
@@ -757,18 +822,19 @@ void vm_sched(void)
|
|||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (vm_queues[VM_TIMEQ] == NULL) {
|
|
||||||
printf("No runnable thread, and no waiting thread\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
// printf("No runnable thread - sleeping\n");
|
// printf("No runnable thread - sleeping\n");
|
||||||
gettimeofday(&tv, NULL);
|
if (vm_queues[VM_TIMEQ]) {
|
||||||
timersub(&vm_queues[VM_TIMEQ]->time, &tv, &tv);
|
gettimeofday(&tv, NULL);
|
||||||
if ((tv.tv_sec < 0) || (tv.tv_usec < 0)) {
|
timersub(&vm_queues[VM_TIMEQ]->time, &tv, &tv);
|
||||||
tv.tv_sec = 0;
|
if ((tv.tv_sec < 0) || (tv.tv_usec < 0)) {
|
||||||
tv.tv_usec = 0;
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
}
|
||||||
|
TIMEVAL_TO_TIMESPEC(&tv, &ts);
|
||||||
|
} else {
|
||||||
|
ts.tv_sec = SLEEPTIME_SEC;
|
||||||
|
ts.tv_nsec = SLEEPTIME_NSEC;
|
||||||
}
|
}
|
||||||
TIMEVAL_TO_TIMESPEC(&tv, &ts);
|
|
||||||
// nanosleep(&ts, NULL);
|
// nanosleep(&ts, NULL);
|
||||||
rv = pollts(vm_pollfd, vm_npollfds, &ts, NULL);
|
rv = pollts(vm_pollfd, vm_npollfds, &ts, NULL);
|
||||||
if ((rv == -1) && (errno != EINTR))
|
if ((rv == -1) && (errno != EINTR))
|
||||||
@@ -791,6 +857,20 @@ void vm_register_signal_fd(int fd, int queue)
|
|||||||
rv = fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC);
|
rv = fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vm_unregister_signal_fd(int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < vm_npollfds; i++) {
|
||||||
|
if (fd == vm_pollfd[i].fd) {
|
||||||
|
memmove(&vm_pollfd[i], &vm_pollfd[i+1],
|
||||||
|
sizeof(struct pollfd) * (vm_npollfds-i-1));
|
||||||
|
vm_npollfds--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void stack_push(struct vm_thread *thread, stkentry e)
|
void stack_push(struct vm_thread *thread, stkentry e)
|
||||||
{
|
{
|
||||||
thread->sp++;
|
thread->sp++;
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
void vm_init(void);
|
void vm_init(void);
|
||||||
void vm_load(char *);
|
void vm_load(char *);
|
||||||
int vm_spawn(char *);
|
int vm_spawn(char *);
|
||||||
|
int vm_spawn_args(char *, int, ...);
|
||||||
void vm_run(void);
|
void vm_run(void);
|
||||||
void vm_register_signal_fd(int /* fd */, int /* queue */);
|
void vm_register_signal_fd(int /* fd */, int /* queue */);
|
||||||
|
void vm_unregister_signal_fd(int /* fd */);
|
||||||
|
void vm_wakeup(int queue);
|
||||||
|
|
||||||
#define VM_MAXQUEUES 512
|
#define VM_MAXQUEUES 512
|
||||||
#define VM_RUNQ 0
|
#define VM_RUNQ 0
|
||||||
@@ -13,8 +16,9 @@ void vm_register_signal_fd(int /* fd */, int /* queue */);
|
|||||||
#define VM_MOUSEQ 6
|
#define VM_MOUSEQ 6
|
||||||
#define VM_BEATQ 7
|
#define VM_BEATQ 7
|
||||||
#define VM_MIDIQ 8
|
#define VM_MIDIQ 8
|
||||||
#define VM_SOCKQ 9
|
#define VM_CMDLISTENQ 9
|
||||||
|
#define VM_CMDREADQ 10
|
||||||
|
|
||||||
#define VM_USERQMIN 10
|
#define VM_USERQMIN 20
|
||||||
#define VM_NOQUEUE (-1)
|
#define VM_NOQUEUE (-1)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user