File: threads.h

package info (click to toggle)
citadel 7.83-2squeeze2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 4,572 kB
  • ctags: 3,756
  • sloc: ansic: 54,870; sh: 4,298; yacc: 660; makefile: 450; xml: 40
file content (149 lines) | stat: -rw-r--r-- 4,958 bytes parent folder | download
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