added simple time calculation types/functiosn/macros.
fixed a bug in timed semaphore signalling
This commit is contained in:
parent
63ce721147
commit
6487143a59
@ -53,6 +53,15 @@
|
||||
{
|
||||
^sp.
|
||||
}
|
||||
|
||||
#method sleep: seconds
|
||||
{
|
||||
| s |
|
||||
s := Semaphore new.
|
||||
Processor signal: s after: seconds.
|
||||
## Processor activeProcess dump.
|
||||
s wait.
|
||||
}
|
||||
}
|
||||
|
||||
#class Semaphore(Object)
|
||||
@ -67,6 +76,8 @@
|
||||
self.fireTimeNsec := 0.
|
||||
}
|
||||
|
||||
## ==================================================================
|
||||
|
||||
#method signal
|
||||
{
|
||||
<primitive: #_semaphore_signal>
|
||||
@ -79,6 +90,20 @@
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method waitWithTimeout: seconds
|
||||
{
|
||||
<primitive: #_semaphore_wait>
|
||||
self primitiveFailed
|
||||
}
|
||||
|
||||
#method waitWithTimeout: seconds and: nanoSeconds
|
||||
{
|
||||
<primitive: #_semaphore_wait>
|
||||
self primitiveFailed
|
||||
}
|
||||
|
||||
## ==================================================================
|
||||
|
||||
#method heapIndex
|
||||
{
|
||||
^heapIndex
|
||||
@ -302,12 +327,6 @@
|
||||
^self.active.
|
||||
}
|
||||
|
||||
#method sleep: anInteger
|
||||
{
|
||||
<primitive: #_processor_sleep>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method resume: aProcess
|
||||
{
|
||||
<primitive: #_processor_schedule>
|
||||
@ -329,12 +348,6 @@
|
||||
"
|
||||
}
|
||||
|
||||
#method remove: aProcess
|
||||
{
|
||||
"<primitive: #_processor_remove>"
|
||||
"TODO: "
|
||||
}
|
||||
|
||||
"
|
||||
#method yield
|
||||
{
|
||||
@ -354,4 +367,17 @@
|
||||
<primitive: #_processor_add_timed_semaphore>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method unsignal: aSemaphore
|
||||
{
|
||||
<primitive: #_processor_remove_semaphore>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
"#method signal: aSemaphore onInput: file
|
||||
{
|
||||
}"
|
||||
"#method signal: aSemaphore onOutput: file
|
||||
{
|
||||
}"
|
||||
}
|
||||
|
176
stix/lib/exec.c
176
stix/lib/exec.c
@ -157,6 +157,21 @@
|
||||
#endif
|
||||
|
||||
|
||||
static STIX_INLINE void vm_gettime (stix_ntime_t* now)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime (CLOCK_MONOTONIC, &ts);
|
||||
STIX_INITNTIME(now, ts.tv_sec, ts.tv_nsec);
|
||||
}
|
||||
|
||||
static STIX_INLINE void vm_sleep (const stix_ntime_t* dur)
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = dur->sec;
|
||||
ts.tv_nsec = dur->nsec;
|
||||
nanosleep (&ts, STIX_NULL);
|
||||
}
|
||||
|
||||
static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
@ -415,12 +430,11 @@ static void terminate_process (stix_t* stix, stix_oop_process_t proc)
|
||||
|
||||
static void resume_process (stix_t* stix, stix_oop_process_t proc)
|
||||
{
|
||||
printf ("TO RESUME PROCESS = %p %d\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_SUSPENDED))
|
||||
{
|
||||
/* SUSPENED ---> RUNNING */
|
||||
|
||||
printf ("TO RESUME PROCESS = %p %d SUSPENED ----> RUNNING\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
//printf ("TO RESUME PROCESS = %p %d SUSPENED ----> RUNNING\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
STIX_ASSERT ((stix_oop_t)proc->prev == stix->_nil);
|
||||
STIX_ASSERT ((stix_oop_t)proc->next == stix->_nil);
|
||||
|
||||
@ -429,7 +443,7 @@ printf ("TO RESUME PROCESS = %p %d SUSPENED ----> RUNNING\n", proc, (int)STIX_OO
|
||||
/*proc->current_context = proc->initial_context;*/
|
||||
proc->state = STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE);
|
||||
|
||||
/*switch_to_process (stix, proc);*/
|
||||
/* don't switch to this process. just set the state to RUNNING */
|
||||
}
|
||||
#if 0
|
||||
else if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
|
||||
@ -455,11 +469,11 @@ static void suspend_process (stix_t* stix, stix_oop_process_t proc)
|
||||
|
||||
nrp = find_next_runnable_process (stix);
|
||||
|
||||
printf ("TO SUSPEND...%p %d\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
//printf ("TO SUSPEND...%p %d\n", proc, (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
if (nrp == proc)
|
||||
{
|
||||
/* no runnable process after suspension */
|
||||
printf ("NO RUNNABLE PROCESS AFTER SUPSENDISION\n");
|
||||
//printf ("NO RUNNABLE PROCESS AFTER SUPSENDISION\n");
|
||||
sleep_active_process (stix, PROC_STATE_RUNNABLE);
|
||||
unchain_from_processor (stix, proc, PROC_STATE_SUSPENDED);
|
||||
|
||||
@ -470,7 +484,7 @@ printf ("NO RUNNABLE PROCESS AFTER SUPSENDISION\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("SWITCHING TO XXXXXXXXXXXXXXXXXXXXx\n");
|
||||
//printf ("SWITCHING TO XXXXXXXXXXXXXXXXXXXXx\n");
|
||||
/* keep the unchained process at the runnable state for
|
||||
* the immediate call to switch_to_process() below */
|
||||
unchain_from_processor (stix, proc, PROC_STATE_RUNNABLE);
|
||||
@ -535,25 +549,34 @@ static int async_signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||
static stix_oop_process_t signal_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
stix_ooi_t count;
|
||||
|
||||
if ((stix_oop_t)sem->waiting_head == stix->_nil)
|
||||
{
|
||||
printf ("signal semaphore...1111\n");
|
||||
//printf ("signal semaphore...1111\n");
|
||||
/* no process is waiting on this semaphore */
|
||||
count = STIX_OOP_TO_SMOOI(sem->count);
|
||||
count++;
|
||||
sem->count = STIX_SMOOI_TO_OOP(count);
|
||||
|
||||
/* no process has been resumed */
|
||||
return stix->_nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("signal semaphore...2222\n");
|
||||
proc = sem->waiting_head;
|
||||
|
||||
/* [NOTE] no GC must occur as 'proc' isn't protected with stix_pushtmp(). */
|
||||
|
||||
unchain_from_semaphore (stix, proc);
|
||||
resume_process (stix, proc); /* TODO: error check */
|
||||
//printf ("signal semaphore...2222 DONE -> resumed process -> proc state %d\n", (int)STIX_OOP_TO_SMOOI(proc->state));
|
||||
|
||||
/* return the resumed process */
|
||||
return proc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,20 +591,23 @@ static void await_semaphore (stix_t* stix, stix_oop_semaphore_t sem)
|
||||
/* it's already signalled */
|
||||
count--;
|
||||
sem->count = STIX_SMOOI_TO_OOP(count);
|
||||
printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - NO SUSPENDING ...................\n");
|
||||
//printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - NO SUSPENDING ...................\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not signaled. need to wait */
|
||||
proc = stix->processor->active;
|
||||
|
||||
printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - SUEPENDING ACTIVE PROCESS...............\n");
|
||||
//printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - SUEPENDING ACTIVE PROCESS..........state=>[%d].....PROC %p\n", (int)STIX_OOP_TO_SMOOI(proc->state), proc);
|
||||
/* suspend the active process */
|
||||
suspend_process (stix, proc);
|
||||
|
||||
/* link the suspened process to the semaphore's process list */
|
||||
/* link the suspended process to the semaphore's process list */
|
||||
chain_into_semaphore (stix, proc, sem);
|
||||
|
||||
STIX_ASSERT (sem->waiting_tail == proc);
|
||||
|
||||
//printf (">>>>>>>>>>>>>> AWAIT SEMAPHORE - SUEPENDING ACTIVE PROCESS....XX......state=>[%d]..PROC %p\n", (int)STIX_OOP_TO_SMOOI(proc->state), proc);
|
||||
STIX_ASSERT (stix->processor->active != proc);
|
||||
}
|
||||
}
|
||||
@ -709,6 +735,7 @@ static void delete_from_sem_heap (stix_t* stix, stix_ooi_t index)
|
||||
lastsem->heap_index = STIX_SMOOI_TO_OOP(index);
|
||||
stix->sem_heap[index] = lastsem;
|
||||
|
||||
|
||||
if (SEM_HEAP_EARLIER_THAN(stix, lastsem, sem))
|
||||
sift_up_sem_heap (stix, index);
|
||||
else
|
||||
@ -1657,23 +1684,11 @@ static int prim_processor_schedule (stix_t* stix, stix_ooi_t nargs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_processor_remove (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
/* TODO: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prim_processor_sleep (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
/* TODO: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prim_processor_add_timed_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
stix_oop_t rcv, sec, nsec;
|
||||
stix_oop_semaphore_t sem;
|
||||
struct timespec ts, ft;
|
||||
stix_ntime_t now, ft;
|
||||
|
||||
STIX_ASSERT (nargs >= 2 || nargs <= 3);
|
||||
|
||||
@ -1710,30 +1725,17 @@ static int prim_processor_add_timed_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
*
|
||||
* this code assumes that the monotonic clock returns a small value
|
||||
* that can fit into a small integer, even after some addtions... */
|
||||
if (clock_gettime (CLOCK_MONOTONIC, &ts) == -1)
|
||||
vm_gettime (&now);
|
||||
STIX_ADDNTIMESNS (&ft, &now, STIX_OOP_TO_SMOOI(sec), STIX_OOP_TO_SMOOI(nsec));
|
||||
if (ft.sec < 0 || ft.sec > STIX_SMOOI_MAX)
|
||||
{
|
||||
/* TODO: soft error handling */
|
||||
printf ("clock_gettime() failure....\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ft.tv_nsec = ts.tv_nsec + STIX_OOP_TO_SMOOI(nsec);
|
||||
ft.tv_sec = ts.tv_sec + STIX_OOP_TO_SMOOI(sec);
|
||||
while (ft.tv_nsec >= 1000000000)
|
||||
{
|
||||
ft.tv_sec++;
|
||||
ft.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
if (ft.tv_sec < 0 || ft.tv_sec > STIX_SMOOI_MAX)
|
||||
{
|
||||
/* soft error - cannot represent the expiry time in
|
||||
/* soft error - cannot represent the e:xpiry time in
|
||||
* a small integer. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
sem->heap_ftime_sec = STIX_SMOOI_TO_OOP(ft.tv_sec);
|
||||
sem->heap_ftime_nsec = STIX_SMOOI_TO_OOP(ft.tv_nsec);
|
||||
sem->heap_ftime_sec = STIX_SMOOI_TO_OOP(ft.sec);
|
||||
sem->heap_ftime_nsec = STIX_SMOOI_TO_OOP(ft.nsec);
|
||||
|
||||
if (add_to_sem_heap (stix, sem) <= -1) return -1;
|
||||
|
||||
@ -1741,15 +1743,20 @@ printf ("clock_gettime() failure....\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int prim_processor_del_time_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
static int prim_processor_remove_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
{
|
||||
/* remove a semaphore from processor's signal scheduling */
|
||||
|
||||
stix_oop_t rcv;
|
||||
stix_oop_semaphore_t sem;
|
||||
|
||||
STIX_ASSERT (nargs == 1);
|
||||
|
||||
sem = (stix_oop_semaphore_t)ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp);
|
||||
sem = (stix_oop_semaphore_t)ACTIVE_STACK_GET(stix, stix->sp);
|
||||
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
|
||||
|
||||
/* TODO: remove a semaphore from IO handler if it's registered...
|
||||
* remove a semaphore from XXXXXXXXXXXXXX */
|
||||
|
||||
if (rcv != (stix_oop_t)stix->processor) return 0;
|
||||
if (STIX_CLASSOF(stix,sem) != stix->_semaphore) return 0;
|
||||
@ -1757,10 +1764,12 @@ static int prim_processor_del_time_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
if (STIX_OOP_IS_SMOOI(sem->heap_index) &&
|
||||
sem->heap_index != STIX_SMOOI_TO_OOP(-1))
|
||||
{
|
||||
delete_from_sem_heap (stix, STIX_OOP_TO_SMOOI(sem));
|
||||
/* the semaphore is in the timed semaphore heap */
|
||||
delete_from_sem_heap (stix, STIX_OOP_TO_SMOOI(sem->heap_index));
|
||||
STIX_ASSERT(sem->heap_index == STIX_SMOOI_TO_OOP(-1));
|
||||
}
|
||||
|
||||
ACTIVE_STACK_POPS (stix, nargs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2448,10 +2457,9 @@ static prim_t primitives[] =
|
||||
{ 0, 0, prim_semaphore_signal, "_semaphore_signal" },
|
||||
{ 0, 0, prim_semaphore_wait, "_semaphore_wait" },
|
||||
|
||||
{ 1, 1, prim_processor_schedule, "_processor_schedule" },
|
||||
{ 1, 1, prim_processor_remove, "_processor_remove" },
|
||||
{ 1, 1, prim_processor_sleep, "_processor_sleep" },
|
||||
{ 2, 3, prim_processor_add_timed_semaphore, "_processor_add_timed_semaphore" },
|
||||
{ 1, 1, prim_processor_schedule, "_processor_schedule" },
|
||||
{ 2, 3, prim_processor_add_timed_semaphore, "_processor_add_timed_semaphore" },
|
||||
{ 1, 1, prim_processor_remove_semaphore, "_processor_remove_semaphore" },
|
||||
|
||||
{ 1, 1, prim_integer_add, "_integer_add" },
|
||||
{ 1, 1, prim_integer_sub, "_integer_sub" },
|
||||
@ -2852,42 +2860,45 @@ int stix_execute (stix_t* stix)
|
||||
|
||||
while (1)
|
||||
{
|
||||
#if 0
|
||||
if (stix->processor->active == stix->nil_process)
|
||||
{
|
||||
/* no more process in the system */
|
||||
STIX_ASSERT (stix->processor->tally = STIX_SMOOI_TO_OOP(0));
|
||||
printf ("NO MORE RUNNABLE PROCESS...\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stix->sem_heap_count > 0)
|
||||
{
|
||||
struct timespec now, ft;
|
||||
|
||||
clock_gettime (CLOCK_MONOTONIC, &now);
|
||||
stix_ntime_t ft, now;
|
||||
vm_gettime (&now);
|
||||
|
||||
do
|
||||
{
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(stix->sem_heap[0]->heap_ftime_sec));
|
||||
STIX_ASSERT (STIX_OOP_IS_SMOOI(stix->sem_heap[0]->heap_ftime_nsec));
|
||||
|
||||
ft.tv_sec = STIX_OOP_TO_SMOOI(stix->sem_heap[0]->heap_ftime_sec);
|
||||
ft.tv_nsec = STIX_OOP_TO_SMOOI(stix->sem_heap[0]->heap_ftime_nsec);
|
||||
STIX_INITNTIME (&ft,
|
||||
STIX_OOP_TO_SMOOI(stix->sem_heap[0]->heap_ftime_sec),
|
||||
STIX_OOP_TO_SMOOI(stix->sem_heap[0]->heap_ftime_nsec)
|
||||
);
|
||||
|
||||
if (ft.tv_sec < now.tv_sec || (ft.tv_sec == now.tv_sec && ft.tv_nsec <= now.tv_nsec))
|
||||
if (STIX_CMPNTIME(&ft, (stix_ntime_t*)&now) <= 0)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
|
||||
proc = stix->sem_heap[0]->waiting_head;
|
||||
/* waited long enough. signal the semaphore */
|
||||
|
||||
signal_semaphore (stix, stix->sem_heap[0]);
|
||||
proc = signal_semaphore (stix, stix->sem_heap[0]);
|
||||
/* [NOTE] no stix_pushtmp() on proc. no GC must occur
|
||||
* in the following line until it's used for
|
||||
* wake_new_process() below. */
|
||||
delete_from_sem_heap (stix, 0);
|
||||
|
||||
if (stix->processor->active == stix->nil_process)
|
||||
/* if no process is waiting on the semaphore,
|
||||
* signal_semaphore() returns stix->_nil. */
|
||||
|
||||
if (stix->processor->active == stix->nil_process && (stix_oop_t)proc != stix->_nil)
|
||||
{
|
||||
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||
STIX_ASSERT (proc == stix->processor->runnable_head);
|
||||
/* this is the only runnable process.
|
||||
* switch the process to the running state.
|
||||
* it uses wake_new_process() instead of
|
||||
* switch_to_process() as there is no running
|
||||
* process at this moment */
|
||||
STIX_ASSERT (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||
STIX_ASSERT (proc == stix->processor->runnable_head);
|
||||
|
||||
wake_new_process (stix, proc);
|
||||
stix->proc_switched = 1;
|
||||
@ -2895,16 +2906,9 @@ STIX_ASSERT (proc == stix->processor->runnable_head);
|
||||
}
|
||||
else if (stix->processor->active == stix->nil_process)
|
||||
{
|
||||
/* THIS PART IS JUST EXPERIMENTAL... PROPER WAITING WITH IO MULTIPLEXER IS NEEDED ... */
|
||||
ft.tv_sec -= now.tv_sec;
|
||||
ft.tv_nsec -= now.tv_nsec;
|
||||
while (ft.tv_nsec < 0)
|
||||
{
|
||||
ft.tv_sec--;
|
||||
ft.tv_nsec += 1000000000;
|
||||
}
|
||||
nanosleep (&ft, STIX_NULL);
|
||||
clock_gettime (CLOCK_MONOTONIC, &now);
|
||||
STIX_SUBNTIME (&ft, &ft, (stix_ntime_t*)&now);
|
||||
vm_sleep (&ft); /* TODO: change this to i/o multiplexer??? */
|
||||
vm_gettime (&now);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2921,13 +2925,6 @@ printf ("REALLY NO MORE RUNNABLE PROCESS...\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (stix->processor->active == stix->idle_process)
|
||||
{
|
||||
IDLEING WAITING FOR PROCESS WAKE-UP...
|
||||
}
|
||||
*/
|
||||
|
||||
while (stix->sem_list_count > 0)
|
||||
{
|
||||
/* handle async signals */
|
||||
@ -3704,7 +3701,6 @@ printf ("TERMINATE A PROCESS RETURNING FROM BLOCK\n");
|
||||
#endif
|
||||
terminate_process (stix, stix->processor->active);
|
||||
#if defined(STIX_DEBUG_EXEC_002)
|
||||
|
||||
printf ("TERMINATED A PROCESS RETURNING FROM BLOCK %lld new active_context %p\n", (long long int)stix->ip, stix->active_context);
|
||||
#endif
|
||||
}
|
||||
|
@ -316,6 +316,83 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
#define STIX_OOCH_IS_UCH
|
||||
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
* TIME-RELATED TYPES
|
||||
* =========================================================================*/
|
||||
#define STIX_MSECS_PER_SEC (1000)
|
||||
#define STIX_MSECS_PER_MIN (STIX_MSECS_PER_SEC * STIX_SECS_PER_MIN)
|
||||
#define STIX_MSECS_PER_HOUR (STIX_MSECS_PER_SEC * STIX_SECS_PER_HOUR)
|
||||
#define STIX_MSECS_PER_DAY (STIX_MSECS_PER_SEC * STIX_SECS_PER_DAY)
|
||||
|
||||
#define STIX_USECS_PER_MSEC (1000)
|
||||
#define STIX_NSECS_PER_USEC (1000)
|
||||
#define STIX_NSECS_PER_MSEC (STIX_NSECS_PER_USEC * STIX_USECS_PER_MSEC)
|
||||
#define STIX_USECS_PER_SEC (STIX_USECS_PER_MSEC * STIX_MSECS_PER_SEC)
|
||||
#define STIX_NSECS_PER_SEC (STIX_NSECS_PER_USEC * STIX_USECS_PER_MSEC * STIX_MSECS_PER_SEC)
|
||||
|
||||
#define STIX_SECNSEC_TO_MSEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * STIX_MSECS_PER_SEC) + ((qse_long_t)(nsec) / STIX_NSECS_PER_MSEC))
|
||||
|
||||
#define STIX_SECNSEC_TO_USEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * STIX_USECS_PER_SEC) + ((qse_long_t)(nsec) / STIX_NSECS_PER_USEC))
|
||||
|
||||
#define STIX_SEC_TO_MSEC(sec) ((sec) * STIX_MSECS_PER_SEC)
|
||||
#define STIX_MSEC_TO_SEC(sec) ((sec) / STIX_MSECS_PER_SEC)
|
||||
|
||||
#define STIX_USEC_TO_NSEC(usec) ((usec) * STIX_NSECS_PER_USEC)
|
||||
#define STIX_NSEC_TO_USEC(nsec) ((nsec) / STIX_NSECS_PER_USEC)
|
||||
|
||||
#define STIX_MSEC_TO_NSEC(msec) ((msec) * STIX_NSECS_PER_MSEC)
|
||||
#define STIX_NSEC_TO_MSEC(nsec) ((nsec) / STIX_NSECS_PER_MSEC)
|
||||
|
||||
#define STIX_SEC_TO_NSEC(sec) ((sec) * STIX_NSECS_PER_SEC)
|
||||
#define STIX_NSEC_TO_SEC(nsec) ((nsec) / STIX_NSECS_PER_SEC)
|
||||
|
||||
#define STIX_SEC_TO_USEC(sec) ((sec) * STIX_USECS_PER_SEC)
|
||||
#define STIX_USEC_TO_SEC(usec) ((usec) / STIX_USECS_PER_SEC)
|
||||
|
||||
typedef struct stix_ntime_t stix_ntime_t;
|
||||
struct stix_ntime_t
|
||||
{
|
||||
stix_intptr_t sec;
|
||||
stix_int32_t nsec; /* nanoseconds */
|
||||
};
|
||||
|
||||
#define STIX_INITNTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns)))
|
||||
#define STIX_CLEARNTIME(c) STIX_INITNTIME(c, 0, 0)
|
||||
|
||||
#define STIX_ADDNTIME(c,a,b) \
|
||||
do { \
|
||||
(c)->sec = (a)->sec + (b)->sec; \
|
||||
(c)->nsec = (a)->nsec + (b)->nsec; \
|
||||
while ((c)->nsec >= STIX_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= STIX_NSECS_PER_SEC; } \
|
||||
} while(0)
|
||||
|
||||
#define STIX_ADDNTIMESNS(c,a,s,ns) \
|
||||
do { \
|
||||
(c)->sec = (a)->sec + (s); \
|
||||
(c)->nsec = (a)->nsec + (ns); \
|
||||
while ((c)->nsec >= STIX_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= STIX_NSECS_PER_SEC; } \
|
||||
} while(0)
|
||||
|
||||
#define STIX_SUBNTIME(c,a,b) \
|
||||
do { \
|
||||
(c)->sec = (a)->sec - (b)->sec; \
|
||||
(c)->nsec = (a)->nsec - (b)->nsec; \
|
||||
while ((c)->nsec < 0) { (c)->sec--; (c)->nsec += STIX_NSECS_PER_SEC; } \
|
||||
} while(0)
|
||||
|
||||
#define STIX_SUBNTIMESNS(c,a,s,ns) \
|
||||
do { \
|
||||
(c)->sec = (a)->sec - s; \
|
||||
(c)->nsec = (a)->nsec - ns; \
|
||||
while ((c)->nsec < 0) { (c)->sec--; (c)->nsec += STIX_NSECS_PER_SEC; } \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define STIX_CMPNTIME(a,b) (((a)->sec == (b)->sec)? ((a)->nsec - (b)->nsec): ((a)->sec - (b)->sec))
|
||||
|
||||
/* =========================================================================
|
||||
* PRIMITIVE MACROS
|
||||
* ========================================================================= */
|
||||
|
Loading…
Reference in New Issue
Block a user