summaryrefslogtreecommitdiff
path: root/implement.h
blob: 5cc0de65a81876213a9116b2d279776ab1054fa7 (plain)
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
/*
 * implement.h
 *
 * Implementation specific (non API) stuff.
 */

#ifndef _IMPLEMENT_H
#define _IMPLEMENT_H

#define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX)

#define _PTHREAD_YES 1
#define _PTHREAD_NO  0

/* Handler execution flags. */
#define _PTHREAD_HANDLER_NOEXECUTE 0
#define _PTHREAD_HANDLER_EXECUTE   1

/* Handler popping schemes. */
enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO };

/* Special value to mark attribute objects as valid. */
#define _PTHREAD_ATTR_INVALID 0xC0FFEE

/* General description of a handler function on a stack. */
typedef struct _pthread_handler_node _pthread_handler_node_t;

struct _pthread_handler_node {
  _pthread_handler_node_t next;
  void (* routine)(void *);
  void * arg;
};

/* Stores a thread call routine and argument. */
typedef struct {
  unsigned (*routine)(void *);
  void * arg;
  jmpbuf env;
} _pthread_call_t;

/* Macro to return the address of the thread entry of the calling thread. */
#define _PTHREAD_THIS (_pthread_find_thread_entry(pthread_this()))

/* Macro to compute the address of a given handler stack. */
#define _PTHREAD_STACK(stack) \
  ((_pthread_handler_node_t *) &(_PTHREAD_THIS)->cleanupstack + stack);

/* Macro to compute the table index of a thread entry from it's entry
   address. */
#define _PTHREAD_THREADS_TABLE_INDEX(this) \
  ((_pthread_threads_table_t *) this - \
   (_pthread_threads_table_t *) _pthread_threads_threads_table)

/* Macro to compute the address of a per-thread mutex lock. */
#define _PTHREAD_THREAD_MUTEX(this) \
   (&_pthread_threads_mutex_table[_PTHREAD_THREADS_TABLE_INDEX(this)])

/* An element in the thread table. */
typedef struct _pthread_threads_thread _pthread_threads_thread_t;

struct _pthread_threads_thread {
  pthread_t                   thread;
  pthread_attr_t              attr;
  _pthread_call_t             call;
  int                         cancel_pending;
  int                         cancelstate;      /* PTHREAD_CANCEL_DISABLE
						   PTHREAD_CANCEL_ENABLE */

  int                         canceltype;       /* PTHREAD_CANCEL_ASYNCHRONOUS
						   PTHREAD_CANCEL_DEFERRED */
  void **                     joinvalueptr;
  int                         join_count;

  /* These must be kept in this order and together. */
  _pthread_handler_node_t *   cleanupstack;
  _pthread_handler_node_t *   destructorstack;
  _pthread_handler_node_t *   forkpreparestack;
  _pthread_handler_node_t *   forkparentstack;
  _pthread_handler_node_t *   forkchildstack;
};

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* Generic handler push and pop routines. */

int _pthread_handler_push(int stack,
			  int poporder,
			  void (*routine)(void *),
			  void *arg);

void _pthread_handler_pop(int stack,
			  int execute);

void _pthread_handler_pop_all(int stack,
			      int execute);

/* Primitives to manage threads table entries. */

int _pthread_new_thread_entry(pthread_t thread,
			      _pthread_threads_thread_t * entry);

_pthread_threads_thread_t * _pthread_find_thread_entry(pthread_t thread);

void _pthread_delete_thread_entry(_pthread_threads_thread_t * this);

/* Thread cleanup. */

void _pthread_vacuum(void);

void _pthread_exit(void * value, int return_code);

#ifdef __cplusplus
}
#endif /* __cplusplus */


/* Global data declared in global.c */

extern pthread_mutex_t _pthread_table_mutex;

extern DWORD _pthread_threads_count;

extern _pthread_threads_thread_t _pthread_threads_table[];

extern pthread_mutex_t _pthread_threads_mutex_table[];

#endif /* _IMPLEMENT_H */