Interaction of effect-based fibers with caml_release_runtime_system?

I have been investigating how C library wrappers can achieve non-blocking I/O in OCaml. Here’s an example of such a wrapper (stub): postgresql-ocaml/src/postgresql_stubs.c at c14d830d3eacd36c18ecf8d2bb93d3b92e092539 · mmottl/postgresql-ocaml · GitHub

    res =
      (nparams == 0 && !binary_result)
        ? PQexec(conn, query)
        : PQexecParams(
            conn, query, nparams, param_types,
            params, lengths, formats, binary_result);
    if (param_types != NULL) caml_stat_free(param_types);
    free_binary_params(formats, lengths);
    free_params(params, nparams);

According to OCaml - Interfacing C with OCaml -

caml_enter_blocking_section as an alias for caml_release_runtime_system

And -

caml_release_runtime_system() The calling thread releases the domain lock and other OCaml resources, enabling other threads to run OCaml code in parallel with the execution of the calling thread.

So this is specifically when using systhreads.

But what about when using fibers created with effect libraries like Eio? Do these interact in the same way with the runtime system? In other words, does calling caml_release_runtime_system() yield the current fiber and allow another fiber to run?

I have not investigated Eio but some experimental code of my own employing effects used an event loop (node’s event loop as it happens) with asynchronous i/o - a bit like Lwt without the monad. So i/o doesn’t block: instead, when a descriptor is signalled as ready, the continuation which handles it is resumed. After that is done, control returns to the event loop. I am pretty certain that Eio does something similar.

Presumably Eio has a thread pool available for cases where there is no non-blocking option available for a particular operation, and for that caml_release_runtime_system() might be relevant.

1 Like

Yes, if the C function blocks then you need to wrap it with Eio_unix.run_in_systhread.