Have actor_poll take an indication from the outer event loop of how many
ticks of ACTOR_RESOLUTION have passed, and return how many ticks into
the future it would like to be called again.
Then in event_loop, try and keep the poll timeouts as long as possible
without delaying actors or screwing up their timeouts too badly.
First draft sent to me by Adam Jackson, but I've reworked everything
except the actor_check changes considerably so blame me.
Bugzilla: https://bugzilla.redhat.com/458213
Cc: Adam Jackson
Signed-off-by: Chris Leech
---
usr/Makefile | 4 ++--
usr/actor.c | 23 ---
usr/actor.h | 2 +-
usr/event_poll.c | 42 ++
4 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/usr/Makefile b/usr/Makefile
index 3d8ee22..550fdff 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -55,14 +55,14 @@ all: $(PROGRAMS)
iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \
iscsid.o session_mgmt.o discoveryd.o
- $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns
+ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lrt
iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o
$(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns
iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \
iscsistart.o statics.o
- $(CC) $(CFLAGS) -static $^ -o $@
+ $(CC) $(CFLAGS) -static $^ -o $@ -lrt
clean:
rm -f *.o $(PROGRAMS) .depend $(LIBSYS)
diff --git a/usr/actor.c b/usr/actor.c
index 7f93e76..3685a41 100644
--- a/usr/actor.c
+++ b/usr/actor.c
@@ -193,17 +193,18 @@ actor_timer_mod(actor_t *thread, uint32_t timeout, void
*data)
return 0;
}
-static void
+static uint64_t
actor_check(uint64_t current_time)
{
struct actor *thread, *tmp;
+ uint64_t ret;
list_for_each_entry_safe(thread, tmp, &pend_list, list) {
- if (actor_diff_time(thread, current_time)) {
+ if ((ret = actor_diff_time(thread, current_time))) {
log_debug(7, "thread %08lx wait some more",
(long)thread);
/* wait some more */
- break;
+ return ret;
}
/* it is time to schedule this entry */
@@ -220,12 +221,17 @@ actor_check(uint64_t current_time)
log_debug(7, "thread %08lx now in actor_list",
(long)thread);
}
+
+ return -1LL;
}
-void
-actor_poll(void)
+uint64_t
+actor_poll(uint64_t ticks_expired)
{
struct actor *thread;
+ uint64_t ticks_to_wait;
+
+ actor_jiffies += ticks_expired;
/* check that there are no any concurrency */
if (poll_in_progress) {
@@ -233,7 +239,7 @@ actor_poll(void)
}
/* check the wait list */
- actor_check(actor_jiffies);
+ ticks_to_wait = actor_check(actor_jiffies);
/* the following code to check in the main data path */
poll_in_progress = 1;
@@ -252,6 +258,9 @@ actor_poll(void)
}
poll_in_progress = 0;
+ if (!list_empty(&poll_list))
+ ticks_to_wait = 1;
+
while (!list_empty(&poll_list)) {
thread = list_entry(poll_list.next, struct actor, list);
list_del_init(&thread->list);
@@ -266,5 +275,5 @@ actor_poll(void)
(long)thread);
}
- actor_jiffies++;
+ return ticks_to_wait;
}
diff --git a/usr/actor.h b/usr/actor.h
index 4c1ae60..eb624ed 100644
--- a/usr/actor.h
+++ b/usr/actor.h
@@ -48,7 +48,7 @@ extern void actor_schedule(actor_t *thread);
extern void actor_timer(actor_t *thread, uint32_t timeout,
void (*callback)(void *), void *data);
extern int actor_timer_mod(actor_t *thread, uint32_t new_timeout, void *data);
-extern void actor_poll(void);
+extern uint64_t actor_poll(uint64_t ticks_expired);
extern void actor_init(void);
#endif /* ACTOR_H */
diff --git a/usr/event_poll.c b/usr/event_poll.c
index f36fec1..dcbb79a 100644
--- a/usr/event_poll.c
+++ b/usr/event_poll.c
@@ -121,17 +121,37 @@ static int shutdown_wait_pids(void)
static int event_loop_stop;
static queue_task_t *shutdown_qtask;
-
void event_loop_exit(queue_task_t *qtask)
{
shutdown_qtask = qtask;
event_loop_stop = 1;
}
+#include
+
+uint64_t elapsed_ticks(struct timespec *start, struct timespec *end)
+{
+ struct timespec elapsed;
+
+ if ((end->tv_nsec - start->tv_nsec) < 0) {
+ elapsed.tv_sec = end->tv_sec - start->tv_sec - 1;
+ elapsed.tv_nsec = 10 + end->tv_nsec - start->tv_nsec;
+ } else{
+ elapsed.tv_sec = end->tv_sec - start->tv_sec;
+ elapsed.tv_nsec = end->tv_nsec - start->tv_nsec;
+ }
+ return (elapsed.tv_sec * (1000 / ACTOR_RESOLUTION)) +
+ (