diff options
| -rw-r--r-- | Changes | 4 | ||||
| -rw-r--r-- | eio.c | 43 | ||||
| -rw-r--r-- | eio.h | 1 | ||||
| -rw-r--r-- | xthread.h | 28 | 
4 files changed, 55 insertions, 21 deletions
| @@ -2,9 +2,11 @@ Revision history for libeio  TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd  TODO: openbsd requires stdint.h for intptr_t - why posix? -TODO: mutex init in child after fork?  1.0 +	- use nonstandard but maybe-working-on-bsd fork technique. +	- support a max_idle value of 0. +	- support setting of idle timeout value.          - readdir: correctly handle malloc failures.          - readdir: new flags argument, can return inode            and possibly filetype, can sort in various ways. @@ -134,9 +134,6 @@  # define D_NAMLEN(de) strlen ((de)->d_name)  #endif -/* number of seconds after which an idle threads exit */ -#define IDLE_TIMEOUT 10 -  /* used for struct dirent, AIX doesn't provide it */  #ifndef NAME_MAX  # define NAME_MAX 4096 @@ -225,12 +222,13 @@ static unsigned int max_poll_reqs;     /* reslock */  static volatile unsigned int nreqs;    /* reqlock */  static volatile unsigned int nready;   /* reqlock */  static volatile unsigned int npending; /* reqlock */ -static volatile unsigned int max_idle = 4; +static volatile unsigned int max_idle = 4;      /* maximum number of threads that can idle indefinitely */ +static volatile unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */ -static xmutex_t wrklock = X_MUTEX_INIT; -static xmutex_t reslock = X_MUTEX_INIT; -static xmutex_t reqlock = X_MUTEX_INIT; -static xcond_t  reqwait = X_COND_INIT; +static xmutex_t wrklock; +static xmutex_t reslock; +static xmutex_t reqlock; +static xcond_t  reqwait;  #if !HAVE_PREADWRITE  /* @@ -370,6 +368,14 @@ static ETP_REQ *reqq_shift (etp_reqq *q)    abort ();  } +static void etp_thread_init (void) +{ +  X_MUTEX_CREATE (wrklock); +  X_MUTEX_CREATE (reslock); +  X_MUTEX_CREATE (reqlock); +  X_COND_CREATE  (reqwait); +} +  static void etp_atfork_prepare (void)  {    X_LOCK (wrklock); @@ -417,12 +423,13 @@ static void etp_atfork_child (void)    nready   = 0;    npending = 0; -  etp_atfork_parent (); +  etp_thread_init ();  }  static void  etp_once_init (void) -{     +{ +  etp_thread_init ();    X_THREAD_ATFORK (etp_atfork_prepare, etp_atfork_parent, etp_atfork_child);  } @@ -623,7 +630,14 @@ static void etp_set_max_poll_reqs (unsigned int maxreqs)  static void etp_set_max_idle (unsigned int nthreads)  {    if (WORDACCESS_UNSAFE) X_LOCK   (reqlock); -  max_idle = nthreads <= 0 ? 1 : nthreads; +  max_idle = nthreads; +  if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); +} + +static void etp_set_idle_timeout (unsigned int seconds) +{ +  if (WORDACCESS_UNSAFE) X_LOCK   (reqlock); +  idle_timeout = seconds;    if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock);  } @@ -761,6 +775,11 @@ void eio_set_max_idle (unsigned int nthreads)    etp_set_max_idle (nthreads);  } +void eio_set_idle_timeout (unsigned int seconds) +{ +  etp_set_idle_timeout (seconds); +} +  void eio_set_min_parallel (unsigned int nthreads)  {    etp_set_min_parallel (nthreads); @@ -1553,7 +1572,7 @@ X_THREAD_PROC (etp_proc)            ++idle; -          ts.tv_sec = time (0) + IDLE_TIMEOUT; +          ts.tv_sec = time (0) + idle_timeout;            if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT)              {                if (idle > max_idle) @@ -241,6 +241,7 @@ void eio_set_max_poll_reqs (unsigned int nreqs);  void eio_set_min_parallel (unsigned int nthreads);  void eio_set_max_parallel (unsigned int nthreads);  void eio_set_max_idle     (unsigned int nthreads); +void eio_set_idle_timeout (unsigned int seconds);  unsigned int eio_nreqs    (void); /* number of requests in-flight */  unsigned int eio_nready   (void); /* number of not-yet handled requests */ @@ -29,6 +29,7 @@ typedef int ssize_t;  #include <windows.h>  #include <pthread.h>  #define sigset_t int +#define sigfillset(a)  #define pthread_sigmask(a,b,c)  #define sigaddset(a,b)  #define sigemptyset(s) @@ -36,11 +37,13 @@ typedef int ssize_t;  typedef pthread_mutex_t xmutex_t;  #define X_MUTEX_INIT           PTHREAD_MUTEX_INITIALIZER +#define X_MUTEX_CREATE(mutex)  pthread_mutex_init (&(mutex), 0)  #define X_LOCK(mutex)          pthread_mutex_lock (&(mutex))  #define X_UNLOCK(mutex)        pthread_mutex_unlock (&(mutex))  typedef pthread_cond_t xcond_t;  #define X_COND_INIT                     PTHREAD_COND_INITIALIZER +#define X_COND_CREATE(cond)		pthread_cond_init (&(cond), 0)  #define X_COND_SIGNAL(cond)             pthread_cond_signal (&(cond))  #define X_COND_WAIT(cond,mutex)         pthread_cond_wait (&(cond), &(mutex))  #define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) @@ -95,18 +98,27 @@ thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)  typedef pthread_mutex_t xmutex_t;  #if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) -# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +# define X_MUTEX_INIT		PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +# define X_MUTEX_CREATE(mutex)						\ +  do {									\ +    pthread_mutexattr_t attr;						\ +    pthread_mutexattr_init (&attr);					\ +    pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);	\ +    pthread_mutex_init (&(mutex), &attr);				\ +  } while (0)  #else -# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +# define X_MUTEX_INIT		PTHREAD_MUTEX_INITIALIZER +# define X_MUTEX_CREATE(mutex)	pthread_mutex_init (&(mutex), 0)  #endif -#define X_LOCK(mutex)   pthread_mutex_lock   (&(mutex)) -#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) +#define X_LOCK(mutex)		pthread_mutex_lock   (&(mutex)) +#define X_UNLOCK(mutex)		pthread_mutex_unlock (&(mutex))  typedef pthread_cond_t xcond_t; -#define X_COND_INIT PTHREAD_COND_INITIALIZER -#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) -#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) -#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) +#define X_COND_INIT			PTHREAD_COND_INITIALIZER +#define X_COND_CREATE(cond)		pthread_cond_init (&(cond), 0) +#define X_COND_SIGNAL(cond)		pthread_cond_signal (&(cond)) +#define X_COND_WAIT(cond,mutex)		pthread_cond_wait (&(cond), &(mutex)) +#define X_COND_TIMEDWAIT(cond,mutex,to)	pthread_cond_timedwait (&(cond), &(mutex), &(to))  typedef pthread_t xthread_t;  #define X_THREAD_PROC(name) static void *name (void *thr_arg) | 
