server: Only call gettimeofday once per poll loop.

This commit is contained in:
Alexandre Julliard 2006-08-10 16:42:09 +02:00
parent 529bb1adff
commit 753c8706f5
13 changed files with 38 additions and 54 deletions

View File

@ -302,6 +302,7 @@ struct timeout_user
}; };
static struct list timeout_list = LIST_INIT(timeout_list); /* sorted timeouts list */ static struct list timeout_list = LIST_INIT(timeout_list); /* sorted timeouts list */
struct timeval current_time;
/* add a timeout user */ /* add a timeout user */
struct timeout_user *add_timeout_user( const struct timeval *when, timeout_callback func, 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 */ if (epoll_fd == -1) break; /* an error occurred with epoll */
ret = epoll_wait( epoll_fd, events, sizeof(events)/sizeof(events[0]), timeout ); ret = epoll_wait( epoll_fd, events, sizeof(events)/sizeof(events[0]), timeout );
gettimeofday( &current_time, NULL );
/* put the events into the pollfd array first, like poll does */ /* put the events into the pollfd array first, like poll does */
for (i = 0; i < ret; i++) 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 ); else ret = kevent( kqueue_fd, NULL, 0, events, sizeof(events)/sizeof(events[0]), NULL );
gettimeofday( &current_time, NULL );
/* put the events into the pollfd array first, like poll does */ /* put the events into the pollfd array first, like poll does */
for (i = 0; i < ret; i++) for (i = 0; i < ret; i++)
{ {
@ -641,9 +645,6 @@ static int get_next_timeout(void)
if (!list_empty( &timeout_list )) if (!list_empty( &timeout_list ))
{ {
struct list expired_list, *ptr; struct list expired_list, *ptr;
struct timeval now;
gettimeofday( &now, NULL );
/* first remove all expired timers from the list */ /* 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 ); struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
if (!time_before( &now, &timeout->when )) if (!time_before( &current_time, &timeout->when ))
{ {
list_remove( &timeout->entry ); list_remove( &timeout->entry );
list_add_tail( &expired_list, &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) if ((ptr = list_head( &timeout_list )) != NULL)
{ {
struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry ); struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
int diff = (timeout->when.tv_sec - now.tv_sec) * 1000 int diff = (timeout->when.tv_sec - current_time.tv_sec) * 1000
+ (timeout->when.tv_usec - now.tv_usec + 999) / 1000; + (timeout->when.tv_usec - current_time.tv_usec + 999) / 1000;
if (diff < 0) diff = 0; if (diff < 0) diff = 0;
return diff; return diff;
} }
@ -687,6 +688,8 @@ void main_loop(void)
{ {
int i, ret, timeout; int i, ret, timeout;
gettimeofday( &current_time, NULL );
main_loop_epoll(); main_loop_epoll();
/* fall through to normal poll loop */ /* fall through to normal poll loop */
@ -697,6 +700,8 @@ void main_loop(void)
if (!active_users) break; /* last user removed by a timeout */ if (!active_users) break; /* last user removed by a timeout */
ret = poll( pollfd, nb_users, timeout ); ret = poll( pollfd, nb_users, timeout );
gettimeofday( &current_time, NULL );
if (ret > 0) if (ret > 0)
{ {
for (i = 0; i < nb_users; i++) for (i = 0; i < nb_users; i++)

View File

@ -82,6 +82,7 @@ inline static struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get
/* timeout functions */ /* timeout functions */
struct timeout_user; struct timeout_user;
extern struct timeval current_time;
typedef void (*timeout_callback)( void *private ); typedef void (*timeout_callback)( void *private );

View File

@ -267,8 +267,7 @@ static void mailslot_queue_async( struct fd *fd, void *apc, void *user,
if (mailslot->read_timeout != -1) if (mailslot->read_timeout != -1)
{ {
struct timeval when; struct timeval when = current_time;
gettimeofday( &when, NULL );
add_timeout( &when, mailslot->read_timeout ); add_timeout( &when, mailslot->read_timeout );
fd_queue_async_timeout( fd, apc, user, iosb, type, count, &when ); fd_queue_async_timeout( fd, apc, user, iosb, type, count, &when );
} }

View File

@ -488,9 +488,7 @@ static void check_flushed( void *arg )
assert( server->event ); assert( server->event );
if (pipe_data_remaining( server )) if (pipe_data_remaining( server ))
{ {
struct timeval tv; struct timeval tv = current_time;
gettimeofday( &tv, NULL );
add_timeout( &tv, 100 ); add_timeout( &tv, 100 );
server->flush_poll = add_timeout_user( &tv, check_flushed, server ); 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 )) if (pipe_data_remaining( server ))
{ {
struct timeval tv; struct timeval tv = current_time;
/* this kind of sux - /* this kind of sux -
there's no unix way to be alerted when a pipe becomes empty */ there's no unix way to be alerted when a pipe becomes empty */
server->event = create_event( NULL, NULL, 0, 0, 0 ); server->event = create_event( NULL, NULL, 0, 0, 0 );
if (!server->event) if (!server->event)
return 0; return 0;
gettimeofday( &tv, NULL );
add_timeout( &tv, 100 ); add_timeout( &tv, 100 );
server->flush_poll = add_timeout_user( &tv, check_flushed, server ); server->flush_poll = add_timeout_user( &tv, check_flushed, server );
*event = server->event; *event = server->event;
@ -873,9 +870,7 @@ DECL_HANDLER(wait_named_pipe)
req->func, req->event, NULL ); req->func, req->event, NULL );
else else
{ {
struct timeval when; struct timeval when = current_time;
gettimeofday( &when, NULL );
if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout ); if (req->timeout == NMPWAIT_USE_DEFAULT_WAIT) add_timeout( &when, pipe->timeout );
else add_timeout( &when, req->timeout ); else add_timeout( &when, req->timeout );
create_async( current, &when, &pipe->waiters, req->func, req->event, NULL ); create_async( current, &when, &pipe->waiters, req->func, req->event, NULL );

View File

@ -255,7 +255,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
list_init( &process->classes ); list_init( &process->classes );
list_init( &process->dlls ); 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; process->end_time.tv_sec = process->end_time.tv_usec = 0;
list_add_head( &process_list, &process->entry ); list_add_head( &process_list, &process->entry );
@ -508,7 +508,7 @@ static void process_killed( struct process *process )
struct list *ptr; struct list *ptr;
assert( list_empty( &process->thread_list )); assert( list_empty( &process->thread_list ));
gettimeofday( &process->end_time, NULL ); process->end_time = current_time;
close_process_desktop( process ); close_process_desktop( process );
handles = process->handles; handles = process->handles;
process->handles = NULL; process->handles = NULL;

View File

@ -253,7 +253,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->timeout = NULL; queue->timeout = NULL;
queue->input = (struct thread_input *)grab_object( input ); queue->input = (struct thread_input *)grab_object( input );
queue->hooks = NULL; queue->hooks = NULL;
gettimeofday( &queue->last_get_msg, NULL ); queue->last_get_msg = current_time;
list_init( &queue->send_result ); list_init( &queue->send_result );
list_init( &queue->callback_result ); list_init( &queue->callback_result );
list_init( &queue->pending_timers ); list_init( &queue->pending_timers );
@ -567,8 +567,7 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue
if (timeout) if (timeout)
{ {
struct timeval when; struct timeval when = current_time;
gettimeofday( &when, NULL );
add_timeout( &when, timeout ); add_timeout( &when, timeout );
result->timeout = add_timeout_user( &when, result_timeout, result ); 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) */ /* check if the thread owning the queue is hung (not checking for messages) */
static int is_queue_hung( struct msg_queue *queue ) static int is_queue_hung( struct msg_queue *queue )
{ {
struct timeval now;
struct wait_queue_entry *entry; struct wait_queue_entry *entry;
gettimeofday( &now, NULL ); if (current_time.tv_sec - queue->last_get_msg.tv_sec <= 5)
if (now.tv_sec - queue->last_get_msg.tv_sec <= 5)
return 0; /* less than 5 seconds since last get message -> not hung */ 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 ) 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 */ /* restart an expired timer */
static void restart_timer( struct msg_queue *queue, struct timer *timer ) static void restart_timer( struct msg_queue *queue, struct timer *timer )
{ {
struct timeval now;
list_remove( &timer->entry ); list_remove( &timer->entry );
gettimeofday( &now, NULL ); while (!time_before( &current_time, &timer->when )) add_timeout( &timer->when, timer->rate );
while (!time_before( &now, &timer->when )) add_timeout( &timer->when, timer->rate );
link_timer( queue, timer ); link_timer( queue, timer );
set_next_timer( queue ); 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) ); struct timer *timer = mem_alloc( sizeof(*timer) );
if (timer) if (timer)
{ {
timer->rate = max( rate, 1 ); timer->rate = max( rate, 1 );
gettimeofday( &timer->when, NULL ); timer->when = current_time;
add_timeout( &timer->when, rate ); add_timeout( &timer->when, rate );
link_timer( queue, timer ); link_timer( queue, timer );
/* check if we replaced the next timer */ /* check if we replaced the next timer */
@ -1711,7 +1705,7 @@ DECL_HANDLER(get_message)
reply->active_hooks = get_active_hooks(); reply->active_hooks = get_active_hooks();
if (!queue) return; if (!queue) return;
gettimeofday( &queue->last_get_msg, NULL ); queue->last_get_msg = current_time;
/* first check for sent messages */ /* first check for sent messages */
if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] ))) if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] )))

View File

@ -1682,9 +1682,8 @@ static void periodic_save( void *arg )
/* start the periodic save timer */ /* start the periodic save timer */
static void set_periodic_save_timer(void) static void set_periodic_save_timer(void)
{ {
struct timeval next; struct timeval next = current_time;
gettimeofday( &next, NULL );
add_timeout( &next, save_period ); add_timeout( &next, save_period );
if (save_timeout_user) remove_timeout_user( save_timeout_user ); if (save_timeout_user) remove_timeout_user( save_timeout_user );
save_timeout_user = add_timeout_user( &next, periodic_save, NULL ); save_timeout_user = add_timeout_user( &next, periodic_save, NULL );

View File

@ -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 */ /* get current tick count to return to client */
unsigned int get_tick_count(void) unsigned int get_tick_count(void)
{ {
struct timeval t; return ((current_time.tv_sec - server_start_time.tv_sec) * 1000) +
gettimeofday( &t, NULL ); ((current_time.tv_usec - server_start_time.tv_usec) / 1000);
return ((t.tv_sec - server_start_time.tv_sec) * 1000) +
((t.tv_usec - server_start_time.tv_usec) / 1000);
} }
static void master_socket_dump( struct object *obj, int verbose ) 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 */ /* close the master socket and stop waiting for new clients */
void close_master_socket(void) void close_master_socket(void)
{ {
struct timeval when;
if (master_socket_timeout == -1) return; /* just keep running forever */ if (master_socket_timeout == -1) return; /* just keep running forever */
if (master_socket_timeout) if (master_socket_timeout)
{ {
gettimeofday( &when, NULL ); struct timeval when = current_time;
add_timeout( &when, master_socket_timeout * 1000 ); add_timeout( &when, master_socket_timeout * 1000 );
master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL ); master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL );
} }

View File

@ -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 serial *serial = get_fd_user( fd );
struct list *queue; struct list *queue;
struct timeval when; struct timeval when = current_time;
int timeout; int timeout;
int events; int events;
@ -271,7 +271,6 @@ static void serial_queue_async( struct fd *fd, void *apc, void *user, void *iosb
return; return;
} }
gettimeofday( &when, NULL );
add_timeout( &when, timeout ); add_timeout( &when, timeout );
if (!create_async( current, &when, queue, apc, user, iosb )) return; if (!create_async( current, &when, queue, apc, user, iosb )) return;

View File

@ -146,7 +146,7 @@ inline static void init_thread_structure( struct thread *thread )
thread->desktop_users = 0; thread->desktop_users = 0;
thread->token = NULL; thread->token = NULL;
gettimeofday( &thread->creation_time, NULL ); thread->creation_time = current_time;
thread->exit_time.tv_sec = thread->exit_time.tv_usec = 0; thread->exit_time.tv_sec = thread->exit_time.tv_usec = 0;
list_init( &thread->mutex_list ); 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_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC;
if (wait->flags & SELECT_TIMEOUT) if (wait->flags & SELECT_TIMEOUT)
{ {
struct timeval now; if (!time_before( &current_time, &wait->timeout )) return STATUS_TIMEOUT;
gettimeofday( &now, NULL );
if (!time_before( &now, &wait->timeout )) return STATUS_TIMEOUT;
} }
return -1; return -1;
} }
@ -737,7 +735,7 @@ void kill_thread( struct thread *thread, int violent_death )
{ {
if (thread->state == TERMINATED) return; /* already killed */ if (thread->state == TERMINATED) return; /* already killed */
thread->state = TERMINATED; thread->state = TERMINATED;
gettimeofday( &thread->exit_time, NULL ); thread->exit_time = current_time;
if (current == thread) current = NULL; if (current == thread) current = NULL;
if (debug_level) if (debug_level)
fprintf( stderr,"%04x: *killed* exit_code=%d\n", fprintf( stderr,"%04x: *killed* exit_code=%d\n",

View File

@ -156,7 +156,7 @@ static int set_timer( struct timer *timer, const abs_time_t *expire, int period,
if (!expire->sec && !expire->usec) if (!expire->sec && !expire->usec)
{ {
/* special case: use now + period as first expiration */ /* special case: use now + period as first expiration */
gettimeofday( &timer->when, NULL ); timer->when = current_time;
add_timeout( &timer->when, period ); add_timeout( &timer->when, period );
} }
else else

View File

@ -36,6 +36,7 @@
#include "winbase.h" #include "winbase.h"
#include "wincon.h" #include "wincon.h"
#include "winternl.h" #include "winternl.h"
#include "file.h"
#include "request.h" #include "request.h"
#include "unicode.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 ) static void dump_abs_time( const abs_time_t *time )
{ {
struct timeval tv;
int secs, usecs; int secs, usecs;
if (!time->sec && !time->usec) if (!time->sec && !time->usec)
@ -71,9 +71,8 @@ static void dump_abs_time( const abs_time_t *time )
fprintf( stderr, "0" ); fprintf( stderr, "0" );
return; return;
} }
gettimeofday( &tv, NULL ); secs = time->sec - current_time.tv_sec;
secs = time->sec - tv.tv_sec; if ((usecs = time->usec - current_time.tv_usec) < 0)
if ((usecs = time->usec - tv.tv_usec) < 0)
{ {
usecs += 1000000; usecs += 1000000;
secs--; secs--;

View File

@ -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 we have one remaining user, it has to be the manager of the desktop window */
if (desktop->users == 1 && get_top_window_owner( desktop )) if (desktop->users == 1 && get_top_window_owner( desktop ))
{ {
struct timeval when; struct timeval when = current_time;
gettimeofday( &when, NULL );
add_timeout( &when, 1000 ); add_timeout( &when, 1000 );
assert( !desktop->close_timeout ); assert( !desktop->close_timeout );
desktop->close_timeout = add_timeout_user( &when, close_desktop_timeout, desktop ); desktop->close_timeout = add_timeout_user( &when, close_desktop_timeout, desktop );