@@ -1,10 +1,11 @@
1#include <stdlib.h>
1#include <stdlib.h>
2#include <stdio.h>
2#include <stdio.h>
3#include <string.h>
3#include <string.h>
5#include <stdarg.h>
4#include <stdarg.h>
6#include <assert.h>
5#include <assert.h>
7#include <pthread.h>
7#include <pthread.h>
9#include "idris_rts.h"
10#include "idris_rts.h"
10#include "idris_gc.h"
11#include "idris_gc.h"
@@ -30,7 +31,7 @@ VM* init_vm(int stack_size, size_t heap_size,
31 vm->ret = NULL;
32 vm->ret = NULL;
32 vm->reg1 = NULL;
33 vm->reg1 = NULL;
34 vm->inbox = malloc(1024*sizeof(VAL));
35 vm->inbox = malloc(1024*sizeof(VAL));
35 memset(vm->inbox, 0, 1024*sizeof(VAL));
36 memset(vm->inbox, 0, 1024*sizeof(VAL));
36 vm->inbox_end = vm->inbox + 1024;
37 vm->inbox_end = vm->inbox + 1024;
@@ -53,7 +54,7 @@ VM* init_vm(int stack_size, size_t heap_size,
54 vm->max_threads = max_threads;
55 vm->max_threads = max_threads;
55 vm->processes = 0;
56 vm->processes = 0;
57 STATS_LEAVE_INIT(vm->stats)
58 STATS_LEAVE_INIT(vm->stats)
58 return vm;
59 return vm;
@@ -61,14 +62,16 @@ VM* init_vm(int stack_size, size_t heap_size,
61Stats terminate(VM* vm) {
62Stats terminate(VM* vm) {
62 Stats stats = vm->stats;
63 Stats stats = vm->stats;
63 STATS_ENTER_EXIT(stats)
64 STATS_ENTER_EXIT(stats)
65 free(vm->inbox);
66 free(vm->inbox);
66 free(vm->valstack);
68 free(vm->valstack);
67 free_heap(&(vm->heap));
69 free_heap(&(vm->heap));
69 pthread_mutex_destroy(&(vm -> inbox_lock));
71 pthread_mutex_destroy(&(vm -> inbox_lock));
70 pthread_mutex_destroy(&(vm -> inbox_block));
72 pthread_mutex_destroy(&(vm -> inbox_block));
71 pthread_cond_destroy(&(vm -> inbox_waiting));
73 pthread_cond_destroy(&(vm -> inbox_waiting));
74 STATS_LEAVE_EXIT(stats)
77 STATS_LEAVE_EXIT(stats)
@@ -79,18 +82,21 @@ void idris_requireAlloc(VM* vm, size_t size) {
79 if (!(vm->heap.next + size < vm->heap.end)) {
82 if (!(vm->heap.next + size < vm->heap.end)) {
80 idris_gc(vm);
83 idris_gc(vm);
83 int lock = vm->processes > 0;
86 int lock = vm->processes > 0;
84 if (lock) { // We only need to lock if we're in concurrent mode
87 if (lock) { // We only need to lock if we're in concurrent mode
85 pthread_mutex_lock(&vm->alloc_lock);
88 pthread_mutex_lock(&vm->alloc_lock);
89void idris_doneAlloc(VM* vm) {
93void idris_doneAlloc(VM* vm) {
90 int lock = vm->processes > 0;
95 int lock = vm->processes > 0;
91 if (lock) { // We only need to lock if we're in concurrent mode
96 if (lock) { // We only need to lock if we're in concurrent mode
92 pthread_mutex_unlock(&vm->alloc_lock);
97 pthread_mutex_unlock(&vm->alloc_lock);
96int space(VM* vm, size_t size) {
102int space(VM* vm, size_t size) {
@@ -99,16 +105,18 @@ int space(VM* vm, size_t size) {
100void* allocate(VM* vm, size_t size, int outerlock) {
106void* allocate(VM* vm, size_t size, int outerlock) {
101// return malloc(size);
107// return malloc(size);
102 int lock = vm->processes > 0 && !outerlock;
109 int lock = vm->processes > 0 && !outerlock;
104 if (lock) { // not message passing
111 if (lock) { // not message passing
105 pthread_mutex_lock(&vm->alloc_lock);
112 pthread_mutex_lock(&vm->alloc_lock);
108 if ((size & 7)!=0) {
116 if ((size & 7)!=0) {
109 size = 8 + ((size >> 3) << 3);
117 size = 8 + ((size >> 3) << 3);
112 size_t chunk_size = size + sizeof(size_t);
120 size_t chunk_size = size + sizeof(size_t);
114 if (vm->heap.next + chunk_size < vm->heap.end) {
122 if (vm->heap.next + chunk_size < vm->heap.end) {
@@ -120,16 +128,19 @@ void* allocate(VM* vm, size_t size, int outerlock) {
120 assert(vm->heap.next <= vm->heap.end);
128 assert(vm->heap.next <= vm->heap.end);
122 memset(ptr, 0, size);
130 memset(ptr, 0, size);
123−
131+#ifdef HAS_PTHREAD
124 if (lock) { // not message passing
132 if (lock) { // not message passing
125 pthread_mutex_unlock(&vm->alloc_lock);
133 pthread_mutex_unlock(&vm->alloc_lock);
127 return ptr;
136 return ptr;
129 idris_gc(vm);
138 idris_gc(vm);
130 if (lock) { // not message passing
140 if (lock) { // not message passing
131 pthread_mutex_unlock(&vm->alloc_lock);
141 pthread_mutex_unlock(&vm->alloc_lock);
133 return allocate(vm, size, 0);
144 return allocate(vm, size, 0);
@@ -187,7 +198,7 @@ VAL MKPTR(VM* vm, void* ptr) {
187 return cl;
198 return cl;
190−VAL MKMPTR(VM* vm, void* ptr, int size) {
201+VAL MKMPTR(VM* vm, void* ptr, size_t size) {
191 Closure* cl = allocate(vm, sizeof(Closure) +
202 Closure* cl = allocate(vm, sizeof(Closure) +
192 sizeof(ManagedPtr) + size, 0);
203 sizeof(ManagedPtr) + size, 0);
193 SETTY(cl, MANAGEDPTR);
204 SETTY(cl, MANAGEDPTR);
@@ -222,7 +233,7 @@ VAL MKPTRc(VM* vm, void* ptr) {
222 return cl;
233 return cl;
225−VAL MKMPTRc(VM* vm, void* ptr, int size) {
236+VAL MKMPTRc(VM* vm, void* ptr, size_t size) {
226 Closure* cl = allocate(vm, sizeof(Closure) +
237 Closure* cl = allocate(vm, sizeof(Closure) +
227 sizeof(ManagedPtr) + size, 1);
238 sizeof(ManagedPtr) + size, 1);
228 SETTY(cl, MANAGEDPTR);
239 SETTY(cl, MANAGEDPTR);
@@ -760,6 +771,7 @@ typedef struct {
761} ThreadData;
772} ThreadData;
763void* runThread(void* arg) {
775void* runThread(void* arg) {
764 ThreadData* td = (ThreadData*)arg;
776 ThreadData* td = (ThreadData*)arg;
765 VM* vm = td->vm;
777 VM* vm = td->vm;
@@ -949,7 +961,7 @@ VAL idris_recvMessage(VM* vm) {
950 return msg;
962 return msg;
953int __idris_argc;
965int __idris_argc;
954char **__idris_argv;
966char **__idris_argv;