Merge branch 'thread-params-dev'

This commit is contained in:
Justin Ethier 2017-03-16 20:50:23 +00:00
commit 4834981ba2
8 changed files with 143 additions and 8 deletions

15
atomics.sld Normal file
View file

@ -0,0 +1,15 @@
(define-library (atomics)
(export
atomic:get
atomic:set!
)
(include-c-header "<ck_pr.h>")
(begin
;TODO: won't work, ints are immutable
;(define-c atomic:fx++
; "(void *data, int argc, closure _, object k, object num)"
; " Cyc_check_fixnum(data, num);
; ck_pr_add_ptr(&num, 2);
; return_closcall1(data, k, num); ")
))

View file

@ -1,4 +1,8 @@
;; A simple program demonstrating how parameter objects interact with threads ;; A simple program demonstrating how parameter objects interact with threads
;;
;; Note this is poor code as it uses timing via sleeps instead of proper
;; thread synchronization!!!
;;
(import (scheme base) (import (scheme base)
(scheme read) (scheme read)
(scheme write) (scheme write)
@ -8,18 +12,20 @@
(thread-start! (thread-start!
(make-thread (make-thread
(lambda () (lambda ()
(thread-sleep! 1000) (thread-sleep! 1200)
(display "started thread, this should be written to console") (display "started thread, this should be written to console")
(newline) (newline)
(display "thread done") (display "thread done")
(newline)))) (newline)
(flush-output-port (current-output-port)))))
(thread-sleep! 1000) ;; Prevent race condition replacing stdout before thread is spawned
(write `(1 2 3)) (write `(1 2 3))
(define fp (open-output-file "tmp.txt")) (define fp (open-output-file "tmp.txt"))
(parameterize (parameterize
((current-output-port fp)) ((current-output-port fp))
(write `(4 5 6)) (write `(4 5 6))
(thread-sleep! 5000) (thread-sleep! 3000)
) )
(close-port fp) (close-port fp)
(write `(7 8 9)) (write `(7 8 9))

16
gc.c
View file

@ -1307,6 +1307,12 @@ void gc_mut_cooperate(gc_thread_data * thd, int buf_len)
if (thd->scm_thread_obj) { if (thd->scm_thread_obj) {
gc_mark_gray(thd, thd->scm_thread_obj); gc_mark_gray(thd, thd->scm_thread_obj);
} }
if (thd->exception_handler_stack) {
gc_mark_gray(thd, thd->exception_handler_stack);
}
if (thd->param_objs) {
gc_mark_gray(thd, thd->param_objs);
}
// Also, mark everything the collector moved to the heap // Also, mark everything the collector moved to the heap
for (i = 0; i < buf_len; i++) { for (i = 0; i < buf_len; i++) {
gc_mark_gray(thd, thd->moveBuf[i]); gc_mark_gray(thd, thd->moveBuf[i]);
@ -1690,6 +1696,15 @@ void gc_wait_handshake()
//for (i = 0; i < m->gc_num_args; i++) { //for (i = 0; i < m->gc_num_args; i++) {
// gc_mark_gray(m, m->gc_args[i]); // gc_mark_gray(m, m->gc_args[i]);
//} //}
if (m->scm_thread_obj) {
gc_mark_gray(m, m->scm_thread_obj);
}
if (m->exception_handler_stack) {
gc_mark_gray(m, m->exception_handler_stack);
}
if (m->param_objs) {
gc_mark_gray(m, m->param_objs);
}
// Also, mark everything the collector moved to the heap // Also, mark everything the collector moved to the heap
for (i = 0; i < buf_len; i++) { for (i = 0; i < buf_len; i++) {
gc_mark_gray(m, m->moveBuf[i]); gc_mark_gray(m, m->moveBuf[i]);
@ -1883,6 +1898,7 @@ void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base,
thd->mutation_count = 0; thd->mutation_count = 0;
thd->mutations = thd->mutations =
vpbuffer_realloc(thd->mutations, &(thd->mutation_buflen)); vpbuffer_realloc(thd->mutations, &(thd->mutation_buflen));
thd->param_objs = NULL;
thd->exception_handler_stack = NULL; thd->exception_handler_stack = NULL;
thd->scm_thread_obj = NULL; thd->scm_thread_obj = NULL;
thd->thread_state = CYC_THREAD_STATE_NEW; thd->thread_state = CYC_THREAD_STATE_NEW;

View file

@ -73,6 +73,7 @@ void gc_init_heap(long heap_size);
#define Cyc_check_pair(d,obj) Cyc_check_type(d,Cyc_is_pair, pair_tag, obj); #define Cyc_check_pair(d,obj) Cyc_check_type(d,Cyc_is_pair, pair_tag, obj);
#define Cyc_check_proc(d,obj) Cyc_check_type2(d,Cyc_is_procedure, closureN_tag, obj); #define Cyc_check_proc(d,obj) Cyc_check_type2(d,Cyc_is_procedure, closureN_tag, obj);
#define Cyc_check_num(d,obj) Cyc_check_type(d,Cyc_is_number, integer_tag, obj); #define Cyc_check_num(d,obj) Cyc_check_type(d,Cyc_is_number, integer_tag, obj);
#define Cyc_check_fixnum(d,obj) Cyc_check_type(d,Cyc_is_fixnum, integer_tag, obj);
#define Cyc_check_int(d,obj) Cyc_check_type(d,Cyc_is_integer, integer_tag, obj); #define Cyc_check_int(d,obj) Cyc_check_type(d,Cyc_is_integer, integer_tag, obj);
#define Cyc_check_str(d,obj) Cyc_check_type(d,Cyc_is_string, string_tag, obj); #define Cyc_check_str(d,obj) Cyc_check_type(d,Cyc_is_string, string_tag, obj);
#define Cyc_check_sym(d,obj) Cyc_check_type(d,Cyc_is_symbol, symbol_tag, obj); #define Cyc_check_sym(d,obj) Cyc_check_type(d,Cyc_is_symbol, symbol_tag, obj);
@ -359,6 +360,7 @@ object Cyc_is_null(object o);
object Cyc_is_number(object o); object Cyc_is_number(object o);
object Cyc_is_real(object o); object Cyc_is_real(object o);
object Cyc_is_integer(object o); object Cyc_is_integer(object o);
object Cyc_is_fixnum(object o);
object Cyc_is_bignum(object o); object Cyc_is_bignum(object o);
object Cyc_is_vector(object o); object Cyc_is_vector(object o);
object Cyc_is_bytevector(object o); object Cyc_is_bytevector(object o);

View file

@ -294,6 +294,8 @@ struct gc_thread_data_t {
char *stack_prev_frame; char *stack_prev_frame;
// Exception handler stack // Exception handler stack
object exception_handler_stack; object exception_handler_stack;
// Parameter object data
object param_objs;
}; };
/* GC prototypes */ /* GC prototypes */

View file

@ -1465,6 +1465,13 @@ object Cyc_is_real(object o)
return Cyc_is_number(o); return Cyc_is_number(o);
} }
object Cyc_is_fixnum(object o)
{
if (obj_is_int(o))
return boolean_t;
return boolean_f;
}
object Cyc_is_integer(object o) object Cyc_is_integer(object o)
{ {
if ((o != NULL) && (obj_is_int(o) || if ((o != NULL) && (obj_is_int(o) ||
@ -1833,6 +1840,8 @@ object Cyc_string2number2_(void *data, object cont, int argc, object str, ...)
result = (int)strtol(string_str(str), NULL, 2); result = (int)strtol(string_str(str), NULL, 2);
} else if (base_num == 8) { } else if (base_num == 8) {
result = (int)strtol(string_str(str), NULL, 8); result = (int)strtol(string_str(str), NULL, 8);
} else if (base_num == 10) {
Cyc_string2number_(data, cont, str); // Default processing
} else if (base_num == 16) { } else if (base_num == 16) {
result = (int)strtol(string_str(str), NULL, 16); result = (int)strtol(string_str(str), NULL, 16);
} }
@ -1842,7 +1851,7 @@ object Cyc_string2number2_(void *data, object cont, int argc, object str, ...)
if (MP_OKAY != mp_read_radix(&(bignum_value(bn)), string_str(str), base_num)) { if (MP_OKAY != mp_read_radix(&(bignum_value(bn)), string_str(str), base_num)) {
Cyc_rt_raise2(data, "Error converting string to bignum", str); Cyc_rt_raise2(data, "Error converting string to bignum", str);
} }
_return_closcall1(data, cont, bn); _return_closcall1(data, cont, Cyc_bignum_normalize(data, bn));
} else { } else {
_return_closcall1(data, cont, obj_int2obj(result)); _return_closcall1(data, cont, obj_int2obj(result));
} }
@ -4776,6 +4785,7 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont,
// Transport exception stack // Transport exception stack
gc_move2heap(((gc_thread_data *) data)->exception_handler_stack); gc_move2heap(((gc_thread_data *) data)->exception_handler_stack);
gc_move2heap(((gc_thread_data *) data)->param_objs);
gc_move2heap(((gc_thread_data *) data)->scm_thread_obj); gc_move2heap(((gc_thread_data *) data)->scm_thread_obj);
// Transport mutations // Transport mutations
@ -5318,11 +5328,29 @@ const object primitive_Cyc_91write = &Cyc_91write_primitive;
const object primitive_Cyc_91display = &Cyc_91display_primitive; const object primitive_Cyc_91display = &Cyc_91display_primitive;
const object primitive_call_95cc = &call_95cc_primitive; const object primitive_call_95cc = &call_95cc_primitive;
void *gc_alloc_pair(gc_thread_data *data, object head, object tail)
{
int heap_grown;
pair_type *p;
pair_type tmp;
tmp.hdr.mark = gc_color_red;
tmp.hdr.grayed = 0;
tmp.tag = pair_tag;
tmp.pair_car = head;
tmp.pair_cdr = tail;
p = gc_alloc(((gc_thread_data *)data)->heap, sizeof(pair_type), (char *)(&tmp), (gc_thread_data *)data, &heap_grown);
return p;
}
/** /**
* Thread initialization function only called from within the runtime * Thread initialization function only called from within the runtime
*/ */
void *Cyc_init_thread(object thread_and_thunk) void *Cyc_init_thread(object thread_and_thunk)
{ {
vector_type *t;
c_opaque_type *o;
object op, parent, child;
long stack_start; long stack_start;
gc_thread_data *thd; gc_thread_data *thd;
thd = malloc(sizeof(gc_thread_data)); thd = malloc(sizeof(gc_thread_data));
@ -5332,6 +5360,28 @@ void *Cyc_init_thread(object thread_and_thunk)
thd->gc_num_args = 1; thd->gc_num_args = 1;
thd->gc_args[0] = &Cyc_91end_91thread_67_primitive; thd->gc_args[0] = &Cyc_91end_91thread_67_primitive;
thd->thread_id = pthread_self(); thd->thread_id = pthread_self();
// Copy thread params from the calling thread
t = (vector_type *)thd->scm_thread_obj;
op = Cyc_vector_ref(thd, t, obj_int2obj(2)); // Field set in thread-start!
o = (c_opaque_type *)op;
parent = ((gc_thread_data *)o->ptr)->param_objs; // Unbox parent thread's data
child = NULL;
thd->param_objs = NULL;
while (parent) {
if (thd->param_objs == NULL) {
thd->param_objs = gc_alloc_pair(thd, NULL, NULL);
child = thd->param_objs;
} else {
pair_type *p = gc_alloc_pair(thd, NULL, NULL);
cdr(child) = p;
child = p;
}
car(child) = gc_alloc_pair(thd, car(car(parent)), cdr(car(parent)));
parent = cdr(parent);
}
// Done initializing parameter objects
gc_add_mutator(thd); gc_add_mutator(thd);
ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_NEW, ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_NEW,
CYC_THREAD_STATE_RUNNABLE); CYC_THREAD_STATE_RUNNABLE);

View file

@ -107,6 +107,7 @@
string->vector string->vector
string-map string-map
string-for-each string-for-each
;get-param-objs ;; TODO: only for debugging!!
make-parameter make-parameter
current-output-port current-output-port
current-input-port current-input-port
@ -948,21 +949,62 @@
() ()
((param value) ...) ((param value) ...)
body)))) body))))
(define-c get-param-objs
"(void *data, int argc, closure _, object k)"
" gc_thread_data *thd = (gc_thread_data *)data;
//Cyc_st_add(data, \"scheme/base.sld:get-param-objs\");
return_closcall1(data, k, thd->param_objs); ")
(define-c set-param-obj!
"(void *data, int argc, closure _, object k, object obj)"
" gc_thread_data *thd = (gc_thread_data *)data;
make_pair(c, obj, thd->param_objs);
thd->param_objs = &c;
return_closcall1(data, k, &c); ")
;"(void *data, int argc, closure _, object k, object obj)"
;" make_pair(p, obj, ((gc_thread_data *)data)->param_objs);
; gc_thread_data *thd = (gc_thread_data *)data;
; //Cyc_st_add(data, \"scheme/base.sld:set-param-objs!\");
; //fprintf(stderr, \"scheme/base.sld:set-param-objs!\\n\");
; global_set((thd->param_objs), &p);
; //thd->param_objs = (object)(&p);
; // obj is on the stack, need to add it to write barrier
; // to ensure it is transported to the heap
; //add_mutation(data, &p, -1, obj);
; return_closcall1(data, k, boolean_t); ")
(define *parameter-id* 0)
(define (make-parameter init . o) (define (make-parameter init . o)
(let* ((converter (let* ((converter
(if (pair? o) (car o) (lambda (x) x))) (if (pair? o) (car o) (lambda (x) x)))
(value (converter init))) (value (converter init))
(key #f))
;; TODO: this is not thread safe!
(set! key *parameter-id*)
(set! *parameter-id* (+ *parameter-id* 1))
;;
(set-param-obj! (cons key value))
(lambda args (lambda args
(cond (cond
((null? args) ((null? args)
value) ;; DEBUG
(let ((pobj (get-param-objs)))
;(if (not (pair? (car pobj)))
; (Cyc-display `(get-param-objs not a list: ,(get-param-objs))))
(cdr (assoc key pobj))))
;; END DEBUG
;(cdr (assoc key (get-param-objs))))
;value)
((eq? (car args) '<param-set!>) ((eq? (car args) '<param-set!>)
(set! value (cadr args))) (let ((cell (assoc key (get-param-objs))))
(set-cdr! cell (cadr args))))
;(set! value (cadr args)))
((eq? (car args) '<param-convert>) ((eq? (car args) '<param-convert>)
converter) converter)
(else (else
;(error "bad parameter syntax" args) ;(error "bad parameter syntax" args)
(set! value (converter (car args))) (let ((cell (assoc key (get-param-objs))))
(set-cdr! cell (converter (car args))))
;(set! value (converter (car args)))
))))) )))))
(define current-output-port (define current-output-port
(make-parameter (Cyc-stdout))) (make-parameter (Cyc-stdout)))

View file

@ -99,6 +99,8 @@
(thread-params (cons t (lambda () (thread-params (cons t (lambda ()
(vector-set! t 2 (%get-thread-data)) (vector-set! t 2 (%get-thread-data))
(thunk))))) (thunk)))))
(vector-set! t 2 (%get-thread-data)) ;; Temporarily make parent thread
;; data available for child init
(Cyc-minor-gc) (Cyc-minor-gc)
(Cyc-spawn-thread! thread-params) (Cyc-spawn-thread! thread-params)
)) ))