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,
bool reuse_last =
false) {
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) {
124 }
else if (reuse_last && current_tid && entry[current_tid - 1].available()) {
126 tid = current_tid - 1;
132 entry[tid].allocate(
new tid_node(tid), status);
139 DLLLOCAL
int getSignalThreadEntry() {
141 entry[0].allocate(0);
145 DLLLOCAL
void release(
int tid) {
150 DLLLOCAL
int releaseReserved(
int tid) {
152 if (entry[tid].status != QTS_RESERVED) {
160 DLLLOCAL
void activate(
int tid, pthread_t ptid = pthread_self(),
QoreProgram* p =
nullptr,
bool foreign =
false) {
162 entry[tid].activate(tid, ptid, p, foreign);
165 DLLLOCAL
void setStatus(
int tid,
int status) {
167 assert(entry[tid].status != status);
168 entry[tid].status = status;
171 DLLLOCAL
void deleteData(
int tid);
173 DLLLOCAL
void deleteDataRelease(
int tid);
175 DLLLOCAL
void deleteDataReleaseSignalThread();
177 DLLLOCAL
int activateReserved(
int tid) {
180 if (entry[tid].status != QTS_RESERVED) {
184 entry[tid].activate(tid, pthread_self(),
nullptr,
true);
188 DLLLOCAL
unsigned getNumThreads()
const {
192 DLLLOCAL
unsigned cancelAllActiveThreads();
198 DLLLOCAL
static QoreHashNode* getCallStackHash(qore_call_t type,
const std::string& code,
199 const QoreProgramLocation& loc);
206 unsigned num_threads = 0;
207 ThreadEntry entry[MAX_QORE_THREADS];
209 tid_node* tid_head =
nullptr,
210 * tid_tail =
nullptr;
215 bool exiting =
false;
217 DLLLOCAL
void releaseIntern(
int tid) {
220 entry[tid].cleanup();
227 DLLLOCAL
extern QoreThreadList thread_list;
229 class QoreThreadListIterator :
public AutoLocker {
231 DLLLOCAL QoreThreadListIterator(
bool access_stack =
false) :
AutoLocker(thread_list.lck),
232 access_stack(access_stack) {
235 thread_list.stack_lck.wrlock();
239 DLLLOCAL ~QoreThreadListIterator() {
242 thread_list.stack_lck.unlock();
246 DLLLOCAL
bool next() {
248 w = w ? w->next : thread_list.tid_head;
249 }
while (w && (!w->tid || (thread_list.entry[w->tid].status != QTS_ACTIVE)));
254 DLLLOCAL
unsigned operator*()
const {
260 tid_node* w =
nullptr;
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:136
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:127
provides a simple POSIX-threads-based read-write lock
Definition: QoreRWLock.h:47
Stack location element abstract class.
Definition: ExceptionSink.h:409
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49