on master help sign in
modify RTS so that it can be built single-threaded if pthreads are not available.
c399b55stepcut
config.mk+1
@@ -36,3 +36,4 @@ else
36endif
36endif
37endif
37endif
38
38
39+#define HAS_PTHREAD
rts/idris_gc.c+2−1
@@ -111,10 +111,11 @@ void idris_gc(VM* vm) {
111 for(root = vm->valstack; root < vm->valstack_top; ++root) {
111 for(root = vm->valstack; root < vm->valstack_top; ++root) {
112 *root = copy(vm, *root);
112 *root = copy(vm, *root);
113 }
113 }
114+#ifdef HAS_PTHREAD
114 for(root = vm->inbox_ptr; root < vm->inbox_write; ++root) {
115 for(root = vm->inbox_ptr; root < vm->inbox_write; ++root) {
115 *root = copy(vm, *root);
116 *root = copy(vm, *root);
116 }
117 }
117−
118+#endif
118 vm->ret = copy(vm, vm->ret);
119 vm->ret = copy(vm, vm->ret);
119 vm->reg1 = copy(vm, vm->reg1);
120 vm->reg1 = copy(vm, vm->reg1);
120
121
rts/idris_rts.c+21−8
@@ -4,7 +4,9 @@
4#include <unistd.h>
4#include <unistd.h>
5#include <stdarg.h>
5#include <stdarg.h>
6#include <assert.h>
6#include <assert.h>
7+#ifdef HAS_PTHREAD
7#include <pthread.h>
8#include <pthread.h>
9+#endif
8
10
9#include "idris_rts.h"
11#include "idris_rts.h"
10#include "idris_gc.h"
12#include "idris_gc.h"
@@ -30,7 +32,7 @@ VM* init_vm(int stack_size, size_t heap_size,
30
32
31 vm->ret = NULL;
33 vm->ret = NULL;
32 vm->reg1 = NULL;
34 vm->reg1 = NULL;
33−
35+#ifdef HAS_PTHREAD
34 vm->inbox = malloc(1024*sizeof(VAL));
36 vm->inbox = malloc(1024*sizeof(VAL));
35 memset(vm->inbox, 0, 1024*sizeof(VAL));
37 memset(vm->inbox, 0, 1024*sizeof(VAL));
36 vm->inbox_end = vm->inbox + 1024;
38 vm->inbox_end = vm->inbox + 1024;
@@ -44,7 +46,7 @@ VM* init_vm(int stack_size, size_t heap_size,
44
46
45 vm->max_threads = max_threads;
47 vm->max_threads = max_threads;
46 vm->processes = 0;
48 vm->processes = 0;
47−
49+#endif
48 STATS_LEAVE_INIT(vm->stats)
50 STATS_LEAVE_INIT(vm->stats)
49 return vm;
51 return vm;
50}
52}
@@ -52,14 +54,16 @@ VM* init_vm(int stack_size, size_t heap_size,
52Stats terminate(VM* vm) {
54Stats terminate(VM* vm) {
53 Stats stats = vm->stats;
55 Stats stats = vm->stats;
54 STATS_ENTER_EXIT(stats)
56 STATS_ENTER_EXIT(stats)
55−
57+#ifdef HAS_PTHREAD
56 free(vm->inbox);
58 free(vm->inbox);
59+#endif
57 free(vm->valstack);
60 free(vm->valstack);
58 free_heap(&(vm->heap));
61 free_heap(&(vm->heap));
59−
62+#ifdef HAS_PTHREAD
60 pthread_mutex_destroy(&(vm -> inbox_lock));
63 pthread_mutex_destroy(&(vm -> inbox_lock));
61 pthread_mutex_destroy(&(vm -> inbox_block));
64 pthread_mutex_destroy(&(vm -> inbox_block));
62 pthread_cond_destroy(&(vm -> inbox_waiting));
65 pthread_cond_destroy(&(vm -> inbox_waiting));
66+#endif
63 free(vm);
67 free(vm);
64
68
65 STATS_LEAVE_EXIT(stats)
69 STATS_LEAVE_EXIT(stats)
@@ -70,18 +74,21 @@ void idris_requireAlloc(VM* vm, size_t size) {
70 if (!(vm->heap.next + size < vm->heap.end)) {
74 if (!(vm->heap.next + size < vm->heap.end)) {
71 idris_gc(vm);
75 idris_gc(vm);
72 }
76 }
73−
77+#ifdef HAS_PTHREAD
74 int lock = vm->processes > 0;
78 int lock = vm->processes > 0;
75 if (lock) { // not message passing
79 if (lock) { // not message passing
76 pthread_mutex_lock(&vm->alloc_lock);
80 pthread_mutex_lock(&vm->alloc_lock);
77 }
81 }
82+#endif
78}
83}
79
84
80void idris_doneAlloc(VM* vm) {
85void idris_doneAlloc(VM* vm) {
86+#ifdef HAS_PTHREAD
81 int lock = vm->processes > 0;
87 int lock = vm->processes > 0;
82 if (lock) { // not message passing
88 if (lock) { // not message passing
83 pthread_mutex_unlock(&vm->alloc_lock);
89 pthread_mutex_unlock(&vm->alloc_lock);
84 }
90 }
91+#endif
85}
92}
86
93
87int space(VM* vm, size_t size) {
94int space(VM* vm, size_t size) {
@@ -90,16 +97,18 @@ int space(VM* vm, size_t size) {
90
97
91void* allocate(VM* vm, size_t size, int outerlock) {
98void* allocate(VM* vm, size_t size, int outerlock) {
92// return malloc(size);
99// return malloc(size);
100+#ifdef HAS_PTHREAD
93 int lock = vm->processes > 0 && !outerlock;
101 int lock = vm->processes > 0 && !outerlock;
94
102
95 if (lock) { // not message passing
103 if (lock) { // not message passing
96 pthread_mutex_lock(&vm->alloc_lock);
104 pthread_mutex_lock(&vm->alloc_lock);
97 }
105 }
106+#endif
98
107
99 if ((size & 7)!=0) {
108 if ((size & 7)!=0) {
100 size = 8 + ((size >> 3) << 3);
109 size = 8 + ((size >> 3) << 3);
101 }
110 }
102−
111+
103 size_t chunk_size = size + sizeof(size_t);
112 size_t chunk_size = size + sizeof(size_t);
104
113
105 if (vm->heap.next + chunk_size < vm->heap.end) {
114 if (vm->heap.next + chunk_size < vm->heap.end) {
@@ -111,16 +120,19 @@ void* allocate(VM* vm, size_t size, int outerlock) {
111 assert(vm->heap.next <= vm->heap.end);
120 assert(vm->heap.next <= vm->heap.end);
112
121
113 memset(ptr, 0, size);
122 memset(ptr, 0, size);
114−
123+#ifdef HAS_PTHREAD
115 if (lock) { // not message passing
124 if (lock) { // not message passing
116 pthread_mutex_unlock(&vm->alloc_lock);
125 pthread_mutex_unlock(&vm->alloc_lock);
117 }
126 }
127+#endif
118 return ptr;
128 return ptr;
119 } else {
129 } else {
120 idris_gc(vm);
130 idris_gc(vm);
131+#ifdef HAS_PTHREAD
121 if (lock) { // not message passing
132 if (lock) { // not message passing
122 pthread_mutex_unlock(&vm->alloc_lock);
133 pthread_mutex_unlock(&vm->alloc_lock);
123 }
134 }
135+#endif
124 return allocate(vm, size, 0);
136 return allocate(vm, size, 0);
125 }
137 }
126
138
@@ -738,6 +750,7 @@ typedef struct {
738 VAL arg;
750 VAL arg;
739} ThreadData;
751} ThreadData;
740
752
753+#ifdef HAS_PTHREAD
741void* runThread(void* arg) {
754void* runThread(void* arg) {
742 ThreadData* td = (ThreadData*)arg;
755 ThreadData* td = (ThreadData*)arg;
743 VM* vm = td->vm;
756 VM* vm = td->vm;
@@ -927,7 +940,7 @@ VAL idris_recvMessage(VM* vm) {
927
940
928 return msg;
941 return msg;
929}
942}
930−
943+#endif
931int __idris_argc;
944int __idris_argc;
932char **__idris_argv;
945char **__idris_argv;
933
946
rts/idris_rts.h+9−2
@@ -6,7 +6,9 @@
6#include <string.h>
6#include <string.h>
7#include <unistd.h>
7#include <unistd.h>
8#include <stdarg.h>
8#include <stdarg.h>
9+#ifdef HAS_PTHREAD
9#include <pthread.h>
10#include <pthread.h>
11+#endif
10#include <stdint.h>
12#include <stdint.h>
11
13
12#include "idris_heap.h"
14#include "idris_heap.h"
@@ -66,6 +68,11 @@ typedef struct Closure {
66 } info;
68 } info;
67} Closure;
69} Closure;
68
70
71+#if HAS_PTHREAD
72+typedef void* pthread_mutex_t;
73+typedef void* pthread_cond_t;
74+#endif
75+
69typedef struct {
76typedef struct {
70 VAL* valstack;
77 VAL* valstack;
71 VAL* valstack_top;
78 VAL* valstack_top;
@@ -73,7 +80,7 @@ typedef struct {
73 VAL* stack_max;
80 VAL* stack_max;
74
81
75 Heap heap;
82 Heap heap;
76−
83+#ifdef HAS_PTHREAD
77 pthread_mutex_t inbox_lock;
84 pthread_mutex_t inbox_lock;
78 pthread_mutex_t inbox_block;
85 pthread_mutex_t inbox_block;
79 pthread_mutex_t alloc_lock;
86 pthread_mutex_t alloc_lock;
@@ -87,7 +94,7 @@ typedef struct {
87
94
88 int processes; // Number of child processes
95 int processes; // Number of child processes
89 int max_threads; // maximum number of threads to run in parallel
96 int max_threads; // maximum number of threads to run in parallel
90−
97+#endif
91 Stats stats;
98 Stats stats;
92
99
93 VAL ret;
100 VAL ret;