forked from M-Labs/artiq
1
0
Fork 0

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) lli64 = ll.IntType(64)
lldouble = ll.DoubleType() lldouble = ll.DoubleType()
llptr = ll.IntType(8).as_pointer() llptr = ll.IntType(8).as_pointer()
llptrptr = ll.IntType(8).as_pointer().as_pointer()
llmetadata = ll.MetaData() llmetadata = ll.MetaData()
@ -349,8 +350,7 @@ class LLVMIRGenerator:
elif name == "strcmp": elif name == "strcmp":
llty = ll.FunctionType(lli32, [llptr, llptr]) llty = ll.FunctionType(lli32, [llptr, llptr])
elif name == "send_rpc": elif name == "send_rpc":
llty = ll.FunctionType(llvoid, [lli32, llptr], llty = ll.FunctionType(llvoid, [lli32, llptr, llptrptr])
var_arg=True)
elif name == "recv_rpc": elif name == "recv_rpc":
llty = ll.FunctionType(lli32, [llptr]) llty = ll.FunctionType(lli32, [llptr])
elif name == "now": elif name == "now":
@ -1233,7 +1233,8 @@ class LLVMIRGenerator:
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [], llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [],
name="rpc.stack") name="rpc.stack")
llargs = [] llargs = self.llbuilder.alloca(llptr, ll.Constant(lli32, len(args)),
name="rpc.args")
for index, arg in enumerate(args): for index, arg in enumerate(args):
if builtins.is_none(arg.type): if builtins.is_none(arg.type):
llargslot = self.llbuilder.alloca(ll.LiteralStructType([]), llargslot = self.llbuilder.alloca(ll.LiteralStructType([]),
@ -1243,10 +1244,13 @@ class LLVMIRGenerator:
llargslot = self.llbuilder.alloca(llarg.type, llargslot = self.llbuilder.alloca(llarg.type,
name="rpc.arg{}".format(index)) name="rpc.arg{}".format(index))
self.llbuilder.store(llarg, llargslot) 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"), self.llbuilder.call(self.llbuiltin("send_rpc"),
[llservice, lltag] + llargs) [llservice, lltag, llargs])
# Don't waste stack space on saved arguments. # Don't waste stack space on saved arguments.
self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr]) self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr])

View File

@ -272,13 +272,19 @@ double sqrt(double x)
/* called by libunwind */ /* called by libunwind */
int fprintf(FILE *stream, const char *fmt, ...) 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.type = MESSAGE_TYPE_LOG;
request.fmt = fmt; request.buf = buf;
va_start(request.args, fmt); request.len = len;
mailbox_send_and_wait(&request); mailbox_send_and_wait(&request);
va_end(request.args);
return 0; return 0;
} }
@ -462,7 +468,7 @@ void watchdog_clear(int id)
mailbox_send_and_wait(&request); 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; struct msg_rpc_send request;
@ -472,9 +478,8 @@ void send_rpc(int service, const char *tag, ...)
request.type = MESSAGE_TYPE_RPC_BATCH; request.type = MESSAGE_TYPE_RPC_BATCH;
request.service = service; request.service = service;
request.tag = tag; request.tag = tag;
va_start(request.args, tag); request.data = data;
mailbox_send_and_wait(&request); mailbox_send_and_wait(&request);
va_end(request.args);
} }
int recv_rpc(void *slot) int recv_rpc(void *slot)
@ -537,7 +542,12 @@ void attribute_writeback(void *utypes)
if(attr->tag) { if(attr->tag) {
uintptr_t value = (uintptr_t)object + attr->offset; 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, ...) 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.type = MESSAGE_TYPE_LOG;
request.fmt = fmt; request.buf = buf;
va_start(request.args, fmt); request.len = len;
mailbox_send_and_wait(&request); mailbox_send_and_wait(&request);
va_end(request.args);
} }

View File

@ -8,7 +8,7 @@ struct artiq_list {
int watchdog_set(int ms); int watchdog_set(int ms);
void watchdog_clear(int id); 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); int recv_rpc(void *slot);
struct artiq_list cache_get(const char *key); struct artiq_list cache_get(const char *key);
void cache_put(const char *key, struct artiq_list value); void cache_put(const char *key, struct artiq_list value);

View File

@ -79,7 +79,7 @@ struct msg_rpc_send {
int type; int type;
int service; int service;
const char *tag; const char *tag;
va_list args; void **data;
}; };
struct msg_rpc_recv_request { struct msg_rpc_recv_request {
@ -118,8 +118,8 @@ struct msg_cache_put_reply {
struct msg_log { struct msg_log {
int type; int type;
const char *fmt; const char *buf;
va_list args; size_t len;
}; };
#endif /* __MESSAGES_H */ #endif /* __MESSAGES_H */

View File

@ -893,13 +893,13 @@ static int send_rpc_value(const char **tag, void **value)
return 1; 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_start(REMOTEMSG_TYPE_RPC_REQUEST);
out_packet_int32(service); out_packet_int32(service);
while(*tag != ':') { while(*tag != ':') {
void *value = va_arg(args, void*); void *value = *data++;
if(!kloader_validate_kpointer(value)) if(!kloader_validate_kpointer(value))
return 0; return 0;
if(!send_rpc_value(&tag, &value)) if(!send_rpc_value(&tag, &value))
@ -994,7 +994,7 @@ static int process_kmsg(struct msg_base *umsg)
case MESSAGE_TYPE_RPC_BATCH: { case MESSAGE_TYPE_RPC_BATCH: {
struct msg_rpc_send *msg = (struct msg_rpc_send *)umsg; 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", core_log("Failed to send RPC request (service %d, tag %s)\n",
msg->service, msg->tag); msg->service, msg->tag);
return 0; // restart session return 0; // restart session