Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
BIND
Commits
29852346
Commit
29852346
authored
Oct 16, 1998
by
Bob Halley
Browse files
checkpoint
parent
00c6365a
Changes
10
Hide whitespace changes
Inline
Side-by-side
bin/tests/task_test.c
View file @
29852346
...
...
@@ -8,13 +8,13 @@
#include
<isc/memcluster.h>
#include
<isc/task.h>
#include
<isc/thread.h>
#include
<isc/result.h>
#include
<isc/timer.h>
mem_context_t
mctx
=
NULL
;
/*ARGSUSED*/
static
boolean_t
my_callback
(
task_t
__attribute__
((
unused
))
task
,
task_event_t
__attribute__
((
unused
))
event
)
my_callback
(
task_t
task
,
task_event_t
event
)
{
int
i
,
j
;
char
*
name
=
event
->
arg
;
...
...
@@ -27,21 +27,16 @@ my_callback(task_t __attribute__((unused)) task,
return
(
FALSE
);
}
/*ARGSUSED*/
static
boolean_t
my_shutdown
(
task_t
__attribute__
((
unused
))
task
,
task_event_t
__attribute__
((
unused
))
event
)
{
my_shutdown
(
task_t
task
,
task_event_t
event
)
{
char
*
name
=
event
->
arg
;
printf
(
"shutdown %s
\n
"
,
name
);
return
(
TRUE
);
}
/*ARGSUSED*/
static
boolean_t
my_tick
(
task_t
__attribute__
((
unused
))
task
,
task_event_t
__attribute__
((
unused
))
event
)
my_tick
(
task_t
task
,
task_event_t
event
)
{
char
*
name
=
event
->
arg
;
...
...
@@ -49,37 +44,6 @@ my_tick(task_t __attribute__((unused)) task,
return
(
FALSE
);
}
void
*
simple_timer_run
(
void
*
arg
)
{
task_t
task
=
arg
;
task_event_t
event
;
int
i
;
for
(
i
=
0
;
i
<
10
;
i
++
)
{
sleep
(
1
);
printf
(
"sending timer to %p
\n
"
,
task
);
event
=
task_event_allocate
(
mctx
,
simple_timer_run
,
2
,
my_tick
,
"foo"
,
sizeof
*
event
);
INSIST
(
event
!=
NULL
);
(
void
)
task_send_event
(
task
,
&
event
);
}
task_detach
(
&
task
);
return
(
NULL
);
}
void
simple_timer_init
(
task_t
task
)
{
os_thread_t
t
;
task_t
task_clone
;
task_clone
=
NULL
;
task_attach
(
task
,
&
task_clone
);
INSIST
(
os_thread_create
(
simple_timer_run
,
task_clone
,
&
t
));
(
void
)
os_thread_detach
(
t
);
}
void
main
(
int
argc
,
char
*
argv
[])
{
task_manager_t
manager
=
NULL
;
...
...
@@ -87,6 +51,9 @@ main(int argc, char *argv[]) {
task_t
t3
=
NULL
,
t4
=
NULL
;
task_event_t
event
;
unsigned
int
workers
;
timer_manager_t
timgr
;
timer_t
ti1
,
ti2
;
os_time_t
absolute
,
interval
;
if
(
argc
>
1
)
workers
=
atoi
(
argv
[
1
]);
...
...
@@ -103,8 +70,19 @@ main(int argc, char *argv[]) {
INSIST
(
task_create
(
manager
,
my_shutdown
,
"3"
,
0
,
&
t3
));
INSIST
(
task_create
(
manager
,
my_shutdown
,
"4"
,
0
,
&
t4
));
simple_timer_init
(
t1
);
simple_timer_init
(
t2
);
timgr
=
NULL
;
INSIST
(
timer_manager_create
(
mctx
,
&
timgr
)
==
ISC_R_SUCCESS
);
ti1
=
NULL
;
absolute
.
seconds
=
0
;
absolute
.
nanoseconds
=
0
;
interval
.
seconds
=
5
;
interval
.
nanoseconds
=
0
;
INSIST
(
timer_create
(
timgr
,
timer_type_ticker
,
absolute
,
interval
,
t1
,
my_tick
,
"foo"
,
&
ti1
)
==
ISC_R_SUCCESS
);
ti2
=
NULL
;
INSIST
(
timer_create
(
timgr
,
timer_type_ticker
,
absolute
,
interval
,
t2
,
my_tick
,
"bar"
,
&
ti2
)
==
ISC_R_SUCCESS
);
printf
(
"task 1 = %p
\n
"
,
t1
);
printf
(
"task 2 = %p
\n
"
,
t2
);
sleep
(
2
);
...
...
lib/isc/heap.c
View file @
29852346
...
...
@@ -42,8 +42,8 @@
#define SIZE_INCREMENT 1024
#define HEAP_MAGIC 0x48454150U
/* HEAP. */
#define VALID_
CONTEXT(ctx)
((
ctx
) != NULL && \
(
ctx
)->magic == HEAP_MAGIC)
#define VALID_
HEAP(h)
((
h
) != NULL && \
(
h
)->magic == HEAP_MAGIC)
struct
heap_context
{
unsigned
int
magic
;
...
...
@@ -59,167 +59,167 @@ struct heap_context {
isc_result
heap_create
(
mem_context_t
mctx
,
heap_higher_priority_func
higher_priority
,
heap_index_func
index
,
unsigned
int
size_increment
,
heap_
context_t
*
ctx
p
)
heap_
t
*
heap
p
)
{
heap_
context_t
ctx
;
heap_
t
heap
;
REQUIRE
(
ctx
p
!=
NULL
&&
*
ctx
p
==
NULL
);
REQUIRE
(
heap
p
!=
NULL
&&
*
heap
p
==
NULL
);
REQUIRE
(
higher_priority
!=
NULL
);
ctx
=
mem_get
(
mctx
,
sizeof
*
ctx
);
if
(
ctx
==
NULL
)
heap
=
mem_get
(
mctx
,
sizeof
*
heap
);
if
(
heap
==
NULL
)
return
(
ISC_R_NOMEMORY
);
ctx
->
magic
=
HEAP_MAGIC
;
ctx
->
size
=
0
;
heap
->
magic
=
HEAP_MAGIC
;
heap
->
size
=
0
;
if
(
size_increment
==
0
)
ctx
->
size_increment
=
SIZE_INCREMENT
;
heap
->
size_increment
=
SIZE_INCREMENT
;
else
ctx
->
size_increment
=
size_increment
;
ctx
->
last
=
0
;
ctx
->
array
=
NULL
;
ctx
->
higher_priority
=
higher_priority
;
ctx
->
index
=
index
;
heap
->
size_increment
=
size_increment
;
heap
->
last
=
0
;
heap
->
array
=
NULL
;
heap
->
higher_priority
=
higher_priority
;
heap
->
index
=
index
;
*
ctxp
=
ctx
;
*
heapp
=
heap
;
return
(
ISC_R_SUCCESS
);
}
void
heap_destroy
(
heap_
context_t
*
ctx
p
)
{
heap_
context_t
ctx
;
heap_destroy
(
heap_
t
*
heap
p
)
{
heap_
t
heap
;
REQUIRE
(
ctx
p
!=
NULL
);
ctx
=
*
ctx
p
;
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
heap
p
!=
NULL
);
heap
=
*
heap
p
;
REQUIRE
(
VALID_
HEAP
(
heap
));
if
(
ctx
->
array
!=
NULL
)
mem_put
(
ctx
->
mctx
,
ctx
->
array
,
ctx
->
size
*
sizeof
(
void
*
));
ctx
->
magic
=
0
;
mem_put
(
ctx
->
mctx
,
ctx
,
sizeof
*
ctx
);
if
(
heap
->
array
!=
NULL
)
mem_put
(
heap
->
mctx
,
heap
->
array
,
heap
->
size
*
sizeof
(
void
*
));
heap
->
magic
=
0
;
mem_put
(
heap
->
mctx
,
heap
,
sizeof
*
heap
);
*
ctx
p
=
NULL
;
*
heap
p
=
NULL
;
}
static
boolean_t
resize
(
heap_
context_t
ctx
)
{
resize
(
heap_
t
heap
)
{
void
**
new_array
;
size_t
new_size
;
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
VALID_
HEAP
(
heap
));
new_size
=
ctx
->
size
+
ctx
->
size_increment
;
new_array
=
mem_get
(
ctx
->
mctx
,
new_size
*
sizeof
(
void
*
));
new_size
=
heap
->
size
+
heap
->
size_increment
;
new_array
=
mem_get
(
heap
->
mctx
,
new_size
*
sizeof
(
void
*
));
if
(
new_array
==
NULL
)
return
(
FALSE
);
memcpy
(
new_array
,
ctx
->
array
,
ctx
->
size
);
mem_put
(
ctx
->
mctx
,
ctx
->
array
,
ctx
->
size
*
sizeof
(
void
*
));
ctx
->
size
=
new_size
;
ctx
->
array
=
new_array
;
memcpy
(
new_array
,
heap
->
array
,
heap
->
size
);
mem_put
(
heap
->
mctx
,
heap
->
array
,
heap
->
size
*
sizeof
(
void
*
));
heap
->
size
=
new_size
;
heap
->
array
=
new_array
;
return
(
TRUE
);
}
static
void
float_up
(
heap_
context_t
ctx
,
unsigned
int
i
,
void
*
elt
)
{
float_up
(
heap_
t
heap
,
unsigned
int
i
,
void
*
elt
)
{
unsigned
int
p
;
for
(
p
=
heap_parent
(
i
);
i
>
1
&&
ctx
->
higher_priority
(
elt
,
ctx
->
array
[
p
]);
i
>
1
&&
heap
->
higher_priority
(
elt
,
heap
->
array
[
p
]);
i
=
p
,
p
=
heap_parent
(
i
)
)
{
ctx
->
array
[
i
]
=
ctx
->
array
[
p
];
if
(
ctx
->
index
!=
NULL
)
(
ctx
->
index
)(
ctx
->
array
[
i
],
i
);
heap
->
array
[
i
]
=
heap
->
array
[
p
];
if
(
heap
->
index
!=
NULL
)
(
heap
->
index
)(
heap
->
array
[
i
],
i
);
}
ctx
->
array
[
i
]
=
elt
;
if
(
ctx
->
index
!=
NULL
)
(
ctx
->
index
)(
ctx
->
array
[
i
],
i
);
heap
->
array
[
i
]
=
elt
;
if
(
heap
->
index
!=
NULL
)
(
heap
->
index
)(
heap
->
array
[
i
],
i
);
}
static
void
sink_down
(
heap_
context_t
ctx
,
unsigned
int
i
,
void
*
elt
)
{
sink_down
(
heap_
t
heap
,
unsigned
int
i
,
void
*
elt
)
{
unsigned
int
j
,
size
,
half_size
;
size
=
ctx
->
last
;
size
=
heap
->
last
;
half_size
=
size
/
2
;
while
(
i
<=
half_size
)
{
/* find smallest of the (at most) two children */
j
=
heap_left
(
i
);
if
(
j
<
size
&&
ctx
->
higher_priority
(
ctx
->
array
[
j
+
1
],
ctx
->
array
[
j
]))
if
(
j
<
size
&&
heap
->
higher_priority
(
heap
->
array
[
j
+
1
],
heap
->
array
[
j
]))
j
++
;
if
(
ctx
->
higher_priority
(
elt
,
ctx
->
array
[
j
]))
if
(
heap
->
higher_priority
(
elt
,
heap
->
array
[
j
]))
break
;
ctx
->
array
[
i
]
=
ctx
->
array
[
j
];
if
(
ctx
->
index
!=
NULL
)
(
ctx
->
index
)(
ctx
->
array
[
i
],
i
);
heap
->
array
[
i
]
=
heap
->
array
[
j
];
if
(
heap
->
index
!=
NULL
)
(
heap
->
index
)(
heap
->
array
[
i
],
i
);
i
=
j
;
}
ctx
->
array
[
i
]
=
elt
;
if
(
ctx
->
index
!=
NULL
)
(
ctx
->
index
)(
ctx
->
array
[
i
],
i
);
heap
->
array
[
i
]
=
elt
;
if
(
heap
->
index
!=
NULL
)
(
heap
->
index
)(
heap
->
array
[
i
],
i
);
}
isc_result
heap_insert
(
heap_
context_t
ctx
,
void
*
elt
)
{
heap_insert
(
heap_
t
heap
,
void
*
elt
)
{
unsigned
int
i
;
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
VALID_
HEAP
(
heap
));
i
=
++
ctx
->
last
;
if
(
ctx
->
last
>=
ctx
->
size
&&
!
resize
(
ctx
))
i
=
++
heap
->
last
;
if
(
heap
->
last
>=
heap
->
size
&&
!
resize
(
heap
))
return
(
ISC_R_NOMEMORY
);
float_up
(
ctx
,
i
,
elt
);
float_up
(
heap
,
i
,
elt
);
return
(
ISC_R_SUCCESS
);
}
void
heap_delete
(
heap_
context_t
ctx
,
unsigned
int
i
)
{
heap_delete
(
heap_
t
heap
,
unsigned
int
i
)
{
void
*
elt
;
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
i
>=
1
&&
i
<=
ctx
->
last
);
REQUIRE
(
VALID_
HEAP
(
heap
));
REQUIRE
(
i
>=
1
&&
i
<=
heap
->
last
);
elt
=
ctx
->
array
[
ctx
->
last
];
if
(
--
ctx
->
last
>
0
)
sink_down
(
ctx
,
i
,
elt
);
elt
=
heap
->
array
[
heap
->
last
];
if
(
--
heap
->
last
>
0
)
sink_down
(
heap
,
i
,
elt
);
}
void
heap_increased
(
heap_
context_t
ctx
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
i
>=
1
&&
i
<=
ctx
->
last
);
heap_increased
(
heap_
t
heap
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
HEAP
(
heap
));
REQUIRE
(
i
>=
1
&&
i
<=
heap
->
last
);
float_up
(
ctx
,
i
,
ctx
->
array
[
i
]);
float_up
(
heap
,
i
,
heap
->
array
[
i
]);
}
void
heap_decreased
(
heap_
context_t
ctx
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
i
>=
1
&&
i
<=
ctx
->
last
);
heap_decreased
(
heap_
t
heap
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
HEAP
(
heap
));
REQUIRE
(
i
>=
1
&&
i
<=
heap
->
last
);
sink_down
(
ctx
,
i
,
ctx
->
array
[
i
]);
sink_down
(
heap
,
i
,
heap
->
array
[
i
]);
}
void
*
heap_element
(
heap_
context_t
ctx
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
i
>=
1
&&
i
<=
ctx
->
last
);
heap_element
(
heap_
t
heap
,
unsigned
int
i
)
{
REQUIRE
(
VALID_
HEAP
(
heap
));
REQUIRE
(
i
>=
1
&&
i
<=
heap
->
last
);
return
(
ctx
->
array
[
i
]);
return
(
heap
->
array
[
i
]);
}
void
heap_for_each
(
heap_
context_t
ctx
,
heap_for_each_func
action
,
void
*
uap
)
{
heap_for_each
(
heap_
t
heap
,
heap_for_each_func
action
,
void
*
uap
)
{
unsigned
int
i
;
REQUIRE
(
VALID_
CONTEXT
(
ctx
));
REQUIRE
(
VALID_
HEAP
(
heap
));
REQUIRE
(
action
!=
NULL
);
for
(
i
=
1
;
i
<=
ctx
->
last
;
i
++
)
(
action
)(
ctx
->
array
[
i
],
uap
);
for
(
i
=
1
;
i
<=
heap
->
last
;
i
++
)
(
action
)(
heap
->
array
[
i
],
uap
);
}
lib/isc/include/isc/event.h
0 → 100644
View file @
29852346
#ifndef ISC_EVENT_H
#define ISC_EVENT_H 1
/***
*** Registry of Predefined Event Type Classes
***/
/*
* An event class is a 16 bit number, the most sigificant bit of which must be
* zero. Each class may contain up to 65536 events. An event type is
* formed by adding the event number within the class to the class number.
* E.g., the first event in the timer class is EVENT_CLASS_TIMER + 1. Event
* number zero is always reserved in each class.
*/
#define EVENT_CLASS(class) ((class) << 16)
#define EVENT_CLASS_TASK EVENT_CLASS(0)
#define EVENT_CLASS_TIMER EVENT_CLASS(1)
#define EVENT_CLASS_NET EVENT_CLASS(2)
#define EVENT_CLASS_FILE EVENT_CLASS(3)
/*
* Event classes >= 1024 and <= 32767 are reserved for application use.
*/
#endif
/* ISC_EVENT_H */
lib/isc/include/isc/heap.h
0 → 100644
View file @
29852346
/*
* Copyright (c) 1997, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include
<isc/result.h>
#include
<isc/boolean.h>
#include
<isc/memcluster.h>
typedef
boolean_t
(
*
heap_higher_priority_func
)(
void
*
,
void
*
);
typedef
void
(
*
heap_index_func
)(
void
*
,
unsigned
int
);
typedef
void
(
*
heap_for_each_func
)(
void
*
,
void
*
);
typedef
struct
heap_context
*
heap_t
;
#define heap_create __heap_create
#define heap_destroy __heap_destroy
#define heap_insert __heap_insert
#define heap_delete __heap_delete
#define heap_increased __heap_increased
#define heap_decreased __heap_decreased
#define heap_element __heap_element
#define heap_for_each __heap_for_each
isc_result
heap_create
(
mem_context_t
,
heap_higher_priority_func
,
heap_index_func
,
unsigned
int
,
heap_t
*
);
void
heap_destroy
(
heap_t
*
);
isc_result
heap_insert
(
heap_t
,
void
*
);
void
heap_delete
(
heap_t
,
unsigned
int
);
void
heap_increased
(
heap_t
,
unsigned
int
);
void
heap_decreased
(
heap_t
,
unsigned
int
);
void
*
heap_element
(
heap_t
,
unsigned
int
);
void
heap_for_each
(
heap_t
,
heap_for_each_func
,
void
*
);
lib/isc/include/isc/task.h
View file @
29852346
...
...
@@ -46,7 +46,7 @@ struct task_event {
LINK
(
struct
task_event
)
link
;
};
#define TASK_EVENT_
NOP
0
#define TASK_EVENT_
ANYEVENT
0
#define TASK_EVENT_SHUTDOWN (-1)
typedef
LIST
(
struct
task_event
)
task_eventlist_t
;
...
...
lib/isc/include/isc/timer.h
View file @
29852346
...
...
@@ -95,13 +95,14 @@ timer_create(timer_manager_t manager,
os_time_t
absolute
,
os_time_t
interval
,
task_t
task
,
task_action_t
action
,
void
*
arg
,
timer_t
*
timerp
);
/*
* Create a new 'type' timer managed by 'manager'. The timers parameters
* are specified by 'absolute' and 'interval'. Events will be posted to
* 'task' and w
ill use 'arg' as the arg value. The new timer is returned in
* 'timerp'.
* 'task' and w
hen dispatched 'action' will be called with 'arg' as the
*
arg value. The new timer is returned in
'timerp'.
*
* Notes:
*
...
...
@@ -122,6 +123,8 @@ timer_create(timer_manager_t manager,
*
* 'task' is a valid task
*
* 'action' is a valid action
*
* 'absolute' and 'idle' may not both be 0
*
* 'timerp' is a valid pointer, and *timerp == NULL
...
...
lib/isc/pthreads/include/isc/condition.h
View file @
29852346
...
...
@@ -6,7 +6,6 @@
#include
<isc/boolean.h>
#include
<isc/mutex.h>
#include
<isc/assertions.h>
typedef
pthread_cond_t
os_condition_t
;
#define OS_CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER
...
...
lib/isc/pthreads/include/isc/thread.h
View file @
29852346
...
...
@@ -11,6 +11,7 @@ typedef pthread_t os_thread_t;
#define os_thread_create(s, a, tp) (pthread_create((tp), NULL, (s), (a)) \
== 0)
#define os_thread_detach(t) (pthread_detach((t)) == 0)
#define os_thread_join(t) (pthread_join((t), NULL) == 0)
#define os_thread_self pthread_self
#endif
/* THREAD_H */
lib/isc/timer.c
View file @
29852346
...
...
@@ -3,6 +3,11 @@
#include
<stdlib.h>
#include
<isc/assertions.h>
#include
<isc/unexpect.h>
#include
<isc/thread.h>
#include
<isc/mutex.h>
#include
<isc/condition.h>
#include
<isc/heap.h>
#include
<isc/timer.h>
/*
...
...
@@ -12,10 +17,12 @@
* We INSIST that they succeed since there's no way for us to continue
* if they fail.
*/
#define LOCK(lp) INSIST(os_mutex_lock((lp)))
#define UNLOCK(lp) INSIST(os_mutex_unlock((lp)))
#define BROADCAST(cvp) INSIST(os_condition_broadcast((cvp)))
#define LOCK(lp) INSIST(os_mutex_lock((lp)))
#define UNLOCK(lp) INSIST(os_mutex_unlock((lp)))
#define BROADCAST(cvp) INSIST(os_condition_broadcast((cvp)))
#define WAIT(cvp, lp) INSIST(os_condition_wait((cvp), (lp)))
#define WAITUNTIL(cvp, lp, tp, bp) INSIST(os_condition_waituntil((cvp), \
(lp), (tp), (bp)))
#define TIMER_MAGIC 0x54494D52U
/* TIMR. */
#define VALID_TIMER(t) ((t) != NULL && \
...
...
@@ -33,8 +40,9 @@ struct timer_t {
os_time_t
absolute
;
os_time_t
interval
;
task_t
task
;
task_action_t
action
;
void
*
arg
;
int
index
;
unsigned
int
index
;
os_time_t
next_time
;
LINK
(
struct
timer_t
)
link
;
};
...
...
@@ -49,14 +57,42 @@ struct timer_manager_t {
mem_context_t
mctx
;
os_mutex_t
lock
;
/* Locked by manager lock. */
boolean_t
done
;
LIST
(
struct
timer_t
)
timers
;
unsigned
int
nscheduled
;
os_time_t
next_time
;
os_condition_t
wakeup
;
os_thread_t
thread
;
heap_
contex
t
heap
;
heap_t
heap
;
};
static
boolean_t
sooner
(
void
*
v1
,
void
*
v2
)
{
timer_t
t1
,
t2
;
t1
=
v1
;
t2
=
v2
;
REQUIRE
(
VALID_TIMER
(
t1
));
REQUIRE
(
VALID_TIMER
(
t2
));
if
(
os_time_compare
(
&
t1
->
next_time
,
&
t2
->
next_time
)
<
0
)
return
(
TRUE
);
return
(
FALSE
);
}
static
void
set_index
(
void
*
what
,
unsigned
int
index
)
{
timer_t
timer
;
timer
=
what
;
REQUIRE
(
VALID_TIMER
(
timer
));
timer
->
index
=
index
;
}
static
inline
void
schedul
e
(
timer_t
timer
,
os_time_t
*
now
,
boolean_t
first_time
)
{
nexttim
e
(
timer_t
timer
,
os_time_t
*
now
p
,
boolean_t
first_time
)
{
/*
* The caller must ensure locking.
*/
...
...
@@ -65,19 +101,19 @@ schedule(timer_t timer, os_time_t *now, boolean_t first_time) {
if
(
first_time
)
{
if
(
timer
->
absolute
.
seconds
==
0
&&
timer
->
absolute
.
nanoseconds
==
0
)
timer
->
next_time
=
now
;
timer
->
next_time
=
*
now
p
;
else
timer
->
next_time
=
timer
->
absolute
;
}
else
os_time_add
(
&
now
,
&
timer
->
interval
,
&
timer
->
next_time
);
os_time_add
(
now
p
,
&
timer
->
interval
,
&
timer
->
next_time
);
}
else
{
/* Idle timer. */
if
(
os_time_compare
(
&
timer
->
touched
,
&
now
)
<=
0
)
{
if
(
os_time_compare
(
&
timer
->
touched
,
now
p
)
<=
0
)
{
os_time_t
idle
,
remaining
;
os_time_subtract
(
&
now
,
&
timer
->
touched
,
&
idle
);
os_time_subtract
(
now
p
,
&
timer
->
touched
,
&
idle
);
if
(
os_time_compare
(
&
idle
,
&
timer
->
interval
)
>=
0
)
{
os_time_add
(
&
now
,
&
timer
->
interval
,
os_time_add
(
now
p
,
&
timer
->
interval
,
&
timer
->
next_time
);
}
else
{
...
...
@@ -86,24 +122,81 @@ schedule(timer_t timer, os_time_t *now, boolean_t first_time) {
/*
* Time touched is in the future! Make it now.
*/
timer
->
touched
=
now
;
os_time_add
(
&
now
,
&
timer
->
interval
,
&
timer
->
next_time
);
timer
->
touched
=
*
now
p
;