diff --git a/lang/el-compiler/runtime/el_runtime.c b/lang/el-compiler/runtime/el_runtime.c index ade897f..753eda2 100644 --- a/lang/el-compiler/runtime/el_runtime.c +++ b/lang/el-compiler/runtime/el_runtime.c @@ -11743,9 +11743,9 @@ el_val_t __channel_new(el_val_t capacity_v) { return EL_INT(slot); } -void __channel_send(el_val_t ch_v, el_val_t msg_v) { +el_val_t __channel_send(el_val_t ch_v, el_val_t msg_v) { int slot = (int)(int64_t)ch_v; - if (slot < 0 || slot >= EL_CHANNEL_MAX) return; + if (slot < 0 || slot >= EL_CHANNEL_MAX) return EL_STR(""); ElChannel* ch = &_channels[slot]; const char* msg = EL_CSTR(msg_v); @@ -11758,7 +11758,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) { /* Send on closed channel is a no-op (drop the message). */ pthread_mutex_unlock(&ch->mu); free(copy); - return; + return EL_STR(""); } if (ch->cap > 0) { @@ -11769,7 +11769,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) { if (ch->closed) { pthread_mutex_unlock(&ch->mu); free(copy); - return; + return EL_STR(""); } ch->buf[ch->tail] = copy; ch->tail = (ch->tail + 1) % ch->cap; @@ -11783,7 +11783,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) { pthread_mutex_unlock(&ch->mu); free(copy); fprintf(stderr, "[__channel_send] out of memory growing channel\n"); - return; + return EL_STR(""); } /* The circular buffer may have wrapped. Linearise it first. * In unbounded mode head is always 0 (we append at tail, drain @@ -11807,6 +11807,7 @@ void __channel_send(el_val_t ch_v, el_val_t msg_v) { pthread_cond_signal(&ch->not_empty); pthread_mutex_unlock(&ch->mu); + return EL_STR(""); } el_val_t __channel_recv(el_val_t ch_v) { @@ -11864,9 +11865,9 @@ el_val_t __channel_try_recv(el_val_t ch_v) { return EL_STR(msg); } -void __channel_close(el_val_t ch_v) { +el_val_t __channel_close(el_val_t ch_v) { int slot = (int)(int64_t)ch_v; - if (slot < 0 || slot >= EL_CHANNEL_MAX) return; + if (slot < 0 || slot >= EL_CHANNEL_MAX) return EL_STR(""); ElChannel* ch = &_channels[slot]; pthread_mutex_lock(&ch->mu); @@ -11875,6 +11876,7 @@ void __channel_close(el_val_t ch_v) { pthread_cond_broadcast(&ch->not_empty); pthread_cond_broadcast(&ch->not_full); pthread_mutex_unlock(&ch->mu); + return EL_STR(""); } /* ── DHARMA runtime additions ──────────────────────────────────────────────── diff --git a/lang/el-compiler/runtime/el_runtime.h b/lang/el-compiler/runtime/el_runtime.h index 87348f5..4b30d7c 100644 --- a/lang/el-compiler/runtime/el_runtime.h +++ b/lang/el-compiler/runtime/el_runtime.h @@ -803,6 +803,19 @@ el_val_t emit_event(el_val_t name, el_val_t duration_ms); el_val_t __thread_create(el_val_t fn_name_v, el_val_t arg_v); el_val_t __thread_join(el_val_t tid_v); +/* Mutex + channel seed primitives (defined in el_runtime.c). Declared here so + * that compiled El programs which use runtime/thread.el's with_mutex helper or + * runtime/channel.el's Go-style channels see real prototypes instead of an + * implicit int-return declaration (which the C11 ABI mis-truncates el_val_t). */ +el_val_t __mutex_new(void); +void __mutex_lock(el_val_t m_v); +void __mutex_unlock(el_val_t m_v); +el_val_t __channel_new(el_val_t capacity_v); +el_val_t __channel_send(el_val_t ch_v, el_val_t msg_v); +el_val_t __channel_recv(el_val_t ch_v); +el_val_t __channel_try_recv(el_val_t ch_v); +el_val_t __channel_close(el_val_t ch_v); + /* ── __ prefixed aliases (self-hosting compiler ABI) ───────────────────────── * The El self-hosting compiler emits calls to __-prefixed names. These are * forwarding wrappers around the existing el_runtime functions above. */