improve ordq

This commit is contained in:
Rongsong Shen 2025-12-17 15:28:27 +08:00
parent 48ab2e60a2
commit f44ad07116
5 changed files with 50 additions and 43 deletions

View file

@ -13,6 +13,7 @@ typedef int (*delay_task_entry_fn_t)(void*);
typedef int (*task_run_fn_t)(delay_task_entry_fn_t, void*);
typedef struct {
time_t nextrun;
int run_period;
int runcount;
delay_task_entry_fn_t entry;

View file

@ -6,17 +6,14 @@
#include "mylock.h"
typedef void* ordkey_t;
typedef struct _ordq_item {
struct _ordq_item* next;
ordkey_t key;
void* data;
} ordq_item_t;
typedef int (*ordq_cmp_fn_t)(void*, ordkey_t, ordkey_t);
typedef int (*ordq_cmp_fn_t)(void*, void*, void*);
typedef void (*ordq_data_killer_t)(void*);
typedef int (*ordq_skip_fn_t)(void*, ordq_item_t*);
typedef int (*ordq_skip_fn_t)(void*, void*);
typedef struct {
mylock_t lock;
@ -26,11 +23,9 @@ typedef struct {
void* ctx;
} ordq_t;
#define mk_ordkey(k) (ordkey_t)((long)(k))
extern int ordq_init(ordq_t*, ordq_data_killer_t, ordq_cmp_fn_t);
extern void ordq_fini(ordq_t* q);
extern int ordq_put(ordq_t*, ordkey_t, void*);
extern int ordq_put(ordq_t*, void*);
extern ordq_item_t* ordq_get(ordq_t*, ordq_skip_fn_t);
extern ordq_item_t* ordq_peek(ordq_t*, ordq_skip_fn_t);
extern void ordq_set_ctx(ordq_t*, void*);

View file

@ -25,7 +25,8 @@ static void* delay_worker(void* args)
}
now = time(NULL);
if ((time_t)it->key > now) {
t = (delay_task_t*)it->data;
if (t->nextrun > now) {
continue;
}
@ -43,7 +44,8 @@ static void* delay_worker(void* args)
time_t nextrun = now + t->run_period;
/* put back to taskq as it need to be run again */
ordq_put(&(mgr->tasks), (void*)nextrun, t);
t->nextrun = nextrun;
ordq_put(&(mgr->tasks), t);
}
FREEUP(it);
@ -52,8 +54,13 @@ static void* delay_worker(void* args)
return NULL;
}
static int time_cmp(time_t k1, time_t k2)
static int task_cmp(void* arg1, void* arg2)
{
delay_task_t* t1 = (delay_task_t*)arg1;
delay_task_t* t2 = (delay_task_t*)arg2;
time_t k1 = t1->nextrun;
time_t k2 = t2->nextrun;
if (k1 > k2) {
return 1;
}
@ -99,7 +106,7 @@ int delaymgr_init(delaymgr_t* mgr, int precision, task_run_fn_t runner_fn)
mgr->worker = 0;
ordq_init(&(mgr->tasks), (ordq_data_killer_t)delay_task_killer,
(ordq_cmp_fn_t)time_cmp);
(ordq_cmp_fn_t)task_cmp);
return 0;
}
@ -183,10 +190,11 @@ int delay_task(delaymgr_t* mgr, int delay, int runcount,
ts_nextrun = now + delay;
t->nextrun = ts_nextrun;
t->runcount = runcount;
t->run_period = delay;
t->entry = entry;
t->args = args;
return ordq_put(&(mgr->tasks), (void*)ts_nextrun, t);
return ordq_put(&(mgr->tasks), t);
}

View file

