mirror of https://github.com/m-labs/artiq.git
runtime: eliminate va_list from kernel interface.
This commit is contained in:
parent
7cfa667d98
commit
1cbb187136
|
@ -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])
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue