From 753c8706f5770bcf9e5327c498caba661df8ef58 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 10 Aug 2006 16:42:09 +0200 Subject: [PATCH] server: Only call gettimeofday once per poll loop. --- server/fd.c | 17 +++++++++++------ server/file.h | 1 + server/mailslot.c | 3 +-- server/named_pipe.c | 11 +++-------- server/process.c | 4 ++-- server/queue.c | 20 +++++++------------- server/registry.c | 3 +-- server/request.c | 10 +++------- server/serial.c | 3 +-- server/thread.c | 8 +++----- server/timer.c | 2 +- server/trace.c | 7 +++---- server/winstation.c | 3 +-- 13 files changed, 38 insertions(+), 54 deletions(-) diff --git a/server/fd.c b/server/fd.c index b7281a4051..5f172a9ee2 100644 --- a/server/fd.c +++ b/server/fd.c @@ -302,6 +302,7 @@ struct timeout_user }; static struct list timeout_list = LIST_INIT(timeout_list); /* sorted timeouts list */ +struct timeval current_time; /* add a timeout user */ struct timeout_user *add_timeout_user( const struct timeval *when, timeout_callback func, @@ -440,6 +441,7 @@ static inline void main_loop_epoll(void) if (epoll_fd == -1) break; /* an error occurred with epoll */ ret = epoll_wait( epoll_fd, events, sizeof(events)/sizeof(events[0]), timeout ); + gettimeofday( ¤t_time, NULL ); /* put the events into the pollfd array first, like poll does */ for (i = 0; i < ret; i++) @@ -545,6 +547,8 @@ static inline void main_loop_epoll(void) } else ret = kevent( kqueue_fd, NULL, 0, events, sizeof(events)/sizeof(events[0]), NULL ); + gettimeofday( ¤t_time, NULL ); + /* put the events into the pollfd array first, like poll does */ for (i = 0; i < ret; i++) { @@ -641,9 +645,6 @@ static int get_next_timeout(void) if (!list_empty( &timeout_list )) { struct list expired_list, *ptr; - struct timeval now; - - gettimeofday( &now, NULL ); /* first remove all expired timers from the list */ @@ -652,7 +653,7 @@ static int get_next_timeout(void) { struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry ); - if (!time_before( &now, &timeout->when )) + if (!time_before( ¤t_time, &timeout->when )) { list_remove( &timeout->entry ); list_add_tail( &expired_list, &timeout->entry ); @@ -673,8 +674,8 @@ static int get_next_timeout(void) if ((ptr = list_head( &timeout_list )) != NULL) { struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry ); - int diff = (timeout->when.tv_sec - now.tv_sec) * 1000 - + (timeout->when.tv_usec - now.tv_usec + 999) / 1000; + int diff = (timeout->when.tv_sec - current_time.tv_sec) * 1000 + + (timeout->when.tv_usec - current_time.tv_usec + 999) / 1000; if (diff < 0) diff = 0; return diff; } @@ -687,6 +688,8 @@ void main_loop(void) { int i, ret, timeout; + gettimeofday( ¤t_time, NULL ); + main_loop_epoll(); /* fall through to normal poll loop */ @@ -697,6 +700,8 @@ void main_loop(void) if (!active_users) break; /* last user removed by a timeout */ ret = poll( pollfd, nb_users, timeout ); + gettimeofday( ¤t_time, NULL ); + if (ret > 0) { for (i = 0; i < nb_users; i++) diff --git a/server/file.h b/server/file.h index 68cbb3eb87..16d4399563 100644 --- a/server/file.h +++ b/server/file.h @@ -82,6 +82,7 @@ inline static struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get /* timeout functions */ struct timeout_user; +extern struct timeval current_time; typedef void (*timeout_callback)( void *private ); diff --git a/server/mailslot.c b/server/mailslot.c index 57a15b59ef..4ae575837b 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -267,8 +267,7 @@ static void mailslot_queue_async( struct fd *fd, void *apc, void *user, if (mailslot->read_timeout != -1) { - struct timeval when; - gettimeofday( &when, NULL ); + struct timeval when = current_time; add_timeout( &when, mailslot->read_timeout ); fd_queue_async_timeout( fd, apc, user, iosb, type, count, &when ); } diff --git a/server/named_pipe.c b/server/named_pipe.c index 202cf68d07..4b68fa07e8 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -488,9 +488,7 @@ static void check_flushed( void *arg ) assert( server->event ); if (pipe_data_remaining( server )) { - struct timeval tv; - - gettimeofday( &tv, NULL ); + struct timeval tv = current_time; add_timeout( &tv, 100 ); server->flush_poll = add_timeout_user( &tv, check_flushed, server ); } @@ -521,14 +519,13 @@ static int pipe_server_flush( struct fd *fd, struct event **event ) if (pipe_data_remaining( server )) { - struct timeval tv; + struct timeval tv = current_time; /* this kind of sux - there's no unix way to be alerted when a pipe becomes empty */ server->event = create_event( NULL, NULL, 0, 0, 0 ); if (!server->event) return 0; - gettimeofday( &tv, NULL ); add_timeout( &tv, 100 ); server->flush_poll = add_timeout_user( &tv, check_flushed, server ); *event = server->event; @@ -873,9 +870,7 @@ DECL_HANDLER(wait_named_pipe) req->func, req->event, NULL ); else { - struct timeval when; - - gettimeofday( &when, NULL ); + struct timeval when = current_time; if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); else add_timeout( &when, req->timeout ); create_async( current, &when, &pipe->waiters, req->func, req->event, NULL ); diff --git a/server/process.c b/server/process.c index 3e5ef97f16..3f933fe33c 100644 --- a/server/process.c +++ b/server/process.c @@ -255,7 +255,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit list_init( &process->classes ); list_init( &process->dlls ); - gettimeofday( &process->start_time, NULL ); + process->start_time = current_time; process->end_time.tv_sec = process->end_time.tv_usec = 0; list_add_head( &process_list, &process->entry ); @@ -508,7 +508,7 @@ static void process_killed( struct process *process ) struct list *ptr; assert( list_empty( &process->thread_list )); - gettimeofday( &process->end_time, NULL ); + process->end_time = current_time; close_process_desktop( process ); handles = process->handles; process->handles = NULL; diff --git a/server/queue.c b/server/queue.c index 24767b6326..90499cccca 100644 --- a/server/queue.c +++ b/server/queue.c @@ -253,7 +253,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ queue->timeout = NULL; queue->input = (struct thread_input *)grab_object( input ); queue->hooks = NULL; - gettimeofday( &queue->last_get_msg, NULL ); + queue->last_get_msg = current_time; list_init( &queue->send_result ); list_init( &queue->callback_result ); list_init( &queue->pending_timers ); @@ -567,8 +567,7 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue if (timeout) { - struct timeval when; - gettimeofday( &when, NULL ); + struct timeval when = current_time; add_timeout( &when, timeout ); result->timeout = add_timeout_user( &when, result_timeout, result ); } @@ -749,11 +748,9 @@ static void cleanup_results( struct msg_queue *queue ) /* check if the thread owning the queue is hung (not checking for messages) */ static int is_queue_hung( struct msg_queue *queue ) { - struct timeval now; struct wait_queue_entry *entry; - gettimeofday( &now, NULL ); - if (now.tv_sec - queue->last_get_msg.tv_sec <= 5) + if (current_time.tv_sec - queue->last_get_msg.tv_sec <= 5) return 0; /* less than 5 seconds since last get message -> not hung */ LIST_FOR_EACH_ENTRY( entry, &queue->obj.wait_queue, struct wait_queue_entry, entry ) @@ -1027,11 +1024,8 @@ static void free_timer( struct msg_queue *queue, struct timer *timer ) /* restart an expired timer */ static void restart_timer( struct msg_queue *queue, struct timer *timer ) { - struct timeval now; - list_remove( &timer->entry ); - gettimeofday( &now, NULL ); - while (!time_before( &now, &timer->when )) add_timeout( &timer->when, timer->rate ); + while (!time_before( ¤t_time, &timer->when )) add_timeout( &timer->when, timer->rate ); link_timer( queue, timer ); set_next_timer( queue ); } @@ -1062,8 +1056,8 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate ) struct timer *timer = mem_alloc( sizeof(*timer) ); if (timer) { - timer->rate = max( rate, 1 ); - gettimeofday( &timer->when, NULL ); + timer->rate = max( rate, 1 ); + timer->when = current_time; add_timeout( &timer->when, rate ); link_timer( queue, timer ); /* check if we replaced the next timer */ @@ -1711,7 +1705,7 @@ DECL_HANDLER(get_message) reply->active_hooks = get_active_hooks(); if (!queue) return; - gettimeofday( &queue->last_get_msg, NULL ); + queue->last_get_msg = current_time; /* first check for sent messages */ if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] ))) diff --git a/server/registry.c b/server/registry.c index 9251188988..b53720c88d 100644 --- a/server/registry.c +++ b/server/registry.c @@ -1682,9 +1682,8 @@ static void periodic_save( void *arg ) /* start the periodic save timer */ static void set_periodic_save_timer(void) { - struct timeval next; + struct timeval next = current_time; - gettimeofday( &next, NULL ); add_timeout( &next, save_period ); if (save_timeout_user) remove_timeout_user( save_timeout_user ); save_timeout_user = add_timeout_user( &next, periodic_save, NULL ); diff --git a/server/request.c b/server/request.c index 765ec7a82c..fd8e58402c 100644 --- a/server/request.c +++ b/server/request.c @@ -467,10 +467,8 @@ int send_client_fd( struct process *process, int fd, obj_handle_t handle ) /* get current tick count to return to client */ unsigned int get_tick_count(void) { - struct timeval t; - gettimeofday( &t, NULL ); - return ((t.tv_sec - server_start_time.tv_sec) * 1000) + - ((t.tv_usec - server_start_time.tv_usec) / 1000); + return ((current_time.tv_sec - server_start_time.tv_sec) * 1000) + + ((current_time.tv_usec - server_start_time.tv_usec) / 1000); } static void master_socket_dump( struct object *obj, int verbose ) @@ -826,13 +824,11 @@ static void close_socket_timeout( void *arg ) /* close the master socket and stop waiting for new clients */ void close_master_socket(void) { - struct timeval when; - if (master_socket_timeout == -1) return; /* just keep running forever */ if (master_socket_timeout) { - gettimeofday( &when, NULL ); + struct timeval when = current_time; add_timeout( &when, master_socket_timeout * 1000 ); master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL ); } diff --git a/server/serial.c b/server/serial.c index cc3086c110..49d3f79181 100644 --- a/server/serial.c +++ b/server/serial.c @@ -246,7 +246,7 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb { struct serial *serial = get_fd_user( fd ); struct list *queue; - struct timeval when; + struct timeval when = current_time; int timeout; int events; @@ -271,7 +271,6 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb return; } - gettimeofday( &when, NULL ); add_timeout( &when, timeout ); if (!create_async( current, &when, queue, apc, user, iosb )) return; diff --git a/server/thread.c b/server/thread.c index 60b74c9269..9d9f2554e6 100644 --- a/server/thread.c +++ b/server/thread.c @@ -146,7 +146,7 @@ inline static void init_thread_structure( struct thread *thread ) thread->desktop_users = 0; thread->token = NULL; - gettimeofday( &thread->creation_time, NULL ); + thread->creation_time = current_time; thread->exit_time.tv_sec = thread->exit_time.tv_usec = 0; list_init( &thread->mutex_list ); @@ -468,9 +468,7 @@ static int check_wait( struct thread *thread ) if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC; if (wait->flags & SELECT_TIMEOUT) { - struct timeval now; - gettimeofday( &now, NULL ); - if (!time_before( &now, &wait->timeout )) return STATUS_TIMEOUT; + if (!time_before( ¤t_time, &wait->timeout )) return STATUS_TIMEOUT; } return -1; } @@ -737,7 +735,7 @@ void kill_thread( struct thread *thread, int violent_death ) { if (thread->state == TERMINATED) return; /* already killed */ thread->state = TERMINATED; - gettimeofday( &thread->exit_time, NULL ); + thread->exit_time = current_time; if (current == thread) current = NULL; if (debug_level) fprintf( stderr,"%04x: *killed* exit_code=%d\n", diff --git a/server/timer.c b/server/timer.c index d1c035ba47..2640dd87a5 100644 --- a/server/timer.c +++ b/server/timer.c @@ -156,7 +156,7 @@ static int set_timer( struct timer *timer, const abs_time_t *expire, int period, if (!expire->sec && !expire->usec) { /* special case: use now + period as first expiration */ - gettimeofday( &timer->when, NULL ); + timer->when = current_time; add_timeout( &timer->when, period ); } else diff --git a/server/trace.c b/server/trace.c index a84752ad60..db93e82c76 100644 --- a/server/trace.c +++ b/server/trace.c @@ -36,6 +36,7 @@ #include "winbase.h" #include "wincon.h" #include "winternl.h" +#include "file.h" #include "request.h" #include "unicode.h" @@ -63,7 +64,6 @@ static void dump_uints( const int *ptr, int len ) static void dump_abs_time( const abs_time_t *time ) { - struct timeval tv; int secs, usecs; if (!time->sec && !time->usec) @@ -71,9 +71,8 @@ static void dump_abs_time( const abs_time_t *time ) fprintf( stderr, "0" ); return; } - gettimeofday( &tv, NULL ); - secs = time->sec - tv.tv_sec; - if ((usecs = time->usec - tv.tv_usec) < 0) + secs = time->sec - current_time.tv_sec; + if ((usecs = time->usec - current_time.tv_usec) < 0) { usecs += 1000000; secs--; diff --git a/server/winstation.c b/server/winstation.c index 6fced81872..e7d2ba64b6 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -337,8 +337,7 @@ void close_process_desktop( struct process *process ) /* if we have one remaining user, it has to be the manager of the desktop window */ if (desktop->users == 1 && get_top_window_owner( desktop )) { - struct timeval when; - gettimeofday( &when, NULL ); + struct timeval when = current_time; add_timeout( &when, 1000 ); assert( !desktop->close_timeout ); desktop->close_timeout = add_timeout_user( &when, close_desktop_timeout, desktop ); -- 2.32.0.93.g670b81a890