@ -26,7 +26,7 @@ static int ordq_put_(ordq_t* q, ordq_item_t* it)
ordq_item_t** p = &(q->head);
while ((*p) != NULL) {
if (q->cmp(q->ctx, (*p)->key, it->key) > 0) {
if (q->cmp(q->ctx, (*p)->data, it->data) > 0) {
/* we found the location to insert */
break;
}
@ -40,7 +40,7 @@ static int ordq_put_(ordq_t* q, ordq_item_t* it)
return 0;
}
int ordq_put(ordq_t* q, ordkey_t key, void* data)
int ordq_put(ordq_t* q, void* data)
{
int rc = 0;
ordq_item_t* it;
@ -50,7 +50,6 @@ int ordq_put(ordq_t* q, ordkey_t key, void* data)
return -ENOMEM;
}
it->key = key;
it->data = data;
mylock_lock(&(q->lock));
@ -67,7 +66,7 @@ void ordq_fini(ordq_t* q)
while (p != NULL) {
ordq_item_t* p1 = p->next;
if (p->data != NULL) {
if (q->killer != NULL) {
q->killer(p->data);
}
@ -85,7 +84,7 @@ static ordq_item_t* ordq_get_(ordq_t* q, ordq_skip_fn_t skipfn)
ordq_item_t** p = &(q->head);
while ((*p) != NULL) {
if ((skipfn == NULL) || !skipfn(q->ctx, (*p))) {
if ((skipfn == NULL) || !skipfn(q->ctx, (*p)->data)) {
ordq_item_t* it = (*p);
*p = it->next;
it->next = NULL;
@ -116,7 +115,7 @@ ordq_item_t* ordq_peek(ordq_t* q, ordq_skip_fn_t skipfn)
mylock_lock(&(q->lock));
it = q->head;
while (it != NULL) {
if ((skipfn == NULL) || !skipfn(q->ctx, it)) {
if ((skipfn == NULL) || !skipfn(q->ctx, it->data)) {
break;
}

View file

@ -7,7 +7,7 @@
#include "unity.h"
#include "utils.h"
static int long_cmp(void* ctx, ordkey_t k1, ordkey_t k2)
static int long_cmp(void* ctx, void* k1, void* k2)
{
if ((long)k1 < (long)k2) {
return -1;
@ -31,13 +31,13 @@ static void test_ordq_get(void)
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 8; i++) {
ordq_put(&q, mk_ordkey(keys[i]), (void*)NULL);
ordq_put(&q, (void*)(long)(keys[i]));
}
for (i = 0; i < 8; i++) {
it = ordq_get(&q, NULL);
TEST_ASSERT_TRUE((it != NULL) && (it->key == mk_ordkey(val[i])));
TEST_ASSERT_TRUE((it != NULL) && ((int)(long)it->data == val[i]));
free(it);
}
@ -46,8 +46,9 @@ static void test_ordq_get(void)
return;
}
static int test_skip(void *ctx, ordq_item_t *data) {
int val = (int)(long)data->key;
static int test_skip(void* ctx, void* data)
{
int val = (int)(long)data;
return (val % 2 != 0);
}
@ -65,31 +66,32 @@ static void test_ordq_get_skip(void)
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 8; i++) {
ordq_put(&q, mk_ordkey(keys[i]), (void*)NULL);
ordq_put(&q, (void*)(long)(keys[i]));
}
j = 0; nc = 0;
j = 0;
nc = 0;
for (i = 0; i < 5; i++) {
it = ordq_get(&q, test_skip);
if ( it == NULL) {
if (it == NULL) {
break;
}
nc ++;
while((j < 8) && (val[j] % 2 != 0)) {
j ++;
nc++;
while ((j < 8) && (val[j] % 2 != 0)) {
j++;
}
TEST_ASSERT_TRUE(it->key == mk_ordkey(val[j]));
TEST_ASSERT_TRUE((int)(long)it->data == (val[j]));
free(it);
j ++;
j++;
}
TEST_ASSERT_TRUE(nc == 5);
ordq_fini(&q);
return;
@ -108,13 +110,13 @@ static void test_ordq_peek(void)
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 8; i++) {
ordq_put(&q, mk_ordkey(keys[i]), (void*)NULL);
ordq_put(&q, (void*)(long)(keys[i]));
}
for (i = 0; i < 8; i++) {
it = ordq_peek(&q, NULL); /* ordq_peek() will not remove item from q */
TEST_ASSERT_TRUE((it != NULL) && (it->key == mk_ordkey(val[0])));
TEST_ASSERT_TRUE((it != NULL) && ((int)(long)it->data == (val[0])));
}
ordq_fini(&q);
@ -122,8 +124,9 @@ static void test_ordq_peek(void)
return;
}
static int test_skip2(void *ctx, ordq_item_t *data) {
int val = (int)(long)data->key;
static int test_skip2(void* ctx, void* data)
{
int val = (int)(long)data;
return (val % 3 != 0);
}
@ -141,13 +144,14 @@ static void test_ordq_peek_skip(void)
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 8; i++) {
ordq_put(&q, mk_ordkey(keys[i]), (void*)NULL);
ordq_put(&q, (void*)(long)(keys[i]));
}
for (i = 0; i < 8; i++) {
it = ordq_peek(&q, test_skip2); /* ordq_peek() will not remove item from q */
it = ordq_peek(
&q, test_skip2); /* ordq_peek() will not remove item from q */
TEST_ASSERT_TRUE((it != NULL) && (it->key == mk_ordkey(val[4])));
TEST_ASSERT_TRUE((it != NULL) && ((int)(long)it->data == val[4]));
}
ordq_fini(&q);