From 03f1751cc9b6f2c3ce261daf21311f55459ee97b Mon Sep 17 00:00:00 2001 From: Michael Hampton Date: Mon, 22 Mar 2004 19:37:29 +0000 Subject: [PATCH] * sysdep.c: worker_thread(): Make scheduling a little more fair to higher sessions * sysdep.c: lprintf(): Enable microsecond display in trace file * stress.c: worker(): Sleep for random amount of time as per specification --- citadel/ChangeLog | 7 +++++++ citadel/server.h | 3 ++- citadel/stress.c | 8 +++++++- citadel/sysdep.c | 39 ++++++++++++++++++++++++++++++++++++++- citadel/user_ops.c | 1 + 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index fbf3a9157..6c2a64e8f 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 614.94 2004/03/22 19:37:28 error + * sysdep.c: worker_thread(): Make scheduling a little more fair to higher + sessions + * sysdep.c: lprintf(): Enable microsecond display in trace file + * stress.c: worker(): Sleep for random amount of time as per specification + Revision 614.93 2004/03/21 22:51:54 error * Fix a few remaining lprintf(9, ...) to lprintf(CTDL_DEBUG, ...) @@ -5580,3 +5586,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/server.h b/citadel/server.h index 8c42ec21c..cc28f2151 100644 --- a/citadel/server.h +++ b/citadel/server.h @@ -156,7 +156,8 @@ typedef struct CitContext t_context; /* Values for CitContext.state */ enum { CON_IDLE, /* This context is doing nothing */ - CON_EXECUTING /* This context is bound to a thread */ + CON_READY, /* This context is ready-to-run */ + CON_EXECUTING, /* This context is bound to a thread */ }; diff --git a/citadel/stress.c b/citadel/stress.c index ba141d0b9..90d495157 100644 --- a/citadel/stress.c +++ b/citadel/stress.c @@ -196,9 +196,15 @@ void* worker(void* data) struct ctdlipcroom *rret; struct timeval tv; long tstart, tend; + int wait; /* Wait for a while */ - sleep(w); + pthread_mutex_lock(&rand_mutex); + /* See Numerical Recipes in C or Knuth vol. 2 ch. 3 */ + /* Randomize between w/3 to w*3 (yes, it's complicated) */ + wait = (int)((1.0+2.7*(float)w)*rand()/(RAND_MAX+(float)w/3.0)); /* range 0-99 */ + pthread_mutex_unlock(&rand_mutex); + sleep(wait); gettimeofday(&tv, NULL); tstart = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* cvt to msec */ diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 061b9fee7..95fe7068c 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -135,18 +135,37 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) { * %03ld to %06ld and remove " / 1000" after tv.tv_usec. */ if (CC && CC->cs_pid) { +#if 0 + /* Millisecond display */ fprintf(stderr, "%04d/%02d/%02d %2d:%02d:%02d.%03ld [%3d] %s", tim->tm_year + 1900, tim->tm_mon + 1, tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec, (long)tv.tv_usec / 1000, CC->cs_pid, buf); +#endif + /* Microsecond display */ + fprintf(stderr, + "%04d/%02d/%02d %2d:%02d:%02d.%06ld [%3d] %s", + tim->tm_year + 1900, tim->tm_mon + 1, + tim->tm_mday, tim->tm_hour, tim->tm_min, + tim->tm_sec, (long)tv.tv_usec, + CC->cs_pid, buf); } else { +#if 0 + /* Millisecond display */ fprintf(stderr, "%04d/%02d/%02d %2d:%02d:%02d.%03ld %s", tim->tm_year + 1900, tim->tm_mon + 1, tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec, (long)tv.tv_usec / 1000, buf); +#endif + /* Microsecond display */ + fprintf(stderr, + "%04d/%02d/%02d %2d:%02d:%02d.%06ld %s", + tim->tm_year + 1900, tim->tm_mon + 1, + tim->tm_mday, tim->tm_hour, tim->tm_min, + tim->tm_sec, (long)tv.tv_usec, buf); } fflush(stderr); } @@ -980,6 +999,8 @@ void *worker_thread(void *arg) { int i; char junk; int highest; + /* This is synchronized below; it helps implement round robin mode */ + static struct CitContext* next_session = NULL; struct CitContext *ptr; struct CitContext *bind_me = NULL; fd_set readfds; @@ -1115,7 +1136,16 @@ SETUP_FD: memcpy(&readfds, &masterfds, sizeof masterfds); else { bind_me = NULL; begin_critical_section(S_SESSION_TABLE); - for (ptr = ContextList; + /* + * We start where we left off. If we get to the end + * we'll start from the beginning again, then give up + * if we still don't find anything. This ensures + * that all contexts get a more-or-less equal chance + * to run. And yes, I did add a goto to the code. -IO + */ +find_session: if (next_session == NULL) + next_session = ContextList; + for (ptr = next_session; ( (ptr != NULL) && (bind_me == NULL) ); ptr = ptr->next) { if ( (FD_ISSET(ptr->client_socket, &readfds)) @@ -1128,6 +1158,13 @@ SETUP_FD: memcpy(&readfds, &masterfds, sizeof masterfds); * letting anyone else touch the context list. */ bind_me->state = CON_EXECUTING; + next_session = bind_me->next; + } else if (next_session == ContextList) { + next_session = NULL; + } + if (bind_me == NULL && next_session != NULL) { + next_session = NULL; + goto find_session; } end_critical_section(S_SESSION_TABLE); diff --git a/citadel/user_ops.c b/citadel/user_ops.c index 92f51c2b0..56559a05e 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -438,6 +438,7 @@ void cmd_user(char *cmdbuf) case login_not_found: cprintf("%d %s not found.\n", ERROR + NO_SUCH_USER, username); return; + default: cprintf("%d Internal error\n", ERROR + INTERNAL_ERROR); } } -- 2.39.2