From ed0bfb4b8eb40d8a4efc65e528e477a2314b34aa Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 22 Apr 2020 06:20:05 -0700 Subject: streams: put_buf and fill_buf become lower-level. In this commit, the put_buf and fill_buf stream virtual functions are changed to operate directly on a low-level buffer, rather than a stream. This will allow these functions to be used for improving the performance of I/O operations that are not related to buffer objects. * stream.h (struct strm_ops): Change type signature of put_buf and fill_buf members. The lengths and iszes are ucnum. The return value is ucnum. The buffer is passed as a pointer and length, rather than a buffer object. * stream.c (unimpl_put_buf, unimpl_fill_buf, generic_put_buf, generic_fill_buf, stdio_put_buf, stdio_fill_buf, delegate_put_buf, delegate_fill_buf): Adjust to new interface. (put_buf, fill_buf, fill_buf_adjust): Pull the poitner and size from the buffer and pass those down to the virtual functions rather than the buffer itself. Convert ucnum return value to val. * strudel.c (strudel_put_buf, strudel_get_buf): The struct delegate interface doesn't change. The put-buf and fill-buf methods still operate on buffer objects. To glue that with the new low-level interface, we use the init_borrowed_buf trick that is was first used in ffi.c: temporary buf objects are efficiently allocated on the stack, pointing to the same memory that is coming down from the stream operation. * txr.1: Document the new restrictions on the buf argument of the put-buf and fill-buf stream delegate methods. Since the buf not a heap object, it cannot be used after the method returns. --- strudel.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'strudel.c') diff --git a/strudel.c b/strudel.c index 5aa4f67e..e36389b7 100644 --- a/strudel.c +++ b/strudel.c @@ -37,6 +37,8 @@ #include "gc.h" #include "eval.h" #include "struct.h" +#include "arith.h" +#include "buf.h" #include "strudel.h" struct strudel_base { /* stru-ct del-egate :) */ @@ -120,20 +122,24 @@ static val strudel_unget_byte(val stream, int byte) return funcall2(meth, obj, num_fast(byte)); } -static val strudel_put_buf(val stream, val buf, cnum pos) +static ucnum strudel_put_buf(val stream, mem_t *ptr, ucnum len, ucnum pos) { struct strudel_base *sb = coerce(struct strudel_base *, stream->co.handle); + obj_t buf_obj; + val buf = init_borrowed_buf(&buf_obj, unum(len), ptr); val obj = sb->obj; val meth = slot(obj, put_buf_s); - return funcall3(meth, obj, buf, num(pos)); + return c_unum(funcall3(meth, obj, buf, num(pos))); } -static val strudel_fill_buf(val stream, val buf, cnum pos) +static ucnum strudel_fill_buf(val stream, mem_t *ptr, ucnum len, ucnum pos) { struct strudel_base *sb = coerce(struct strudel_base *, stream->co.handle); + obj_t buf_obj; + val buf = init_borrowed_buf(&buf_obj, unum(len), ptr); val obj = sb->obj; val meth = slot(obj, fill_buf_s); - return funcall3(meth, obj, buf, num(pos)); + return c_unum(funcall3(meth, obj, buf, num(pos))); } static val strudel_close(val stream, val throw_on_error) -- cgit v1.2.3