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
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;
96friend class QoreThreadListIterator;
97friend class QoreThreadDataHelper;
106 DLLLOCAL QoreThreadList() {
109 DLLLOCAL ThreadData* getThreadData(
int tid) {
110 return entry[tid].active()
111 ? entry[tid].thread_data
115 DLLLOCAL
int get(
int status = QTS_NA,
bool reuse_last =
false) {
119 if (current_tid == MAX_QORE_THREADS) {
120 int i = last_tid + 1;
123 if (i == MAX_QORE_THREADS) {
129 assert(i && i < MAX_QORE_THREADS);
130 if (entry[i].available()) {
142 }
else if (reuse_last && current_tid && entry[current_tid - 1].available()) {
143 printd(5,
"QoreThreadList::get() reusing TID %d\n", current_tid - 1);
145 tid = current_tid - 1;
149 assert(entry[tid].available());
151 entry[tid].allocate(
new tid_node(tid), status);
158 DLLLOCAL
int getSignalThreadEntry() {
160 entry[0].allocate(0);
164 DLLLOCAL
void release(
int tid) {
169 DLLLOCAL
int releaseReserved(
int tid) {
171 if (entry[tid].status != QTS_RESERVED) {
179 DLLLOCAL
void activate(
int tid, pthread_t ptid = pthread_self(),
QoreProgram* p =
nullptr,
bool foreign =
false) {
181 entry[tid].activate(tid, ptid, p, foreign);
184 DLLLOCAL
void setStatus(
int tid,
int status) {
186 assert(entry[tid].status != status);
187 entry[tid].status = status;
190 DLLLOCAL
void deleteData(
int tid);
192 DLLLOCAL
void deleteDataRelease(
int tid);
194 DLLLOCAL
void deleteDataReleaseSignalThread();
196 DLLLOCAL
int activateReserved(
int tid) {
199 if (entry[tid].status != QTS_RESERVED) {
203 entry[tid].activate(tid, pthread_self(),
nullptr,
true);
207 DLLLOCAL
unsigned getNumThreads()
const {
211 DLLLOCAL
unsigned cancelAllActiveThreads();
217 DLLLOCAL
static QoreHashNode* getCallStackHash(qore_call_t type,
const std::string& code,
218 const QoreProgramLocation& loc);
225 unsigned num_threads = 0;
226 ThreadEntry entry[MAX_QORE_THREADS];
228 tid_node* tid_head =
nullptr,
229 * tid_tail =
nullptr;
237 bool exiting =
false;
239 DLLLOCAL
void releaseIntern(
int tid) {
242 entry[tid].cleanup();
249DLLLOCAL
extern QoreThreadList thread_list;
251class QoreThreadListIterator :
public AutoLocker {
253 DLLLOCAL QoreThreadListIterator(
bool access_stack =
false) :
AutoLocker(thread_list.
lck),
254 access_stack(access_stack) {
257 thread_list.stack_lck.wrlock();
261 DLLLOCAL ~QoreThreadListIterator() {
264 thread_list.stack_lck.unlock();
268 DLLLOCAL
bool next() {
270 w = w ? w->next : thread_list.tid_head;
271 }
while (w && (!w->tid || (thread_list.entry[w->tid].status != QTS_ACTIVE)));
276 DLLLOCAL
unsigned operator*()
const {
282 tid_node* w =
nullptr;
286class QoreThreadDataHelper :
public AutoLocker {
288 DLLLOCAL QoreThreadDataHelper(
int tid) :
AutoLocker(thread_list.
lck), tid(tid) {
291 DLLLOCAL ThreadData* get() {
292 if (tid >= 0 && tid < MAX_QORE_THREADS) {
293 return thread_list.getThreadData(tid);
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:136
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:178
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition: QoreHashNode.h:50
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
provides a simple POSIX-threads-based read-write lock
Definition: QoreRWLock.h:47
Stack location element abstract class.
Definition: ExceptionSink.h:418
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49