From 1cbb187136becbbbe17e2be458877d95a563ecae Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 30 Sep 2016 03:07:27 +0000 Subject: [PATCH] runtime: eliminate va_list from kernel interface. --- .../compiler/transforms/llvm_ir_generator.py | 14 ++++--- artiq/runtime/ksupport.c | 40 +++++++++++++------ artiq/runtime/ksupport.h | 2 +- artiq/runtime/messages.h | 6 +-- artiq/runtime/session.c | 6 +-- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index 826db2b4d..ecc21c3cb 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -19,6 +19,7 @@ lli32 = ll.IntType(32) lli64 = ll.IntType(64) lldouble = ll.DoubleType() llptr = ll.IntType(8).as_pointer() +llptrptr = ll.IntType(8).as_pointer().as_pointer() llmetadata = ll.MetaData() @@ -349,8 +350,7 @@ class LLVMIRGenerator: elif name == "strcmp": llty = ll.FunctionType(lli32, [llptr, llptr]) elif name == "send_rpc": - llty = ll.FunctionType(llvoid, [lli32, llptr], - var_arg=True) + llty = ll.FunctionType(llvoid, [lli32, llptr, llptrptr]) elif name == "recv_rpc": llty = ll.FunctionType(lli32, [llptr]) elif name == "now": @@ -1233,7 +1233,8 @@ class LLVMIRGenerator: llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [], name="rpc.stack") - llargs = [] + llargs = self.llbuilder.alloca(llptr, ll.Constant(lli32, len(args)), + name="rpc.args") for index, arg in enumerate(args): if builtins.is_none(arg.type): llargslot = self.llbuilder.alloca(ll.LiteralStructType([]), @@ -1243,10 +1244,13 @@ class LLVMIRGenerator: llargslot = self.llbuilder.alloca(llarg.type, name="rpc.arg{}".format(index)) self.llbuilder.store(llarg, llargslot) - llargs.append(llargslot) + llargslot = self.llbuilder.bitcast(llargslot, llptr) + + llargptr = self.llbuilder.gep(llargs, [ll.Constant(lli32, index)]) + self.llbuilder.store(llargslot, llargptr) self.llbuilder.call(self.llbuiltin("send_rpc"), - [llservice, lltag] + llargs) + [llservice, lltag, llargs]) # Don't waste stack space on saved arguments. self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr]) diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index 00066cda3..7d5b5d21a 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -272,13 +272,19 @@ double sqrt(double x) /* called by libunwind */ int fprintf(FILE *stream, const char *fmt, ...) { - struct msg_log request; + va_list args; + va_start(args, fmt); + char buf[256]; + int len = vscnprintf(buf, sizeof(buf), fmt, args); + + va_end(args); + + struct msg_log request; request.type = MESSAGE_TYPE_LOG; - request.fmt = fmt; - va_start(request.args, fmt); + request.buf = buf; + request.len = len; mailbox_send_and_wait(&request); - va_end(request.args); return 0; } @@ -462,7 +468,7 @@ void watchdog_clear(int id) mailbox_send_and_wait(&request); } -void send_rpc(int service, const char *tag, ...) +void send_rpc(int service, const char *tag, void **data) { struct msg_rpc_send request; @@ -472,9 +478,8 @@ void send_rpc(int service, const char *tag, ...) request.type = MESSAGE_TYPE_RPC_BATCH; request.service = service; request.tag = tag; - va_start(request.args, tag); + request.data = data; mailbox_send_and_wait(&request); - va_end(request.args); } int recv_rpc(void *slot) @@ -537,7 +542,12 @@ void attribute_writeback(void *utypes) if(attr->tag) { uintptr_t value = (uintptr_t)object + attr->offset; - send_rpc(0, attr->tag, &object, &attr->name, value); + void *args[] = { + &object, + &attr->name, + (void*)value + }; + send_rpc(0, attr->tag, args); } } } @@ -590,11 +600,17 @@ void cache_put(const char *key, struct artiq_list value) void core_log(const char *fmt, ...) { - struct msg_log request; + va_list args; + va_start(args, fmt); + char buf[256]; + int len = vscnprintf(buf, sizeof(buf), fmt, args); + + va_end(args); + + struct msg_log request; request.type = MESSAGE_TYPE_LOG; - request.fmt = fmt; - va_start(request.args, fmt); + request.buf = buf; + request.len = len; mailbox_send_and_wait(&request); - va_end(request.args); } diff --git a/artiq/runtime/ksupport.h b/artiq/runtime/ksupport.h index fc3ef7662..6624ffcfa 100644 --- a/artiq/runtime/ksupport.h +++ b/artiq/runtime/ksupport.h @@ -8,7 +8,7 @@ struct artiq_list { int watchdog_set(int ms); void watchdog_clear(int id); -void send_rpc(int service, const char *tag, ...); +void send_rpc(int service, const char *tag, void **data); int recv_rpc(void *slot); struct artiq_list cache_get(const char *key); void cache_put(const char *key, struct artiq_list value); diff --git a/artiq/runtime/messages.h b/artiq/runtime/messages.h index 6b72e0c4b..30b5bba1d 100644 --- a/artiq/runtime/messages.h +++ b/artiq/runtime/messages.h @@ -79,7 +79,7 @@ struct msg_rpc_send { int type; int service; const char *tag; - va_list args; + void **data; }; struct msg_rpc_recv_request { @@ -118,8 +118,8 @@ struct msg_cache_put_reply { struct msg_log { int type; - const char *fmt; - va_list args; + const char *buf; + size_t len; }; #endif /* __MESSAGES_H */ diff --git a/artiq/runtime/session.c b/artiq/runtime/session.c index 7e8236e86..1cb361bed 100644 --- a/artiq/runtime/session.c +++ b/artiq/runtime/session.c @@ -893,13 +893,13 @@ static int send_rpc_value(const char **tag, void **value) return 1; } -static int send_rpc_request(int service, const char *tag, va_list args) +static int send_rpc_request(int service, const char *tag, void **data) { out_packet_start(REMOTEMSG_TYPE_RPC_REQUEST); out_packet_int32(service); while(*tag != ':') { - void *value = va_arg(args, void*); + void *value = *data++; if(!kloader_validate_kpointer(value)) return 0; if(!send_rpc_value(&tag, &value)) @@ -994,7 +994,7 @@ static int process_kmsg(struct msg_base *umsg) case MESSAGE_TYPE_RPC_BATCH: { struct msg_rpc_send *msg = (struct msg_rpc_send *)umsg; - if(!send_rpc_request(msg->service, msg->tag, msg->args)) { + if(!send_rpc_request(msg->service, msg->tag, msg->data)) { core_log("Failed to send RPC request (service %d, tag %s)\n", msg->service, msg->tag); return 0; // restart session