148 lines
3.5 KiB
C
148 lines
3.5 KiB
C
#include <pthread.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "spdk_engine/io_engine.h"
|
|
#include "test_common.h"
|
|
|
|
#define THREAD_COUNT 4
|
|
|
|
struct mt_case_arg {
|
|
struct zvfs_blob_handle *handle;
|
|
uint64_t cluster_size;
|
|
uint64_t offset;
|
|
uint8_t seed;
|
|
pthread_barrier_t *barrier;
|
|
int rc;
|
|
};
|
|
|
|
static void *mt_case_worker(void *arg) {
|
|
struct mt_case_arg *ctx = (struct mt_case_arg *)arg;
|
|
void *wbuf = NULL;
|
|
void *rbuf = NULL;
|
|
|
|
if (alloc_aligned_buf(&wbuf, ctx->cluster_size) != 0 ||
|
|
alloc_aligned_buf(&rbuf, ctx->cluster_size) != 0) {
|
|
free(wbuf);
|
|
free(rbuf);
|
|
ctx->rc = 1;
|
|
return NULL;
|
|
}
|
|
|
|
fill_pattern((uint8_t *)wbuf, ctx->cluster_size, ctx->seed);
|
|
(void)pthread_barrier_wait(ctx->barrier);
|
|
|
|
if (blob_write(ctx->handle, ctx->offset, wbuf, ctx->cluster_size) != 0) {
|
|
ctx->rc = 1;
|
|
goto out;
|
|
}
|
|
if (blob_read(ctx->handle, ctx->offset, rbuf, ctx->cluster_size) != 0) {
|
|
ctx->rc = 1;
|
|
goto out;
|
|
}
|
|
if (memcmp(wbuf, rbuf, ctx->cluster_size) != 0) {
|
|
ctx->rc = 1;
|
|
goto out;
|
|
}
|
|
|
|
ctx->rc = 0;
|
|
|
|
out:
|
|
free(wbuf);
|
|
free(rbuf);
|
|
return NULL;
|
|
}
|
|
|
|
int main(void) {
|
|
int rc = 0;
|
|
const char *bdev_name = getenv("SPDK_BDEV_NAME");
|
|
int i = 0;
|
|
struct zvfs_blob_handle *h = NULL;
|
|
uint64_t blob_id = 0;
|
|
uint64_t cluster = 0;
|
|
pthread_t tids[THREAD_COUNT];
|
|
struct mt_case_arg args[THREAD_COUNT];
|
|
pthread_barrier_t barrier;
|
|
int barrier_inited = 0;
|
|
|
|
if (!bdev_name) {
|
|
bdev_name = "Malloc0";
|
|
}
|
|
if (io_engine_init(bdev_name) != 0) {
|
|
fprintf(stderr, "TEST3: io_engine_init failed (bdev=%s)\n", bdev_name);
|
|
return 1;
|
|
}
|
|
|
|
printf("[TEST3] multi thread / same blob\n");
|
|
|
|
h = blob_create(0);
|
|
if (!h) {
|
|
fprintf(stderr, "TEST3: blob_create failed\n");
|
|
return 1;
|
|
}
|
|
blob_id = h->id;
|
|
cluster = h->size;
|
|
if (cluster == 0) {
|
|
fprintf(stderr, "TEST3: invalid cluster size\n");
|
|
rc = 1;
|
|
goto out;
|
|
}
|
|
if (blob_resize(h, cluster * THREAD_COUNT) != 0) {
|
|
fprintf(stderr, "TEST3: blob_resize failed\n");
|
|
rc = 1;
|
|
goto out;
|
|
}
|
|
|
|
if (pthread_barrier_init(&barrier, NULL, THREAD_COUNT) != 0) {
|
|
fprintf(stderr, "TEST3: barrier init failed\n");
|
|
rc = 1;
|
|
goto out;
|
|
}
|
|
barrier_inited = 1;
|
|
|
|
for (i = 0; i < THREAD_COUNT; i++) {
|
|
args[i].handle = h;
|
|
args[i].cluster_size = cluster;
|
|
args[i].offset = cluster * (uint64_t)i;
|
|
args[i].seed = (uint8_t)(0x40 + i);
|
|
args[i].barrier = &barrier;
|
|
args[i].rc = 1;
|
|
if (pthread_create(&tids[i], NULL, mt_case_worker, &args[i]) != 0) {
|
|
fprintf(stderr, "TEST3: pthread_create[%d] failed\n", i);
|
|
rc = 1;
|
|
while (--i >= 0) {
|
|
pthread_join(tids[i], NULL);
|
|
}
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < THREAD_COUNT; i++) {
|
|
pthread_join(tids[i], NULL);
|
|
if (args[i].rc != 0) {
|
|
fprintf(stderr, "TEST3: worker[%d] failed\n", i);
|
|
rc = 1;
|
|
}
|
|
}
|
|
|
|
out:
|
|
if (barrier_inited) {
|
|
(void)pthread_barrier_destroy(&barrier);
|
|
}
|
|
if (h) {
|
|
(void)blob_close(h);
|
|
}
|
|
if (blob_id != 0) {
|
|
(void)blob_delete(blob_id);
|
|
}
|
|
|
|
if (rc == 0) {
|
|
printf("[TEST3] PASS\n");
|
|
return 0;
|
|
}
|
|
printf("[TEST3] FAIL\n");
|
|
return 1;
|
|
}
|