@@ -3,6 +3,8 @@
3#include <string.h>
3#include <string.h>
4#include <unistd.h>
4#include <unistd.h>
5#include <stdarg.h>
5#include <stdarg.h>
7#include "idris_rts.h"
9#include "idris_rts.h"
8#include "idris_gc.h"
10#include "idris_gc.h"
@@ -31,9 +33,32 @@ VM* init_vm(int stack_size, size_t heap_size) {
31 vm -> heap_growth = heap_size;
33 vm -> heap_growth = heap_size;
32 vm -> ret = NULL;
34 vm -> ret = NULL;
33 vm -> reg1 = NULL;
35 vm -> reg1 = NULL;
37+ vm -> inbox = malloc(1024*sizeof(VAL));
38+ vm -> inbox_end = vm -> inbox + 1024;
39+ vm -> inbox_ptr = vm -> inbox;
40+ vm -> inbox_write = vm -> inbox;
42+ pthread_mutex_init(&(vm -> inbox_lock), NULL);
43+ pthread_mutex_init(&(vm -> inbox_block), NULL);
44+ pthread_cond_init(&(vm -> inbox_waiting), NULL);
34 return vm;
46 return vm;
49+void terminate(VM* vm) {
53+ free(vm->floatstack);
55+ if (vm->oldheap != NULL) { free(vm->oldheap); }
56+ pthread_mutex_destroy(&(vm -> inbox_lock));
57+ pthread_mutex_destroy(&(vm -> inbox_block));
58+ pthread_cond_destroy(&(vm -> inbox_waiting));
37void* allocate(VM* vm, size_t size) {
62void* allocate(VM* vm, size_t size) {
38// return malloc(size);
63// return malloc(size);
39 if ((size & 7)!=0) {
64 if ((size & 7)!=0) {
@@ -305,6 +330,136 @@ VAL idris_strRev(VM* vm, VAL str) {
305 return cl;
330 return cl;
339+void* runThread(void* arg) {
340+ ThreadData* td = (ThreadData*)arg;
343+ printf("We're off\n");
350+ printf("We're done\n");
354+void* vmThread(VM* callvm, func f, VAL arg) {
355+ VM* vm = init_vm(callvm->stack_max - callvm->valstack, callvm->heap_size);
357+ pthread_attr_t attr;
360+ pthread_attr_init(&attr);
361+ pthread_attr_getstacksize (&attr, &stacksize);
362+ pthread_attr_setstacksize (&attr, stacksize*64);
363+ printf("Default stack size = %li\n", stacksize);
365+ ThreadData *td = malloc(sizeof(ThreadData));
368+ td->arg = copyTo(vm, arg);
373+ printf("Threading\n");
374+ pthread_create(&t, &attr, runThread, td);
378+// VM is assumed to be a different vm from the one x lives on (so we don't need
379+// to worry about gc moving things, as the VM x is on will not be allocating)
381+VAL copyTo(VM* vm, VAL x) {
385+ if (x==NULL || ISINT(x)) {
390+ cl = allocCon(vm, x->info.c.arity);
391+ cl->info.c.tag = x->info.c.tag;
392+ cl->info.c.arity = x->info.c.arity;
394+ argptr = (VAL*)(cl->info.c.args);
395+ for(i = 0; i < x->info.c.arity; ++i) {
396+ *argptr = copyTo(vm, *((VAL*)(x->info.c.args)+i)); // recursive version
401+ cl = MKFLOAT(vm, x->info.f);
404+ cl = MKSTR(vm, x->info.str);
407+ cl = MKBIGM(vm, x->info.ptr);
410+ cl = MKPTR(vm, x->info.ptr);
413+ assert(0); // We're in trouble if this happens...
419+// Add a message to another VM's message queue
420+void sendMessage(VM* sender, VM* dest, VAL msg) {
421+ VAL dmsg = copyTo(dest, msg);
422+ pthread_mutex_lock(&(dest->inbox_lock));
424+ *(dest->inbox_write) = dmsg;
426+ dest->inbox_write++;
427+ if (dest->inbox_write >= dest->inbox_end) {
428+ dest->inbox_write = dest->inbox;
431+ if (dest->inbox_write == dest->inbox_ptr) {
432+ fprintf(stderr, "Inbox full"); // Maybe grow it instead...
436+ // Wake up the other thread
437+ pthread_cond_signal(&(dest->inbox_waiting));
439+ pthread_mutex_unlock(&(dest->inbox_lock));
442+// block until there is a message in the queue
443+VAL recvMessage(VM* vm) {
444+ pthread_mutex_lock(&vm->inbox_block);
445+ pthread_cond_wait(&vm->inbox_waiting, &vm->inbox_block);
447+ VAL msg = *(vm->inbox_ptr);
449+ pthread_mutex_lock(&(vm->inbox_lock));
450+ *(vm->inbox_ptr) = NULL;
452+ if (vm->inbox_ptr >= vm->inbox_end) {
453+ vm->inbox_ptr = vm->inbox;
455+ pthread_mutex_unlock(&(vm->inbox_lock));
457+ fprintf(stderr, "No messages waiting");
461+ pthread_mutex_unlock(&vm->inbox_block);
309void stackOverflow() {
464void stackOverflow() {
310 fprintf(stderr, "Stack overflow");
465 fprintf(stderr, "Stack overflow");