improve ordq
This commit is contained in:
parent
48ab2e60a2
commit
f44ad07116
5 changed files with 50 additions and 43 deletions
|
|
@ -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 int (*task_run_fn_t)(delay_task_entry_fn_t, void*);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
time_t nextrun;
|
||||||
int run_period;
|
int run_period;
|
||||||
int runcount;
|
int runcount;
|
||||||
delay_task_entry_fn_t entry;
|
delay_task_entry_fn_t entry;
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,14 @@
|
||||||
|
|
||||||
#include "mylock.h"
|
#include "mylock.h"
|
||||||
|
|
||||||
typedef void* ordkey_t;
|
|
||||||
|
|
||||||
typedef struct _ordq_item {
|
typedef struct _ordq_item {
|
||||||
struct _ordq_item* next;
|
struct _ordq_item* next;
|
||||||
ordkey_t key;
|
|
||||||
void* data;
|
void* data;
|
||||||
} ordq_item_t;
|
} 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 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 {
|
typedef struct {
|
||||||
mylock_t lock;
|
mylock_t lock;
|
||||||
|
|
@ -26,11 +23,9 @@ typedef struct {
|
||||||
void* ctx;
|
void* ctx;
|
||||||
} ordq_t;
|
} 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 int ordq_init(ordq_t*, ordq_data_killer_t, ordq_cmp_fn_t);
|
||||||
extern void ordq_fini(ordq_t* q);
|
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_get(ordq_t*, ordq_skip_fn_t);
|
||||||
extern ordq_item_t* ordq_peek(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*);
|
extern void ordq_set_ctx(ordq_t*, void*);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ static void* delay_worker(void* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
if ((time_t)it->key > now) {
|
t = (delay_task_t*)it->data;
|
||||||
|
if (t->nextrun > now) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +44,8 @@ static void* delay_worker(void* args)
|
||||||
time_t nextrun = now + t->run_period;
|
time_t nextrun = now + t->run_period;
|
||||||
|
|
||||||
/* put back to taskq as it need to be run again */
|
/* 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);
|
FREEUP(it);
|
||||||
|
|
@ -52,8 +54,13 @@ static void* delay_worker(void* args)
|
||||||
return NULL;
|
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) {
|
if (k1 > k2) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +106,7 @@ int delaymgr_init(delaymgr_t* mgr, int precision, task_run_fn_t runner_fn)
|
||||||
mgr->worker = 0;
|
mgr->worker = 0;
|
||||||
|
|
||||||
ordq_init(&(mgr->tasks), (ordq_data_killer_t)delay_task_killer,
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -183,10 +190,11 @@ int delay_task(delaymgr_t* mgr, int delay, int runcount,
|
||||||
|
|
||||||
ts_nextrun = now + delay;
|
ts_nextrun = now + delay;
|
||||||
|
|
||||||
|
t->nextrun = ts_nextrun;
|
||||||
t->runcount = runcount;
|
t->runcount = runcount;
|
||||||
t->run_period = delay;
|
t->run_period = delay;
|
||||||
t->entry = entry;
|
t->entry = entry;
|
||||||
t->args = args;
|
t->args = args;
|
||||||
|
|
||||||
return ordq_put(&(mgr->tasks), (void*)ts_nextrun, t);
|
return ordq_put(&(mgr->tasks), t);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ static int ordq_put_(ordq_t* q, ordq_item_t* it)
|
||||||
ordq_item_t** p = &(q->head);
|
ordq_item_t** p = &(q->head);
|
||||||
|
|
||||||
while ((*p) != NULL) {
|
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 */
|
/* we found the location to insert */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ static int ordq_put_(ordq_t* q, ordq_item_t* it)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ordq_put(ordq_t* q, ordkey_t key, void* data)
|
int ordq_put(ordq_t* q, void* data)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
ordq_item_t* it;
|
ordq_item_t* it;
|
||||||
|
|
@ -50,7 +50,6 @@ int ordq_put(ordq_t* q, ordkey_t key, void* data)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
it->key = key;
|
|
||||||
it->data = data;
|
it->data = data;
|
||||||
|
|
||||||
mylock_lock(&(q->lock));
|
mylock_lock(&(q->lock));
|
||||||
|
|
@ -67,7 +66,7 @@ void ordq_fini(ordq_t* q)
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
ordq_item_t* p1 = p->next;
|
ordq_item_t* p1 = p->next;
|
||||||
|
|
||||||
if (p->data != NULL) {
|
if (q->killer != NULL) {
|
||||||
q->killer(p->data);
|
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);
|
ordq_item_t** p = &(q->head);
|
||||||
|
|
||||||
while ((*p) != NULL) {
|
while ((*p) != NULL) {
|
||||||
if ((skipfn == NULL) || !skipfn(q->ctx, (*p))) {
|
if ((skipfn == NULL) || !skipfn(q->ctx, (*p)->data)) {
|
||||||
ordq_item_t* it = (*p);
|
ordq_item_t* it = (*p);
|
||||||
*p = it->next;
|
*p = it->next;
|
||||||
it->next = NULL;
|
it->next = NULL;
|
||||||
|
|
@ -116,7 +115,7 @@ ordq_item_t* ordq_peek(ordq_t* q, ordq_skip_fn_t skipfn)
|
||||||
mylock_lock(&(q->lock));
|
mylock_lock(&(q->lock));
|
||||||
it = q->head;
|
it = q->head;
|
||||||
while (it != NULL) {
|
while (it != NULL) {
|
||||||
if ((skipfn == NULL) || !skipfn(q->ctx, it)) {
|
if ((skipfn == NULL) || !skipfn(q->ctx, it->data)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "utils.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) {
|
if ((long)k1 < (long)k2) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -31,13 +31,13 @@ static void test_ordq_get(void)
|
||||||
TEST_ASSERT_TRUE(rc >= 0);
|
TEST_ASSERT_TRUE(rc >= 0);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
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++) {
|
for (i = 0; i < 8; i++) {
|
||||||
it = ordq_get(&q, NULL);
|
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);
|
free(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,8 +46,9 @@ static void test_ordq_get(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_skip(void *ctx, ordq_item_t *data) {
|
static int test_skip(void* ctx, void* data)
|
||||||
int val = (int)(long)data->key;
|
{
|
||||||
|
int val = (int)(long)data;
|
||||||
|
|
||||||
return (val % 2 != 0);
|
return (val % 2 != 0);
|
||||||
}
|
}
|
||||||
|
|
@ -65,31 +66,32 @@ static void test_ordq_get_skip(void)
|
||||||
TEST_ASSERT_TRUE(rc >= 0);
|
TEST_ASSERT_TRUE(rc >= 0);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
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++) {
|
for (i = 0; i < 5; i++) {
|
||||||
it = ordq_get(&q, test_skip);
|
it = ordq_get(&q, test_skip);
|
||||||
|
|
||||||
if ( it == NULL) {
|
if (it == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nc ++;
|
nc++;
|
||||||
|
|
||||||
while((j < 8) && (val[j] % 2 != 0)) {
|
while ((j < 8) && (val[j] % 2 != 0)) {
|
||||||
j ++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(it->key == mk_ordkey(val[j]));
|
TEST_ASSERT_TRUE((int)(long)it->data == (val[j]));
|
||||||
free(it);
|
free(it);
|
||||||
|
|
||||||
j ++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_ASSERT_TRUE(nc == 5);
|
TEST_ASSERT_TRUE(nc == 5);
|
||||||
|
|
||||||
ordq_fini(&q);
|
ordq_fini(&q);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -108,13 +110,13 @@ static void test_ordq_peek(void)
|
||||||
TEST_ASSERT_TRUE(rc >= 0);
|
TEST_ASSERT_TRUE(rc >= 0);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
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++) {
|
for (i = 0; i < 8; i++) {
|
||||||
it = ordq_peek(&q, NULL); /* ordq_peek() will not remove item from q */
|
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);
|
ordq_fini(&q);
|
||||||
|
|
@ -122,8 +124,9 @@ static void test_ordq_peek(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_skip2(void *ctx, ordq_item_t *data) {
|
static int test_skip2(void* ctx, void* data)
|
||||||
int val = (int)(long)data->key;
|
{
|
||||||
|
int val = (int)(long)data;
|
||||||
|
|
||||||
return (val % 3 != 0);
|
return (val % 3 != 0);
|
||||||
}
|
}
|
||||||
|
|
@ -141,13 +144,14 @@ static void test_ordq_peek_skip(void)
|
||||||
TEST_ASSERT_TRUE(rc >= 0);
|
TEST_ASSERT_TRUE(rc >= 0);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
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++) {
|
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);
|
ordq_fini(&q);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue