updated the timer job scheduler to use a direct index holder pointer

This commit is contained in:
hyung-hwan 2016-01-31 05:39:12 +00:00
parent 702a008fbb
commit e0736bd657
5 changed files with 78 additions and 38 deletions

View File

@ -42,28 +42,16 @@
#define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count) #define STIO_MEMMOVE(dst,src,count) memmove(dst,src,count)
#define STIO_ASSERT assert #define STIO_ASSERT assert
typedef void (*stio_tmr_handler_t) (
stio_t* stio,
const stio_ntime_t* now,
stio_tmrjob_t* evt
);
typedef void (*stio_updtmrjobr_t) (
stio_t* stio,
stio_tmridx_t old_index,
stio_tmridx_t new_index,
stio_tmrjob_t* evt
);
struct stio_tmrjob_t struct stio_tmrjob_t
{ {
void* ctx; void* ctx;
stio_ntime_t when; stio_ntime_t when;
stio_tmr_handler_t handler; stio_tmrjob_handler_t handler;
stio_updtmrjobr_t updater; #if defined(STIO_USE_TMRJOB_IDXPTR)
stio_tmridx_t* idxptr; /* pointer to the index holder */
#else
stio_tmrjob_updater_t updater;
#endif
}; };
#define STIO_TMRIDX_INVALID ((stio_tmridx_t)-1) #define STIO_TMRIDX_INVALID ((stio_tmridx_t)-1)

View File

@ -170,11 +170,15 @@ static void tmr_connect_handle (stio_t* stio, const stio_ntime_t* now, stio_tmrj
} }
} }
#if defined(STIO_USE_TMRJOB_IDXPTR)
/* nothing to define */
#else
static void tmr_connect_update (stio_t* stio, stio_tmridx_t old_index, stio_tmridx_t new_index, stio_tmrjob_t* job) static void tmr_connect_update (stio_t* stio, stio_tmridx_t old_index, stio_tmridx_t new_index, stio_tmrjob_t* job)
{ {
stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx; stio_dev_tcp_t* tcp = (stio_dev_tcp_t*)job->ctx;
tcp->tmridx_connect = new_index; tcp->tmridx_connect = new_index;
} }
#endif
static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg) static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
@ -245,7 +249,11 @@ static int tcp_ioctl (stio_dev_t* dev, int cmd, void* arg)
stio_gettime (&tmrjob.when); stio_gettime (&tmrjob.when);
stio_addtime (&tmrjob.when, &conn->timeout, &tmrjob.when); stio_addtime (&tmrjob.when, &conn->timeout, &tmrjob.when);
tmrjob.handler = tmr_connect_handle; tmrjob.handler = tmr_connect_handle;
#if defined(STIO_USE_TMRJOB_IDXPTR)
tmrjob.idxptr = &tcp->tmridx_connect;
#else
tmrjob.updater = tmr_connect_update; tmrjob.updater = tmr_connect_update;
#endif
STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID); STIO_ASSERT (tcp->tmridx_connect == STIO_TMRIDX_INVALID);
tcp->tmridx_connect = stio_instmrjob (tcp->stio, &tmrjob); tcp->tmridx_connect = stio_instmrjob (tcp->stio, &tmrjob);

View File

@ -79,17 +79,6 @@
#define STIO_SEC_TO_USEC(sec) ((sec) * STIO_USECS_PER_SEC) #define STIO_SEC_TO_USEC(sec) ((sec) * STIO_USECS_PER_SEC)
#define STIO_USEC_TO_SEC(usec) ((usec) / STIO_USECS_PER_SEC) #define STIO_USEC_TO_SEC(usec) ((usec) / STIO_USECS_PER_SEC)
/**
* The stio_ntime_t type defines a numeric time type expressed in the
* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970).
*/
typedef struct stio_ntime_t stio_ntime_t;
struct stio_ntime_t
{
stio_intptr_t sec;
stio_int32_t nsec; /* nanoseconds */
};
#define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns))) #define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
#define stio_cleartime(x) stio_inittime(x,0,0) #define stio_cleartime(x) stio_inittime(x,0,0)
/*#define stio_cleartime(x) ((x)->sec = (x)->nsec = 0)*/ /*#define stio_cleartime(x) ((x)->sec = (x)->nsec = 0)*/

View File

@ -55,7 +55,11 @@ static stio_tmridx_t sift_up (stio_t* stio, stio_tmridx_t index, int notify)
{ {
/* move down the parent to my current position */ /* move down the parent to my current position */
stio->tmr.jobs[index] = stio->tmr.jobs[parent]; stio->tmr.jobs[index] = stio->tmr.jobs[parent];
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#else
stio->tmr.jobs[index].updater (stio, parent, index, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, parent, index, &stio->tmr.jobs[index]);
#endif
/* traverse up */ /* traverse up */
index = parent; index = parent;
@ -63,12 +67,16 @@ static stio_tmridx_t sift_up (stio_t* stio, stio_tmridx_t index, int notify)
} }
while (index > 0 && YOUNGER_THAN(&item, &stio->tmr.jobs[parent])); while (index > 0 && YOUNGER_THAN(&item, &stio->tmr.jobs[parent]));
stio->tmr.jobs[index] = item;
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#else
/* we send no notification if the item is added with stio_instmrjob() /* we send no notification if the item is added with stio_instmrjob()
* or updated with stio_updtmrjob(). the caller of these functions * or updated with stio_updtmrjob(). the caller of these functions
* must rely on the return value. */ * must rely on the return value. */
stio->tmr.jobs[index] = item;
if (notify && index != old_index) if (notify && index != old_index)
stio->tmr.jobs[index].updater (stio, old_index, index, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, old_index, index, &stio->tmr.jobs[index]);
#endif
} }
return index; return index;
@ -105,15 +113,23 @@ static stio_tmridx_t sift_down (stio_t* stio, stio_tmridx_t index, int notify)
if (YOUNGER_THAN(&item, &stio->tmr.jobs[younger])) break; if (YOUNGER_THAN(&item, &stio->tmr.jobs[younger])) break;
stio->tmr.jobs[index] = stio->tmr.jobs[younger]; stio->tmr.jobs[index] = stio->tmr.jobs[younger];
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#else
stio->tmr.jobs[index].updater (stio, younger, index, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, younger, index, &stio->tmr.jobs[index]);
#endif
index = younger; index = younger;
} }
while (index < base); while (index < base);
stio->tmr.jobs[index] = item; stio->tmr.jobs[index] = item;
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#else
if (notify && index != old_index) if (notify && index != old_index)
stio->tmr.jobs[index].updater (stio, old_index, index, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, old_index, index, &stio->tmr.jobs[index]);
#endif
} }
return index; return index;
@ -126,13 +142,21 @@ void stio_deltmrjob (stio_t* stio, stio_tmridx_t index)
STIO_ASSERT (index < stio->tmr.size); STIO_ASSERT (index < stio->tmr.size);
item = stio->tmr.jobs[index]; item = stio->tmr.jobs[index];
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = STIO_TMRIDX_INVALID;
#else
stio->tmr.jobs[index].updater (stio, index, STIO_TMRIDX_INVALID, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, index, STIO_TMRIDX_INVALID, &stio->tmr.jobs[index]);
#endif
stio->tmr.size = stio->tmr.size - 1; stio->tmr.size = stio->tmr.size - 1;
if (stio->tmr.size > 0 && index != stio->tmr.size) if (stio->tmr.size > 0 && index != stio->tmr.size)
{ {
stio->tmr.jobs[index] = stio->tmr.jobs[stio->tmr.size]; stio->tmr.jobs[index] = stio->tmr.jobs[stio->tmr.size];
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#else
stio->tmr.jobs[index].updater (stio, stio->tmr.size, index, &stio->tmr.jobs[index]); stio->tmr.jobs[index].updater (stio, stio->tmr.size, index, &stio->tmr.jobs[index]);
#endif
YOUNGER_THAN(&stio->tmr.jobs[index], &item)? sift_up(stio, index, 1): sift_down(stio, index, 1); YOUNGER_THAN(&stio->tmr.jobs[index], &item)? sift_up(stio, index, 1): sift_down(stio, index, 1);
} }
} }
@ -161,6 +185,9 @@ stio_tmridx_t stio_instmrjob (stio_t* stio, const stio_tmrjob_t* job)
stio->tmr.size = stio->tmr.size + 1; stio->tmr.size = stio->tmr.size + 1;
stio->tmr.jobs[index] = *job; stio->tmr.jobs[index] = *job;
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#endif
return sift_up (stio, index, 0); return sift_up (stio, index, 0);
} }
@ -169,13 +196,16 @@ stio_tmridx_t stio_updtmrjob (stio_t* stio, stio_size_t index, const stio_tmrjob
stio_tmrjob_t item; stio_tmrjob_t item;
item = stio->tmr.jobs[index]; item = stio->tmr.jobs[index];
stio->tmr.jobs[index] = *job; stio->tmr.jobs[index] = *job;
#if defined(STIO_USE_TMRJOB_IDXPTR)
if (stio->tmr.jobs[index].idxptr) *stio->tmr.jobs[index].idxptr = index;
#endif
return YOUNGER_THAN(job, &item)? sift_up (stio, index, 0): sift_down (stio, index, 0); return YOUNGER_THAN(job, &item)? sift_up (stio, index, 0): sift_down (stio, index, 0);
} }
void stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm, stio_size_t* firecnt) void stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm, stio_size_t* firecnt)
{ {
stio_ntime_t now; stio_ntime_t now;
stio_tmrjob_t event; stio_tmrjob_t tmrjob;
stio_size_t count = 0; stio_size_t count = 0;
/* if the current time is not specified, get it from the system */ /* if the current time is not specified, get it from the system */
@ -186,11 +216,11 @@ void stio_firetmrjobs (stio_t* stio, const stio_ntime_t* tm, stio_size_t* firecn
{ {
if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break; if (stio_cmptime(&stio->tmr.jobs[0].when, &now) > 0) break;
event = stio->tmr.jobs[0]; tmrjob = stio->tmr.jobs[0]; /* copy the scheduled job */
stio_deltmrjob (stio, 0); /* remove the registered job */ stio_deltmrjob (stio, 0); /* deschedule the job */
count++; count++;
event.handler (stio, &now, &event); /* then fire the job */ tmrjob.handler (stio, &now, &tmrjob); /* then fire the job */
} }
if (firecnt) *firecnt = count; if (firecnt) *firecnt = count;

View File

@ -29,8 +29,17 @@
#include <stio-cmn.h> #include <stio-cmn.h>
typedef struct stio_tmrjob_t stio_tmrjob_t; /**
typedef stio_size_t stio_tmridx_t; * The stio_ntime_t type defines a numeric time type expressed in the
* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970).
*/
typedef struct stio_ntime_t stio_ntime_t;
struct stio_ntime_t
{
stio_intptr_t sec;
stio_int32_t nsec; /* nanoseconds */
};
struct stio_sckadr_t struct stio_sckadr_t
{ {
@ -233,6 +242,22 @@ enum stio_dev_event_flag_t
typedef enum stio_dev_event_flag_t stio_dev_event_flag_t; typedef enum stio_dev_event_flag_t stio_dev_event_flag_t;
typedef struct stio_tmrjob_t stio_tmrjob_t;
typedef stio_size_t stio_tmridx_t;
typedef void (*stio_tmrjob_handler_t) (
stio_t* stio,
const stio_ntime_t* now,
stio_tmrjob_t* tmrjob
);
typedef void (*stio_tmrjob_updater_t) (
stio_t* stio,
stio_tmridx_t old_index,
stio_tmridx_t new_index,
stio_tmrjob_t* tmrjob
);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif