1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/* $Id: threads.h 8609 2010-06-07 21:08:46Z dothebart $ */
#ifndef THREADS_H
#define THREADS_H
#include "sysdep.h"
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include <sys/time.h>
#include <string.h>
#ifdef HAVE_DB_H
#include <db.h>
#elif defined(HAVE_DB4_DB_H)
#include <db4/db.h>
#else
#error Neither <db.h> nor <db4/db.h> was found by configure. Install db4-devel.
#endif
#include "server.h"
#include "sysdep_decls.h"
#ifndef timerclear
#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#endif
#ifndef timerisset
#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef timersub
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#endif
// #define THREADS_USESIGNALS
/*
* Thread stuff
*/
enum CtdlThreadState {
CTDL_THREAD_INVALID,
CTDL_THREAD_VALID,
CTDL_THREAD_CREATE,
CTDL_THREAD_CANCELLED,
CTDL_THREAD_EXITED,
CTDL_THREAD_STOPPING,
CTDL_THREAD_STOP_REQ, /* Do NOT put any running states before this state */
CTDL_THREAD_SLEEPING,
CTDL_THREAD_BLOCKED,
CTDL_THREAD_RUNNING,
CTDL_THREAD_LAST_STATE
};
typedef struct CtdlThreadNode CtdlThreadNode;
struct CtdlThreadNode{
citthread_t tid; /* id as returned by citthread_create() */
pid_t pid; /* pid, as best the OS will let us determine */
long reltid; /* counting from start... */
time_t when; /* When to start a scheduled thread */
struct CitContext *Context; /* The session context that this thread mught be working on or NULL if none */
long number; /* A unigue number for this thread (not implimented yet) */
int wakefd_recv; /* An fd that this thread can sleep on (not implimented yet) */
int wakefd_send; /* An fd that this thread can send out on (Not implimented yet) */
int signal; /* A field to store a signal we caught. */
const char *name; /* A name for this thread */
void *(*thread_func) (void *arg); /* The actual function that does this threads work */
void *user_args; /* Arguments passed to this threads work function */
long flags; /* Flags that describe this thread */
enum CtdlThreadState state; /* Flag to show state of this thread */
time_t stop_ticker; /* A counter to determine how long it has taken for this thread to exit */
citthread_mutex_t ThreadMutex; /* A mutex to sync this thread to others if this thread allows (also used for sleeping) */
citthread_cond_t ThreadCond; /* A condition variable to sync this thread with others */
citthread_mutex_t SleepMutex; /* A mutex for sleeping */
citthread_cond_t SleepCond; /* A condition variable for sleeping */
citthread_attr_t attr; /* Attributes of this thread */
struct timeval start_time; /* Time this thread was started */
struct timeval last_state_change; /* Time when this thread last changed state */
double avg_sleeping; /* Average sleeping time */
double avg_running; /* Average running time */
double avg_blocked; /* Average blocked time */
double load_avg; /* Load average for this thread */
CtdlThreadNode *prev; /* Previous thread in the thread table */
CtdlThreadNode *next; /* Next thread in the thread table */
} ;
extern CtdlThreadNode *CtdlThreadList;
typedef struct ThreadTSD ThreadTSD;
struct ThreadTSD {
DB_TXN *tid; /* Transaction handle */
DBC *cursors[MAXCDB]; /* Cursors, for traversals... */
CtdlThreadNode *self; /* Pointer to this threads control structure */
} ;
extern double CtdlThreadLoadAvg;
extern double CtdlThreadWorkerAvg;
extern long statcount; /* are we doing a stats check? */
extern citthread_key_t ThreadKey;
void ctdl_thread_internal_init_tsd(void);
void ctdl_internal_thread_gc (void);
void ctdl_thread_internal_init(void);
void ctdl_thread_internal_cleanup(void);
void ctdl_thread_internal_calc_loadavg(void);
void ctdl_thread_internal_free_tsd(void);
CtdlThreadNode *ctdl_internal_create_thread(char *name, long flags, void *(*thread_func) (void *arg), void *args);
void ctdl_thread_internal_check_scheduled(void);
void ctdl_thread_internal_change_state (CtdlThreadNode *this_thread, enum CtdlThreadState new_state);
void InitialiseSemaphores(void);
int try_critical_section (int which_one);
void begin_critical_section (int which_one);
void end_critical_section (int which_one);
void go_threading(void);
#endif // THREADS_H
|