runtime: eliminate va_list from kernel interface.

This commit is contained in:
whitequark 2016-09-30 03:07:27 +00:00
parent 7cfa667d98
commit 1cbb187136
5 changed files with 44 additions and 24 deletions

View File

@ -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])

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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