tests: lib: spsc_pbuf: Improve stress test
Improve stress tests to be more robust and demanding. Previous implementation did not reveal race condition. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
6928c4a546
commit
716fa446cd
@ -11,6 +11,7 @@
|
||||
|
||||
#define HDR_LEN sizeof(uint32_t)
|
||||
#define TLEN(len) ROUND_UP(HDR_LEN + len, sizeof(uint32_t))
|
||||
#define STRESS_TIMEOUT_MS ((CONFIG_SYS_CLOCK_TICKS_PER_SEC < 10000) ? 1000 : 15000)
|
||||
|
||||
/* The buffer size itself would be 199 bytes.
|
||||
* 212 - sizeof(struct spsc_pbuf) - 1 = 199.
|
||||
@ -415,6 +416,7 @@ struct stress_data {
|
||||
uint32_t capacity;
|
||||
uint32_t write_cnt;
|
||||
uint32_t read_cnt;
|
||||
uint32_t wr_err;
|
||||
};
|
||||
|
||||
bool stress_read(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
@ -422,20 +424,22 @@ bool stress_read(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
struct stress_data *ctx = (struct stress_data *)user_data;
|
||||
char buf[128];
|
||||
int len;
|
||||
int rpt = (sys_rand32_get() & 3) + 1;
|
||||
|
||||
len = spsc_pbuf_read(ctx->pbuf, buf, (uint16_t)sizeof(buf));
|
||||
for (int i = 0; i < rpt; i++) {
|
||||
len = spsc_pbuf_read(ctx->pbuf, buf, (uint16_t)sizeof(buf));
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return true;
|
||||
if (len < 0) {
|
||||
zassert_true(false, "Unexpected error: %d, cnt:%d", len, ctx->read_cnt);
|
||||
}
|
||||
|
||||
check_buffer(buf, len, ctx->read_cnt);
|
||||
ctx->read_cnt++;
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
zassert_true(false, "Unexpected error: %d, cnt:%d", len, ctx->read_cnt);
|
||||
}
|
||||
|
||||
check_buffer(buf, len, ctx->read_cnt);
|
||||
ctx->read_cnt++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -444,36 +448,41 @@ bool stress_write(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
struct stress_data *ctx = (struct stress_data *)user_data;
|
||||
char buf[128];
|
||||
uint16_t len = 1 + (sys_rand32_get() % (ctx->capacity / 4));
|
||||
int rpt = (sys_rand32_get() & 1) + 1;
|
||||
|
||||
zassert_true(len < sizeof(buf), "len:%d %d", len, ctx->capacity);
|
||||
|
||||
memset(buf, (uint8_t)ctx->write_cnt, len);
|
||||
if (spsc_pbuf_write(ctx->pbuf, buf, len) == 0) {
|
||||
ctx->write_cnt++;
|
||||
for (int i = 0; i < rpt; i++) {
|
||||
memset(buf, (uint8_t)ctx->write_cnt, len);
|
||||
if (spsc_pbuf_write(ctx->pbuf, buf, len) == len) {
|
||||
ctx->write_cnt++;
|
||||
} else {
|
||||
ctx->wr_err++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZTEST(test_spsc_pbuf, test_stress)
|
||||
{
|
||||
static uint8_t buffer[128] __aligned(MAX(Z_SPSC_PBUF_DCACHE_LINE, 4));
|
||||
static struct stress_data ctx;
|
||||
static struct stress_data ctx = {};
|
||||
uint32_t repeat = 0;
|
||||
|
||||
ctx.write_cnt = 0;
|
||||
ctx.read_cnt = 0;
|
||||
ctx.pbuf = spsc_pbuf_init(buffer, sizeof(buffer), 0);
|
||||
ctx.capacity = spsc_pbuf_capacity(ctx.pbuf);
|
||||
|
||||
ztress_set_timeout(K_MSEC(5000));
|
||||
ZTRESS_EXECUTE(ZTRESS_THREAD(stress_read, &ctx, repeat, 0, Z_TIMEOUT_TICKS(4)),
|
||||
ZTRESS_THREAD(stress_write, &ctx, repeat, 1000, Z_TIMEOUT_TICKS(4)));
|
||||
ztress_set_timeout(K_MSEC(STRESS_TIMEOUT_MS));
|
||||
TC_PRINT("Reading from an interrupt, writing from a thread\n");
|
||||
ZTRESS_EXECUTE(ZTRESS_TIMER(stress_read, &ctx, repeat, Z_TIMEOUT_TICKS(4)),
|
||||
ZTRESS_THREAD(stress_write, &ctx, repeat, 2000, Z_TIMEOUT_TICKS(4)));
|
||||
TC_PRINT("Writes:%d failures: %d\n", ctx.write_cnt, ctx.wr_err);
|
||||
|
||||
ZTRESS_EXECUTE(ZTRESS_THREAD(stress_write, &ctx, repeat, 0, Z_TIMEOUT_TICKS(4)),
|
||||
TC_PRINT("Writing from an interrupt, reading from a thread\n");
|
||||
ZTRESS_EXECUTE(ZTRESS_TIMER(stress_write, &ctx, repeat, Z_TIMEOUT_TICKS(4)),
|
||||
ZTRESS_THREAD(stress_read, &ctx, repeat, 1000, Z_TIMEOUT_TICKS(4)));
|
||||
TC_PRINT("Writes:%d failures: %d\n", ctx.write_cnt, ctx.wr_err);
|
||||
}
|
||||
|
||||
bool stress_claim_free(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
@ -481,40 +490,47 @@ bool stress_claim_free(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
struct stress_data *ctx = (struct stress_data *)user_data;
|
||||
char *buf;
|
||||
uint16_t len;
|
||||
int rpt = sys_rand32_get() % 0x3;
|
||||
|
||||
len = spsc_pbuf_claim(ctx->pbuf, &buf);
|
||||
for (int i = 0; i < rpt; i++) {
|
||||
len = spsc_pbuf_claim(ctx->pbuf, &buf);
|
||||
|
||||
if (len == 0) {
|
||||
return true;
|
||||
if (len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
check_buffer(buf, len, ctx->read_cnt);
|
||||
|
||||
spsc_pbuf_free(ctx->pbuf, len);
|
||||
|
||||
ctx->read_cnt++;
|
||||
}
|
||||
|
||||
check_buffer(buf, len, ctx->read_cnt);
|
||||
|
||||
spsc_pbuf_free(ctx->pbuf, len);
|
||||
|
||||
ctx->read_cnt++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stress_alloc_commit(void *user_data, uint32_t cnt, bool last, int prio)
|
||||
{
|
||||
struct stress_data *ctx = (struct stress_data *)user_data;
|
||||
uint16_t len = 1 + (sys_rand32_get() % (ctx->capacity / 4));
|
||||
uint32_t rnd = sys_rand32_get();
|
||||
uint16_t len = 1 + (rnd % (ctx->capacity / 4));
|
||||
int rpt = rnd % 0x3;
|
||||
char *buf;
|
||||
int err;
|
||||
|
||||
err = spsc_pbuf_alloc(ctx->pbuf, len, &buf);
|
||||
zassert_true(err >= 0, NULL);
|
||||
if (err != len) {
|
||||
return true;
|
||||
for (int i = 0; i < rpt; i++) {
|
||||
err = spsc_pbuf_alloc(ctx->pbuf, len, &buf);
|
||||
zassert_true(err >= 0, NULL);
|
||||
if (err != len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
memset(buf, (uint8_t)ctx->write_cnt, len);
|
||||
|
||||
spsc_pbuf_commit(ctx->pbuf, len);
|
||||
ctx->write_cnt++;
|
||||
}
|
||||
|
||||
memset(buf, (uint8_t)ctx->write_cnt, len);
|
||||
|
||||
spsc_pbuf_commit(ctx->pbuf, len);
|
||||
ctx->write_cnt++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -529,7 +545,7 @@ ZTEST(test_spsc_pbuf, test_stress_0cpy)
|
||||
ctx.pbuf = spsc_pbuf_init(buffer, sizeof(buffer), 0);
|
||||
ctx.capacity = spsc_pbuf_capacity(ctx.pbuf);
|
||||
|
||||
ztress_set_timeout(K_MSEC(5000));
|
||||
ztress_set_timeout(K_MSEC(STRESS_TIMEOUT_MS));
|
||||
ZTRESS_EXECUTE(ZTRESS_THREAD(stress_claim_free, &ctx, repeat, 0, Z_TIMEOUT_TICKS(4)),
|
||||
ZTRESS_THREAD(stress_alloc_commit, &ctx, repeat, 1000, Z_TIMEOUT_TICKS(4)));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user