32 #ifndef _QORE_QORETHREADLIST_H
34 #define _QORE_QORETHREADLIST_H
36 #include <qore/QoreRWLock.h>
40 #ifndef MAX_QORE_THREADS
41 #define MAX_QORE_THREADS 0x1000
49 #define QTS_RESERVED 3
51 #if defined(DARWIN) && MAX_QORE_THREADS > 2560 && !defined(__MAC_10_7)
57 #warning Darwin cannot support more than 2560 threads, MAX_QORE_THREADS set to 2560
58 #undef MAX_QORE_THREADS
59 #define MAX_QORE_THREADS 2560
65 tid_node* next, *prev;
67 DLLLOCAL tid_node(
int ntid);
76 ThreadData* thread_data;
80 DLLLOCAL
void cleanup();
82 DLLLOCAL
void allocate(tid_node* tn,
int stat = QTS_NA);
84 DLLLOCAL
void activate(
int tid, pthread_t n_ptid,
QoreProgram* p,
bool foreign =
false);
86 DLLLOCAL
bool active()
const {
87 return status == QTS_ACTIVE;
90 DLLLOCAL
bool available()
const {
91 return status == QTS_AVAIL;
95 class QoreThreadList {
96 friend class QoreThreadListIterator;
97 friend class tid_node;
105 DLLLOCAL QoreThreadList() {
108 DLLLOCAL
int get(
int status = QTS_NA) {
112 if (current_tid == MAX_QORE_THREADS) {
115 for (i = 1; i < MAX_QORE_THREADS; i++) {
116 if (entry[i].available()) {
121 if (i == MAX_QORE_THREADS) {
129 entry[tid].allocate(
new tid_node(tid), status);
136 DLLLOCAL
int getSignalThreadEntry() {
138 entry[0].allocate(0);
142 DLLLOCAL
void release(
int tid) {
147 DLLLOCAL
int releaseReserved(
int tid) {
149 if (entry[tid].status != QTS_RESERVED) {
157 DLLLOCAL
void activate(
int tid, pthread_t ptid = pthread_self(),
QoreProgram* p = 0,
bool foreign =
false) {
159 entry[tid].activate(tid, ptid, p, foreign);
162 DLLLOCAL
void setStatus(
int tid,
int status) {
164 assert(entry[tid].status != status);
165 entry[tid].status = status;
168 DLLLOCAL
void deleteData(
int tid);
170 DLLLOCAL
void deleteDataRelease(
int tid);
172 DLLLOCAL
void deleteDataReleaseSignalThread();
174 DLLLOCAL
int activateReserved(
int tid) {
177 if (entry[tid].status != QTS_RESERVED) {
181 entry[tid].activate(tid, pthread_self(), 0,
true);
185 DLLLOCAL
unsigned getNumThreads()
const {
189 DLLLOCAL
unsigned cancelAllActiveThreads();
195 DLLLOCAL
static QoreHashNode* getCallStackHash(qore_call_t type,
const std::string& code,
196 const QoreProgramLocation& loc);
203 unsigned num_threads = 0;
204 ThreadEntry entry[MAX_QORE_THREADS];
206 tid_node* tid_head =
nullptr,
207 * tid_tail =
nullptr;
212 bool exiting =
false;
214 DLLLOCAL
void releaseIntern(
int tid) {
217 entry[tid].cleanup();
224 DLLLOCAL
extern QoreThreadList thread_list;
226 class QoreThreadListIterator :
public AutoLocker {
228 DLLLOCAL QoreThreadListIterator(
bool access_stack =
false) :
AutoLocker(thread_list.lck),
229 access_stack(access_stack) {
232 thread_list.stack_lck.wrlock();
236 DLLLOCAL ~QoreThreadListIterator() {
239 thread_list.stack_lck.unlock();
243 DLLLOCAL
bool next() {
245 w = w ? w->next : thread_list.tid_head;
246 }
while (w && (!w->tid || (thread_list.entry[w->tid].status != QTS_ACTIVE)));
251 DLLLOCAL
unsigned operator*()
const {
257 tid_node* w =
nullptr;