From c07a6ff6bf0ca074e542d2f86b350fe5394f9dfd Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Thu, 13 Aug 2020 18:46:48 -0400 Subject: [PATCH] Demonstrate passing args to SCM func from C --- examples/call-scm-from-c/full-with-gc.scm | 18 ++++++++----- examples/call-scm-from-c/full.c | 31 +++++++++++++---------- examples/call-scm-from-c/full.h | 2 +- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/examples/call-scm-from-c/full-with-gc.scm b/examples/call-scm-from-c/full-with-gc.scm index 5bce8b42..8c0cab5c 100644 --- a/examples/call-scm-from-c/full-with-gc.scm +++ b/examples/call-scm-from-c/full-with-gc.scm @@ -7,8 +7,9 @@ (define lock (make-mutex)) (define *done* #f) -(define *dummy* signal-done) ;; Hack to prevent optimizing out signal-done -(define *dummy2* sum-numbers) ;; Hack to prevent optimizing out signal-done +(define *dummy* signal-done) ;; Hack to prevent optimizing out +(define *dummy1* print-result) ;; Hack to prevent optimizing out +(define *dummy2* sum-numbers) ;; Hack to prevent optimizing out (define-c start-c-thread "(void *data, int argc, closure _, object k)" @@ -16,7 +17,7 @@ return_closcall1(data, k, boolean_t); ") (define (sum-numbers) - (let ((result 0)) + (let ((result 500)) (for-each (lambda (n) (set! result (+ result n))) @@ -24,16 +25,19 @@ (lambda X (list result 'result #(result))))) -;(define (print-result +(define (print-result fnc) + (let* ((result (fnc)) + (num (car result))) + (write `(SCM result is ,num)) + (newline))) ;; Signal (wait) that it is done, this is called from C -(define (signal-done) ; obj) - (let ((obj #t)) +(define (signal-done obj) (write `(Called from C set *done* to ,obj)) (newline) (mutex-lock! lock) (set! *done* obj) - (mutex-unlock! lock))) + (mutex-unlock! lock)) ;; More efficient to use a condition var here to signal ready, ;; but this is just an example diff --git a/examples/call-scm-from-c/full.c b/examples/call-scm-from-c/full.c index e9607112..ac9854cb 100644 --- a/examples/call-scm-from-c/full.c +++ b/examples/call-scm-from-c/full.c @@ -10,10 +10,11 @@ */ extern object __glo_signal_91done; extern object __glo_sum_91numbers; +extern object __glo_print_91result; gc_thread_data local; -void *Cyc_init_thread(object thread_and_thunk); +void *Cyc_init_thread(object thread_and_thunk, int argc, object *args); /** * Code for the C thread. @@ -24,19 +25,27 @@ void *Cyc_init_thread(object thread_and_thunk); */ void *c_thread(void *parent_thd) { - object obj; + object obj, fnc, args[1]; printf("Hello from C thread\n"); printf("C calling into SCM\n"); - obj = scm_call_with_gc(parent_thd, __glo_sum_91numbers, boolean_t); + fnc = scm_call_with_gc(parent_thd, __glo_sum_91numbers, 0, NULL); - printf("C received: "); + printf("\nC received: "); + Cyc_write(NULL, fnc, stdout); + printf("\n"); + + args[0] = fnc; + obj = scm_call_with_gc(parent_thd, __glo_print_91result, 1, args); + + printf("\nC received: "); Cyc_write(NULL, obj, stdout); printf("\n"); - obj = scm_call_with_gc(parent_thd, __glo_signal_91done, boolean_t); + args[0] = boolean_t; + obj = scm_call_with_gc(parent_thd, __glo_signal_91done, 1, args); - printf("C received: "); + printf("\nC received: "); Cyc_write(NULL, obj, stdout); printf("\n"); return NULL; @@ -51,9 +60,6 @@ void *c_thread(void *parent_thd) void cleanup_and_return(gc_thread_data *thd, int argc, object k, object result) { - int i; - printf("cleanup and return %p result %p\n", &i, result); - // Cleaup thread object per Cyc_exit_thread gc_remove_mutator(thd); ck_pr_cas_int((int *)&(thd->thread_state), CYC_THREAD_STATE_RUNNABLE, @@ -71,9 +77,6 @@ void cleanup_and_return(gc_thread_data *thd, int argc, object k, object result) */ void after_call_scm(gc_thread_data *thd, int argc, object k, object result) { - int i; - printf("after call scm %p result %p\n", &i, result); - mclosure0(clo, cleanup_and_return); object buf[1]; buf[0] = result; GC(thd, &clo, buf, 1); @@ -105,7 +108,7 @@ void after_call_scm(gc_thread_data *thd, int argc, object k, object result) * or re-allocated (EG: malloc) before returning it * to the C layer. */ -object scm_call_with_gc(gc_thread_data *parent_thd, object fnc, object arg) +object scm_call_with_gc(gc_thread_data *parent_thd, object fnc, int argc, object *args) { jmp_buf l; local.gc_cont = NULL; @@ -133,7 +136,7 @@ object scm_call_with_gc(gc_thread_data *parent_thd, object fnc, object arg) make_pair(thread_and_thunk, &vec, fnc); // TODO: OK we are not clearing vec[5]? I think so... if (!setjmp(*(local.jmp_start))) { - Cyc_init_thread(&thread_and_thunk); + Cyc_init_thread(&thread_and_thunk, argc, args); } return local.gc_cont; diff --git a/examples/call-scm-from-c/full.h b/examples/call-scm-from-c/full.h index 08a634f0..b0656e20 100644 --- a/examples/call-scm-from-c/full.h +++ b/examples/call-scm-from-c/full.h @@ -1,4 +1,4 @@ #include "cyclone/types.h" void start_c_thread(gc_thread_data *thd); -object scm_call_with_gc(gc_thread_data *parent_thd, object fnc, object arg); +object scm_call_with_gc(gc_thread_data *parent_thd, object fnc, int argc, object *args);