Remove buffer argument from value_str()
Use a ring of buffers instead, so we can printf() up to 16 values in the same call.
This commit is contained in:
parent
36bf4250f3
commit
f61711047c
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2021-2022 Barcelona Supercomputing Center (BSC)
|
# Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
@ -42,6 +42,7 @@ add_library(emu STATIC
|
|||||||
track.c
|
track.c
|
||||||
thread.c
|
thread.c
|
||||||
extend.c
|
extend.c
|
||||||
|
value.c
|
||||||
ovni/event.c
|
ovni/event.c
|
||||||
ovni/setup.c
|
ovni/setup.c
|
||||||
nanos6/setup.c
|
nanos6/setup.c
|
||||||
|
@ -71,9 +71,8 @@ check_duplicates(struct chan *chan, struct value *v)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (value_is_equal(&chan->last_value, v)) {
|
if (value_is_equal(&chan->last_value, v)) {
|
||||||
char buf[128];
|
|
||||||
err("%s: same value as last_value %s",
|
err("%s: same value as last_value %s",
|
||||||
chan->name, value_str(chan->last_value, buf));
|
chan->name, value_str(chan->last_value));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,10 +97,7 @@ chan_set(struct chan *chan, struct value value)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG
|
dbg("%s: sets value to %s", chan->name, value_str(value));
|
||||||
char buf[128];
|
|
||||||
dbg("%s: sets value to %s", chan->name, value_str(value, buf));
|
|
||||||
#endif
|
|
||||||
chan->data.value = value;
|
chan->data.value = value;
|
||||||
|
|
||||||
if (set_dirty(chan) != 0) {
|
if (set_dirty(chan) != 0) {
|
||||||
|
@ -77,7 +77,7 @@ cb_select(struct chan *sel_chan, void *ptr)
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
UNUSED(buf);
|
UNUSED(buf);
|
||||||
dbg("select channel got value %s\n",
|
dbg("select channel got value %s\n",
|
||||||
value_str(sel_value, buf));
|
value_str(sel_value));
|
||||||
|
|
||||||
struct mux_input *input = NULL;
|
struct mux_input *input = NULL;
|
||||||
if (select_input(mux, sel_value, &input) != 0) {
|
if (select_input(mux, sel_value, &input) != 0) {
|
||||||
@ -90,7 +90,7 @@ cb_select(struct chan *sel_chan, void *ptr)
|
|||||||
input->selected = 1;
|
input->selected = 1;
|
||||||
mux->selected = input->index;
|
mux->selected = input->index;
|
||||||
dbg("mux selects input key=%s chan=%s\n",
|
dbg("mux selects input key=%s chan=%s\n",
|
||||||
value_str(sel_value, buf), input->chan->name);
|
value_str(sel_value), input->chan->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set to null by default */
|
/* Set to null by default */
|
||||||
@ -123,9 +123,8 @@ cb_input(struct chan *in_chan, void *ptr)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
dbg("setting output chan %s to value %s",
|
dbg("setting output chan %s to value %s",
|
||||||
input->output->name, value_str(out_value, buf));
|
input->output->name, value_str(out_value));
|
||||||
|
|
||||||
if (chan_set(input->output, out_value) != 0) {
|
if (chan_set(input->output, out_value) != 0) {
|
||||||
err("chan_set() failed");
|
err("chan_set() failed");
|
||||||
|
@ -88,7 +88,6 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
{
|
{
|
||||||
struct value value;
|
struct value value;
|
||||||
struct chan *chan = rchan->chan;
|
struct chan *chan = rchan->chan;
|
||||||
char buf[128];
|
|
||||||
if (chan_read(chan, &value) != 0) {
|
if (chan_read(chan, &value) != 0) {
|
||||||
err("chan_read %s failed\n", chan->name);
|
err("chan_read %s failed\n", chan->name);
|
||||||
return -1;
|
return -1;
|
||||||
@ -106,7 +105,7 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err("error duplicated value %s for channel %s\n",
|
err("error duplicated value %s for channel %s\n",
|
||||||
value_str(value, buf), chan->name);
|
value_str(value), chan->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
if (~rchan->flags & PRV_ZERO && val == 0) {
|
if (~rchan->flags & PRV_ZERO && val == 0) {
|
||||||
err("forbidden value 0 in %s: %s\n",
|
err("forbidden value 0 in %s: %s\n",
|
||||||
chan->name,
|
chan->name,
|
||||||
value_str(value, buf));
|
value_str(value));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -134,13 +133,13 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err("chan_read %s only int64 and null supported: %s\n",
|
err("chan_read %s only int64 and null supported: %s\n",
|
||||||
chan->name, value_str(value, buf));
|
chan->name, value_str(value));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_line(prv, rchan->row_base1, rchan->type, val);
|
write_line(prv, rchan->row_base1, rchan->type, val);
|
||||||
|
|
||||||
dbg("written %s for chan %s", value_str(value, buf), chan->name);
|
dbg("written %s for chan %s", value_str(value), chan->name);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
7
src/emu/value.c
Normal file
7
src/emu/value.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||||
|
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
|
char value_buffers[VALUE_NBUF][VALUE_BUFSIZE];
|
||||||
|
size_t value_nextbuf = 0;
|
@ -9,6 +9,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define VALUE_NBUF 32
|
||||||
|
#define VALUE_BUFSIZE 128
|
||||||
|
|
||||||
|
extern char value_buffers[VALUE_NBUF][VALUE_BUFSIZE];
|
||||||
|
extern size_t value_nextbuf;
|
||||||
|
|
||||||
enum value_type {
|
enum value_type {
|
||||||
VALUE_NULL = 0,
|
VALUE_NULL = 0,
|
||||||
VALUE_INT64,
|
VALUE_INT64,
|
||||||
@ -51,22 +57,33 @@ value_is_null(struct value a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline char *
|
static inline char *
|
||||||
value_str(struct value a, char *buf)
|
value_str(struct value a)
|
||||||
{
|
{
|
||||||
|
char *buf = value_buffers[value_nextbuf];
|
||||||
|
int ret = 0;
|
||||||
|
size_t n = VALUE_BUFSIZE;
|
||||||
|
|
||||||
switch (a.type) {
|
switch (a.type) {
|
||||||
case VALUE_NULL:
|
case VALUE_NULL:
|
||||||
sprintf(buf, "{NULL}");
|
ret = snprintf(buf, n, "{NULL}");
|
||||||
break;
|
break;
|
||||||
case VALUE_INT64:
|
case VALUE_INT64:
|
||||||
sprintf(buf, "{int64_t %ld}", a.i);
|
ret = snprintf(buf, n, "{int64_t %ld}", a.i);
|
||||||
break;
|
break;
|
||||||
case VALUE_DOUBLE:
|
case VALUE_DOUBLE:
|
||||||
sprintf(buf, "{double %e}", a.d);
|
ret = snprintf(buf, n, "{double %e}", a.d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die("value_str: unexpected value type\n");
|
die("value_str: unexpected value type\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret >= (int) n)
|
||||||
|
die("value string too long");
|
||||||
|
|
||||||
|
value_nextbuf++;
|
||||||
|
if (value_nextbuf > VALUE_NBUF)
|
||||||
|
value_nextbuf = 0;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,9 @@ check_output(struct mux *mux, struct value expected)
|
|||||||
die("chan_read() failed for output channel\n");
|
die("chan_read() failed for output channel\n");
|
||||||
|
|
||||||
if (!value_is_equal(&out_value, &expected)) {
|
if (!value_is_equal(&out_value, &expected)) {
|
||||||
char buf1[128];
|
|
||||||
char buf2[128];
|
|
||||||
die("unexpected value found %s in output (expected %s)\n",
|
die("unexpected value found %s in output (expected %s)\n",
|
||||||
value_str(out_value, buf1),
|
value_str(out_value),
|
||||||
value_str(expected, buf2));
|
value_str(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
err("----- output ok -----\n");
|
err("----- output ok -----\n");
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#include "emu/value.h"
|
#include "emu/value.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
int
|
/* Ensure there are no holes in the value structure */
|
||||||
main(void)
|
static void
|
||||||
|
test_holes(void)
|
||||||
{
|
{
|
||||||
struct value a, b;
|
struct value a, b;
|
||||||
|
|
||||||
@ -21,6 +22,16 @@ main(void)
|
|||||||
die("values are not the same\n");
|
die("values are not the same\n");
|
||||||
|
|
||||||
err("OK\n");
|
err("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure value_null results in values being equal */
|
||||||
|
static void
|
||||||
|
test_null_init(void)
|
||||||
|
{
|
||||||
|
struct value a, b;
|
||||||
|
|
||||||
|
memset(&a, 66, sizeof(struct value));
|
||||||
|
memset(&b, 0, sizeof(struct value));
|
||||||
|
|
||||||
a = value_null();
|
a = value_null();
|
||||||
b = value_null();
|
b = value_null();
|
||||||
@ -28,5 +39,42 @@ main(void)
|
|||||||
if (!value_is_equal(&a, &b))
|
if (!value_is_equal(&a, &b))
|
||||||
die("null not equal");
|
die("null not equal");
|
||||||
|
|
||||||
|
err("OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that we can printf at least 8 values without overwritting the
|
||||||
|
* value_str() buffer */
|
||||||
|
static void
|
||||||
|
test_multiple_str(void)
|
||||||
|
{
|
||||||
|
if (VALUE_NBUF < 8)
|
||||||
|
die("VALUE_NBUF too small");
|
||||||
|
|
||||||
|
char *str[VALUE_NBUF];
|
||||||
|
for (int i = 0; i < VALUE_NBUF; i++) {
|
||||||
|
struct value v = value_int64(i);
|
||||||
|
str[i] = value_str(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < VALUE_NBUF; i++) {
|
||||||
|
char expected[128];
|
||||||
|
sprintf(expected, "{int64_t %d}", i);
|
||||||
|
if (strcmp(expected, str[i]) != 0) {
|
||||||
|
die("mismatch in bufer i=%d: expected %s, got %s",
|
||||||
|
i, expected, str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err("OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
test_holes();
|
||||||
|
test_null_init();
|
||||||
|
test_multiple_str();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user