lib/proxy: relay stdout, stderr through built-in proxies

proxy_outfd, proxy_errfd are the file descriptors of these built-in
proxies, for issuing formatted printouts without incurring switches to
the inband stage.

evl_printf() is a shorthand call formatting its argument list before
sending the resulting string through proxy_outfd.
This commit is contained in:
Philippe Gerum 2019-06-30 13:01:50 +02:00
parent b1a5755354
commit 98507f2679
4 changed files with 49 additions and 4 deletions

View File

@ -10,6 +10,7 @@
#include <stdarg.h>
#include <sys/types.h>
#include <linux/types.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@ -28,6 +29,11 @@ int evl_vprint_proxy(int proxyfd,
int evl_print_proxy(int proxyfd,
const char *fmt, ...);
int evl_printf(const char *fmt, ...);
extern int proxy_outfd,
proxy_errfd;
#ifdef __cplusplus
}
#endif

View File

@ -58,8 +58,8 @@ static inline int generic_init(void)
/*
* Failing to open the control device with ENOENT is a clear
* sign that we have no EVL core in there. Return with
* -ENOSYS to give a clear hint about this.
* sign that we have no EVL core in there. Return with -ENOSYS
* to give a clear hint about this.
*/
ctlfd = open(EVL_CONTROL_DEV, O_RDWR);
if (ctlfd < 0)
@ -102,6 +102,7 @@ static inline int generic_init(void)
goto fail;
}
pthread_atfork(NULL, NULL, atfork_unmap_shmem);
evl_ctlfd = ctlfd;
evl_shared_memory = shmem;
@ -220,8 +221,7 @@ static inline int do_init(void)
if (ret)
return ret;
pthread_atfork(NULL, NULL, atfork_unmap_shmem);
init_proxy_streams();
install_signal_handlers();
return 0;

View File

@ -35,6 +35,8 @@ int arch_evl_init(void);
int attach_evl_clocks(void);
void init_proxy_streams(void);
int create_evl_element(const char *type,
const char *name,
void *attrs,

View File

@ -15,9 +15,25 @@
#include <uapi/evl/proxy.h>
#include "internal.h"
#define STDSTREAM_BUFSZ 16384
static __thread __attribute__ ((tls_model (EVL_TLS_MODEL)))
char fmt_buf[1024];
int proxy_outfd = -EBADF, proxy_errfd = -EBADF;
void init_proxy_streams(void)
{
/*
* This might fail if stdout/stderr are closed, just ignore if
* so.
*/
proxy_outfd = evl_new_proxy(fileno(stdout), STDSTREAM_BUFSZ, 0,
"stdout:%d", getpid());
proxy_errfd = evl_new_proxy(fileno(stderr), STDSTREAM_BUFSZ, 0,
"stderr:%d", getpid());
}
int evl_new_proxy(int fd, size_t bufsz, size_t granularity,
const char *fmt, ...)
{
@ -67,3 +83,24 @@ int evl_print_proxy(int proxyfd, const char *fmt, ...)
return ret;
}
int evl_printf(const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
/*
* If evl_init() has not run yet, we can resort to vprintf()
* since latency is not an issue.
*/
if (evl_ctlfd < 0)
ret = vprintf(fmt, ap);
else
ret = evl_vprint_proxy(proxy_outfd, fmt, ap);
va_end(ap);
return ret;
}