summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuyu <[email protected]>2024-06-06 18:36:33 +0800
committerliuyu <[email protected]>2024-06-06 18:36:33 +0800
commit657e0c0d674f52e66dd12b713e61be6b5fddba5d (patch)
treec0b5eb5468ab33cc85dcbf666264c6e547566755
parent6cae15d76c7e0865dffea888a5ec1c66812ce88d (diff)
-rw-r--r--tests/benchmark/bcm_benchmark.c7
-rw-r--r--tests/benchmark/bcm_queue.c107
-rwxr-xr-xtests/benchmark/benchmark.sh4
-rw-r--r--tests/benchmark/config/compare/general/case8_simple_mpmc.ini15
-rw-r--r--tests/common/test_mix.c18
-rw-r--r--tests/common/test_mix.h5
-rw-r--r--tests/common/test_queue.c61
-rw-r--r--tests/common/test_queue.h15
8 files changed, 193 insertions, 39 deletions
diff --git a/tests/benchmark/bcm_benchmark.c b/tests/benchmark/bcm_benchmark.c
index 6499e0c..25edc1d 100644
--- a/tests/benchmark/bcm_benchmark.c
+++ b/tests/benchmark/bcm_benchmark.c
@@ -1,6 +1,6 @@
/*
* @Author: liuyu
- * @LastEditTime: 2024-06-06 10:52:56
+ * @LastEditTime: 2024-06-06 18:28:48
* @Describe: TODO
*/
@@ -107,9 +107,10 @@ int main(int argc, char *argv[]) {
burst_cnt = 1;
}
} else {
- config = "/root/code/c/bbq-ly/tests/benchmark/config/compare/general/case5_complex_mpsc.ini";
+ config = "/root/code/c/bbq-ly/tests/benchmark/config/compare/general/case8_simple_mpmc.ini";
+ ring_type = "rmind";
// ring_type = "dpdk";
- ring_type = "bbq";
+ // ring_type = "bbq";
burst_cnt = 100;
BBQ_ERR_LOG("use default config, ringt_type:%s burst:%u config:%s argc:%d", ring_type, burst_cnt, config, argc);
}
diff --git a/tests/benchmark/bcm_queue.c b/tests/benchmark/bcm_queue.c
index 2db8ce0..98b0d29 100644
--- a/tests/benchmark/bcm_queue.c
+++ b/tests/benchmark/bcm_queue.c
@@ -1,10 +1,11 @@
/*
* @Author: liuyu
- * @LastEditTime: 2024-06-06 12:07:21
+ * @LastEditTime: 2024-06-06 17:36:40
* @Describe: TODO
*/
#include "bcm_queue.h"
+#include "ringbuf.h"
static __rte_always_inline unsigned int
bcm_ring_enqueue_burst(struct rte_ring *r, void *obj_table, size_t n, unsigned int flags) {
@@ -52,11 +53,112 @@ int test_queue_init_dpdk(test_cfg *cfg, test_queue_s *q) {
return BBQ_OK;
}
+unsigned char *rmind_buf;
+uint16_t worker_cnt;
+ringbuf_worker_t **rmind_workers;
+
+void test_queue_free_rmind(void *ring) {
+ for (uint16_t i = 0; i < worker_cnt; i++) {
+ ringbuf_unregister((ringbuf_t *)ring, rmind_workers[i]);
+ }
+
+ test_free(TEST_MODULE_RMIND, rmind_workers);
+ test_free(TEST_MODULE_RMIND, rmind_buf);
+ test_free(TEST_MODULE_RMIND, ring);
+}
+
+uint32_t test_enqueue_burst_rmind(void *ring, void *obj_table, size_t n, unsigned int flags, uint16_t thread_idx) {
+ uint32_t cnt = 0;
+ int ret = 0;
+ size_t off = 0;
+ void *obj = NULL;
+ ringbuf_worker_t *w = (ringbuf_worker_t *)rmind_workers[thread_idx];
+ size_t len = sizeof(uintptr_t);
+
+ for (cnt = 0; cnt < n; cnt++) {
+ obj = ((void **)obj_table)[cnt];
+ uintptr_t uptr = (uintptr_t)obj;
+
+ if ((ret = ringbuf_acquire(ring, w, len)) != -1) {
+ off = (size_t)ret;
+ memcpy(&rmind_buf[off], &uptr, len);
+ ringbuf_produce(ring, w);
+ } else {
+ break;
+ }
+ }
+
+ return cnt;
+}
+
+uint32_t test_dequeue_burst_rmind(void *ring, void *obj_table, uint32_t n) {
+ size_t len = 0;
+ size_t off = 0;
+ size_t per_size = sizeof(void *);
+ void **table = (void **)obj_table;
+
+ if ((len = ringbuf_consume(ring, &off)) != 0) {
+ size_t rem = len;
+ size_t i = 0;
+
+ while (rem) {
+ uintptr_t *data = (uintptr_t *)(&rmind_buf[off]);
+ table[i] = (void *)(*data);
+ i++;
+ off += per_size;
+ rem -= sizeof(void *);
+ }
+ ringbuf_release(ring, len);
+ return i;
+ }
+
+ return 0;
+}
+
+int test_queue_init_rmind(test_cfg *cfg, test_queue_s *q) {
+ static size_t ringbuf_obj_size;
+ worker_cnt = cfg->ring.producer_cnt + cfg->ring.consumer_cnt;
+
+ ringbuf_get_sizes(worker_cnt, &ringbuf_obj_size, NULL);
+ ringbuf_t *r = test_malloc(TEST_MODULE_RMIND, ringbuf_obj_size);
+ if (r == NULL) {
+ exit(-1);
+ }
+
+ size_t buf_size = sizeof(void *) * cfg->ring.entries_cnt;
+ rmind_buf = test_malloc(TEST_MODULE_RMIND, buf_size);
+ if (rmind_buf == NULL) {
+ exit(-1);
+ }
+ ringbuf_setup(r, worker_cnt, buf_size);
+
+ rmind_workers = test_malloc(TEST_MODULE_RMIND, sizeof(*rmind_workers) * worker_cnt);
+ if (rmind_workers == NULL) {
+ exit(-1);
+ }
+ for (uint32_t i = 0; i < worker_cnt; i++) {
+ rmind_workers[i] = ringbuf_register(r, i);
+ if (rmind_workers[i] == NULL) {
+ exit(-1);
+ }
+ }
+
+ q->ring = r;
+ q->ring_free_f = (test_ring_free_f)test_queue_free_rmind;
+ q->enqueue_f = NULL;
+ q->dequeue_f = NULL;
+ q->enqueue_burst_f = (test_enqueue_burst_f)test_enqueue_burst_rmind;
+ q->dequeue_burst_f = (test_dequeue_burst_f)test_dequeue_burst_rmind;
+
+ return 0;
+}
+
int bcm_queue_init(test_cfg *cfg, test_queue_s *q) {
if (cfg == NULL || q == NULL) {
return BBQ_NULL_PTR;
}
+ memset(q, 0, sizeof(*q));
int ret = -1;
q->ring_type = cfg->ring.ring_type;
switch (q->ring_type) {
@@ -66,6 +168,9 @@ int bcm_queue_init(test_cfg *cfg, test_queue_s *q) {
case TEST_RING_TYPE_BBQ:
ret = test_queue_init_bbq(cfg, q);
break;
+ case TEST_RING_TYPE_RMIND:
+ ret = test_queue_init_rmind(cfg, q);
+ break;
default:
return BBQ_UNKNOWN_TYPE;
}
diff --git a/tests/benchmark/benchmark.sh b/tests/benchmark/benchmark.sh
index 858b14f..69c4730 100755
--- a/tests/benchmark/benchmark.sh
+++ b/tests/benchmark/benchmark.sh
@@ -1,12 +1,12 @@
#!/bin/bash
###
# @Author: liuyu
-# @LastEditTime: 2024-06-05 18:43:28
+# @LastEditTime: 2024-06-06 14:59:48
# @Describe: TODO
###
-ring_type_arr=("bbq" "dpdk")
+ring_type_arr=("bbq" "dpdk" "rmind")
# 检查参数数量
if [ "$#" -ne 4 ]; then
diff --git a/tests/benchmark/config/compare/general/case8_simple_mpmc.ini b/tests/benchmark/config/compare/general/case8_simple_mpmc.ini
new file mode 100644
index 0000000..f31d772
--- /dev/null
+++ b/tests/benchmark/config/compare/general/case8_simple_mpmc.ini
@@ -0,0 +1,15 @@
+[base]
+ introduce = "case5 复杂负载下,多生产者、单消费者 吞吐测试" ;测试配置说明
+ cores_cnt = 8 ;测试用核心个数
+
+[ring]
+ workload = "simple" ;负载模式 simple/complex
+ entries_cnt = 4096 ;ring初始化时分配entry的个数
+ block_count = 0 ;bbq配置,等于0则表示根据entries_cnt自动计算
+ producer_cnt = 1 ;生产者个数
+ consumer_cnt = 4 ;消费者个数
+
+[run]
+ run_time = 5 ; 整体运行的秒数,大于0生效
+ enqueue_cnt = 0 ;每个线程入队次数,大于0生效
+ dequeue_cnt = 0 ;每个线程出队次数,大于0生效 \ No newline at end of file
diff --git a/tests/common/test_mix.c b/tests/common/test_mix.c
index e1f532a..7a44097 100644
--- a/tests/common/test_mix.c
+++ b/tests/common/test_mix.c
@@ -1,7 +1,7 @@
/*
* @Description: 描述信息
* @Date: 2024-05-25 10:55:48
- * @LastEditTime: 2024-06-05 18:45:47
+ * @LastEditTime: 2024-06-06 18:32:47
*/
#include "test_mix.h"
@@ -137,6 +137,19 @@ int test_load_config(const char *config, const char *ring_type, uint32_t burst_c
BBQ_INFO_LOG("ring_type:%s(%u)", ring_type, cfg->ring.ring_type);
BBQ_INFO_LOG("burst_cnt:%u", burst_cnt);
+
+ if (cfg->ring.ring_type == TEST_RING_TYPE_RMIND) {
+ // rmind仅支持1个消费者,仅支持burst方式
+ if (cfg->ring.consumer_cnt > 1) {
+ BBQ_ERR_LOG("ring type:%s only support single consumer", TEST_RING_TYPE_RMIND_STR);
+ return -1;
+ }
+
+ if (cfg->ring.burst_cnt <= 1) {
+ BBQ_ERR_LOG("ring type:%s only support burst_cnt > 1", TEST_RING_TYPE_RMIND_STR);
+ return -1;
+ }
+ }
// 释放dictionary对象
iniparser_freedict(ini);
return 0;
@@ -206,6 +219,7 @@ test_workload_e test_workload_str2enum(const char *workload) {
char *ring_type_map[TEST_RING_TYPE_MAX] = {
[TEST_RING_TYPE_BBQ] = TEST_RING_TYPE_BBQ_STR,
[TEST_RING_TYPE_DPDK] = TEST_RING_TYPE_DPDK_STR,
+ [TEST_RING_TYPE_RMIND] = TEST_RING_TYPE_RMIND_STR,
};
test_ring_type test_ring_type_str2enum(const char *ring_type) {
@@ -213,6 +227,8 @@ test_ring_type test_ring_type_str2enum(const char *ring_type) {
return TEST_RING_TYPE_BBQ;
} else if (strcmp(ring_type, TEST_RING_TYPE_DPDK_STR) == 0) {
return TEST_RING_TYPE_DPDK;
+ } else if (strcmp(ring_type, TEST_RING_TYPE_RMIND_STR) == 0) {
+ return TEST_RING_TYPE_RMIND;
}
return TEST_RING_TYPE_MAX;
diff --git a/tests/common/test_mix.h b/tests/common/test_mix.h
index 8f65e9f..1676255 100644
--- a/tests/common/test_mix.h
+++ b/tests/common/test_mix.h
@@ -1,6 +1,6 @@
/*
* @Author: liuyu
- * @LastEditTime: 2024-06-06 10:57:22
+ * @LastEditTime: 2024-06-06 14:23:24
* @Describe: TODO
*/
@@ -43,9 +43,11 @@ typedef enum {
#define TEST_RING_TYPE_BBQ_STR "bbq"
#define TEST_RING_TYPE_DPDK_STR "dpdk"
+#define TEST_RING_TYPE_RMIND_STR "rmind"
typedef enum {
TEST_RING_TYPE_BBQ,
TEST_RING_TYPE_DPDK,
+ TEST_RING_TYPE_RMIND,
TEST_RING_TYPE_MAX,
} test_ring_type;
@@ -94,6 +96,7 @@ typedef enum {
TEST_MODULE_DATA,
TEST_MODULE_BCM,
TEST_MODULE_TABLE,
+ TEST_MODULE_RMIND,
TEST_MODULE_MAX,
} test_module_e;
diff --git a/tests/common/test_queue.c b/tests/common/test_queue.c
index 5021a98..28f3f3d 100644
--- a/tests/common/test_queue.c
+++ b/tests/common/test_queue.c
@@ -1,6 +1,6 @@
/*
* @Author: liuyu
- * @LastEditTime: 2024-06-06 12:10:26
+ * @LastEditTime: 2024-06-06 18:27:47
* @Describe: TODO
*/
@@ -77,7 +77,7 @@ test_exit_data *test_exit_data_create(test_thread_arg_s *t_arg) {
exit(-1);
}
- size_t size = t_arg->cfg->ring.burst_cnt;
+ size_t size = t_arg->cfg->ring.entries_cnt;
exit_data->simple_data_cnt = size;
exit_data->simple_data = test_data_create(size);
@@ -118,15 +118,17 @@ void test_data_destory(test_data **data, size_t cnt) {
test_free(TEST_MODULE_DATA, data);
}
-uint32_t test_exec_enqueue(test_queue_s *q, test_data **data, size_t burst_cnt, test_time_metric *op_use_diff) {
+uint32_t test_exec_enqueue(test_queue_s *q, test_data **data, size_t burst_cnt, test_time_metric *op_use_diff, uint16_t thread_idx) {
uint32_t enqueue_cnt = 0;
test_time_metric op_use_start = test_clock_time_get();
if (burst_cnt == 1) {
- if (q->enqueue_f(q->ring, data[0]) == 0) {
- enqueue_cnt = 1;
+ if (q->enqueue_f) {
+ if (q->enqueue_f(q->ring, data[0]) == 0) {
+ enqueue_cnt = 1;
+ }
}
} else {
- enqueue_cnt = q->enqueue_burst_f(q->ring, data, burst_cnt, BBQ_F_ARRAY_2D);
+ enqueue_cnt = q->enqueue_burst_f(q->ring, data, burst_cnt, BBQ_F_ARRAY_2D, thread_idx);
}
*op_use_diff = test_clock_time_sub(test_clock_time_get(), op_use_start);
@@ -138,8 +140,10 @@ uint32_t test_exec_dequeue(test_queue_s *q, test_data **data, size_t burst_cnt,
test_time_metric op_use_start = test_clock_time_get();
if (burst_cnt == 1) {
- if (q->dequeue_f(q->ring, &data[0]) == 0) {
- dequeue_cnt = 1;
+ if (q->dequeue_f) {
+ if (q->dequeue_f(q->ring, &data[0]) == 0) {
+ dequeue_cnt = 1;
+ }
}
} else {
dequeue_cnt = q->dequeue_burst_f(q->ring, data, burst_cnt);
@@ -178,14 +182,15 @@ void *test_thread_producer_start(void *arg) {
}
if (cfg->ring.workload == TEST_WORKLOAD_SIMPLE) {
- enqueue_cnt = test_exec_enqueue(q, exit_data->simple_data, exit_data->simple_data_cnt, &op_latency);
+ enqueue_cnt = test_exec_enqueue(q, exit_data->simple_data, exit_data->simple_data_cnt, &op_latency, t_arg->thread_idx);
} else {
- test_data **data = test_data_create(cfg->ring.burst_cnt);
+ // 由于rmind不支持指定个数的批量出队列,为了兼容它,这里分配的空间位置entries大小。
+ test_data **data = test_data_create(cfg->ring.entries_cnt);
if (data == NULL) {
BBQ_ERR_LOG("malloc falied");
exit(-1);
}
- enqueue_cnt = test_exec_enqueue(q, data, cfg->ring.burst_cnt, &op_latency);
+ enqueue_cnt = test_exec_enqueue(q, data, cfg->ring.burst_cnt, &op_latency, t_arg->thread_idx);
for (uint32_t i = enqueue_cnt; i < cfg->ring.burst_cnt; i++) {
test_free(TEST_MODULE_DATA, data[i]);
}
@@ -230,7 +235,8 @@ void *test_thread_consumer_start(void *arg) {
uint64_t op_err_latency_ns = 0;
uint64_t data_error_cnt = 0;
char thread_name[128] = {0};
- test_data **deq_data = test_malloc(TEST_MODULE_DATA, sizeof(*deq_data) * cfg->ring.burst_cnt);
+ test_data **deq_data = test_malloc(TEST_MODULE_DATA, sizeof(*deq_data) * cfg->ring.entries_cnt);
+
snprintf(thread_name, sizeof(thread_name), "consumer:%x", exit_data->thread_id);
prctl(PR_SET_NAME, thread_name);
@@ -239,7 +245,7 @@ void *test_thread_consumer_start(void *arg) {
exit_data->metric_start = test_clock_time_get();
- uint32_t last_times = 5;
+ uint32_t last_times = 50000;
while (true) {
if ((cfg->run.deq_per_consumer > 0 && run_times >= cfg->run.deq_per_consumer) || (!cfg->run.running)) {
// 控制次数的循环或运行时间到了,检查生产者是否全部退出,且队列被消费完了
@@ -305,7 +311,7 @@ void test_check_run_time(test_cfg *cfg) {
}
pthread_t *
-test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype, int core, pthread_t *thread) {
+test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype, int core, uint16_t thread_id, pthread_t *thread) {
BBQ_DBG_LOG("thread type:%d core:%d", ttype, core);
test_thread_arg_s *arg = (test_thread_arg_s *)test_malloc(TEST_MODULE_COMMON, sizeof(test_thread_arg_s)); // 线程回收时free
arg->cfg = cfg;
@@ -313,6 +319,7 @@ test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype,
arg->ttype = ttype;
arg->core = core;
arg->busy_loop = (core + 1) * 7 % 100;
+ arg->thread_idx = thread_id;
if (ttype == TEST_THREAD_PRODUCER) {
pthread_create(thread, NULL, test_thread_producer_start, arg);
@@ -329,7 +336,7 @@ test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype,
pthread_t *test_threads_create(test_cfg *cfg, test_queue_s *q) {
// 创建生产者消费者线程
int ret;
- size_t thread_id = 0;
+ uint16_t thread_id = 0;
int core_id = 0;
size_t thread_cnt = cfg->ring.producer_cnt + cfg->ring.consumer_cnt;
pthread_t *threads = (pthread_t *)test_malloc(TEST_MODULE_COMMON, sizeof(pthread_t) * thread_cnt); // 存储所有线程ID的数组
@@ -339,17 +346,21 @@ pthread_t *test_threads_create(test_cfg *cfg, test_queue_s *q) {
// 如果数量不同,则在最后分配剩余部分。
if (cfg->ring.producer_cnt == 1 && cfg->ring.consumer_cnt >= 1) {
// SPMC,第一个核心给生产者,其他分配给消费者
- test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
for (int i = 0; i < cfg->ring.consumer_cnt; i++) {
CORE_ID_CHK_SET(core_id, cfg->base.cores_cnt);
- test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
}
} else if (cfg->ring.consumer_cnt == 1 && cfg->ring.producer_cnt >= 1) {
// MPSC,第一个核心给消费者,其他分配给生产者
- test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
for (int i = 0; i < cfg->ring.producer_cnt; i++) {
CORE_ID_CHK_SET(core_id, cfg->base.cores_cnt);
- test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
}
} else {
// MPMC 或 只有生产者 或这有消费者,核心交错分配
@@ -358,22 +369,26 @@ pthread_t *test_threads_create(test_cfg *cfg, test_queue_s *q) {
for (core_id = 0; core_id < cfg->base.cores_cnt && pcnt > 0 && ccnt > 0;) {
if ((core_id & 1) == 0) {
// 偶数
- test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
pcnt--;
} else {
- test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
ccnt--;
}
CORE_ID_CHK_SET(core_id, cfg->base.cores_cnt);
}
for (int i = 0; i < pcnt; i++) {
- test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_PRODUCER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
CORE_ID_CHK_SET(core_id, cfg->base.cores_cnt);
}
for (int i = 0; i < ccnt; i++) {
- test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, &(threads[thread_id++]));
+ test_one_thread_create(cfg, q, TEST_THREAD_CONSUMER, core_id, thread_id, &(threads[thread_id]));
+ thread_id++;
CORE_ID_CHK_SET(core_id, cfg->base.cores_cnt);
}
}
diff --git a/tests/common/test_queue.h b/tests/common/test_queue.h
index 92afc9f..0d6454f 100644
--- a/tests/common/test_queue.h
+++ b/tests/common/test_queue.h
@@ -1,6 +1,6 @@
/*
* @Author: liuyu
- * @LastEditTime: 2024-06-06 12:07:11
+ * @LastEditTime: 2024-06-06 16:39:11
* @Describe: TODO
*/
@@ -15,23 +15,24 @@
typedef void (*test_ring_free_f)(void *ring);
typedef int (*test_ring_enqueue_f)(void *ring, void *obj);
typedef int (*test_ring_dequeue_f)(void *ring, void *obj);
-typedef uint32_t (*test_enqueue_burst_f)(void *ring, void *obj_table, size_t n, unsigned int flags);
+typedef uint32_t (*test_enqueue_burst_f)(void *ring, void *obj_table, size_t n, unsigned int flags, uint16_t thread_idx);
typedef uint32_t (*test_dequeue_burst_f)(void *ring, void *obj_table, uint32_t n);
typedef bool (*test_ring_empty_f)(void *ring);
typedef struct {
+ void *ring;
test_ring_type ring_type;
test_ring_free_f ring_free_f;
test_ring_enqueue_f enqueue_f;
test_ring_dequeue_f dequeue_f;
test_enqueue_burst_f enqueue_burst_f;
test_dequeue_burst_f dequeue_burst_f;
- void *ring;
} test_queue_s;
typedef struct {
int core;
- uint32_t busy_loop; // 忙循环次数
+ uint16_t thread_idx; // 线程索引,不是pthread_id
+ uint32_t busy_loop; // 忙循环次数
test_thread_type_e ttype;
test_cfg *cfg;
test_queue_s *q;
@@ -79,24 +80,22 @@ typedef struct {
extern void test_threads_destory(pthread_t *threads);
extern pthread_t *test_threads_create(test_cfg *cfg, test_queue_s *q);
-extern pthread_t *test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype, int core, pthread_t *thread);
+extern pthread_t *test_one_thread_create(test_cfg *cfg, test_queue_s *q, test_thread_type_e ttype, int core, uint16_t thread_id, pthread_t *thread);
extern void test_check_run_time(test_cfg *cfg);
extern void *test_thread_consumer_start(void *arg);
extern void *test_thread_producer_start(void *arg);
extern uint32_t test_exec_dequeue(test_queue_s *q, test_data **data, size_t burst_cnt, test_time_metric *op_use_diff);
-extern uint32_t test_exec_enqueue(test_queue_s *q, test_data **data, size_t burst_cnt, test_time_metric *op_use_diff);
+extern uint32_t test_exec_enqueue(test_queue_s *q, test_data **data, size_t burst_cnt, test_time_metric *op_use_diff, uint16_t thread_idx);
extern test_exit_data *test_exit_data_destory(test_exit_data *data);
extern test_exit_data *test_exit_data_create(test_thread_arg_s *t_arg);
extern void test_wait_all_threads_ready(test_cfg *cfg);
extern void test_queue_destory(test_queue_s *q);
extern int test_queue_init_bbq(test_cfg *cfg, test_queue_s *q);
extern void test_merge_all_data(test_exit_data **exit_data, uint32_t thread_cnt, test_merge_s *merge);
-
extern uint64_t bbq_idx(bbq_queue_s *q, uint64_t x);
extern uint64_t bbq_off(bbq_queue_s *q, uint64_t x);
extern uint64_t bbq_head_vsn(bbq_queue_s *q, uint64_t x);
extern uint64_t bbq_cur_vsn(bbq_queue_s *q, uint64_t x);
-
extern test_data **test_data_create(size_t cnt);
extern void test_data_destory(test_data **data, size_t cnt);
#endif \ No newline at end of file