37#include "tinycthread/tinycthread.h"
44#define SCIPtnyInitLock(lock) ( mtx_init((lock), mtx_plain) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
45#define SCIPtnyDestroyLock(lock) ( mtx_destroy(lock) )
46#define SCIPtnyAcquireLock(lock) ( mtx_lock(lock) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
47#define SCIPtnyReleaseLock(lock) ( mtx_unlock(lock) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
50#define SCIPtnyInitCondition(condition) ( cnd_init(condition) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
51#define SCIPtnyDestroyCondition(condition) ( cnd_destroy(condition) )
52#define SCIPtnySignalCondition(condition) ( cnd_signal(condition) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
53#define SCIPtnyBroadcastCondition(condition) ( cnd_broadcast(condition) == thrd_success ? SCIP_OKAY : SCIP_ERROR )
54#define SCIPtnyWaitCondition(condition, lock) ( cnd_wait((condition), (lock)) == thrd_success ? SCIP_OKAY: SCIP_ERROR )
71_Thread_local
int _threadnumber;
131 _threadnumber = (int)(uintptr_t) threadnum;
135 _threadpool->currworkingthreads += 1;
144 while( _threadpool->jobqueue->njobs == 0 && !_threadpool->shutdown )
150 if( _threadpool->shutdown )
153 _threadpool->currworkingthreads -= 1;
160 newjob = _threadpool->jobqueue->firstjob;
161 _threadpool->jobqueue->njobs--;
163 if( _threadpool->jobqueue->njobs == 0 )
165 _threadpool->jobqueue->firstjob =
NULL;
166 _threadpool->jobqueue->lastjob =
NULL;
169 _threadpool->jobqueue->firstjob = newjob->
nextjob;
172 if( _threadpool->blockwhenfull &&
173 _threadpool->jobqueue->njobs == _threadpool->queuesize - 1 )
179 if( _threadpool->jobqueue->njobs == 0 )
185 if( _threadpool->currentjobs->njobs == 0 )
187 _threadpool->currentjobs->firstjob = newjob;
188 _threadpool->currentjobs->lastjob = newjob;
192 _threadpool->currentjobs->lastjob->nextjob = newjob;
193 _threadpool->currentjobs->lastjob = newjob;
196 _threadpool->currentjobs->njobs++;
207 currjob = _threadpool->currentjobs->firstjob;
210 while( currjob != newjob )
217 if( currjob == _threadpool->currentjobs->firstjob )
218 _threadpool->currentjobs->firstjob = currjob->
nextjob;
222 if( currjob == _threadpool->currentjobs->lastjob )
223 _threadpool->currentjobs->lastjob = prevjob;
225 _threadpool->currentjobs->njobs--;
228 if( _threadpool->finishedjobs->njobs == 0 )
230 _threadpool->finishedjobs->firstjob = newjob;
231 _threadpool->finishedjobs->lastjob = newjob;
235 _threadpool->finishedjobs->lastjob->nextjob = newjob;
236 _threadpool->finishedjobs->lastjob = newjob;
239 _threadpool->finishedjobs->njobs++;
273 (*thrdpool)->currentid = 0;
274 (*thrdpool)->queuesize = qsize;
275 (*thrdpool)->nthreads = nthreads;
276 (*thrdpool)->blockwhenfull = blockwhenfull;
277 (*thrdpool)->shutdown =
FALSE;
278 (*thrdpool)->queueopen =
TRUE;
282 (*thrdpool)->jobqueue->firstjob =
NULL;
283 (*thrdpool)->jobqueue->lastjob =
NULL;
284 (*thrdpool)->jobqueue->njobs = 0;
288 (*thrdpool)->currentjobs->firstjob =
NULL;
289 (*thrdpool)->currentjobs->lastjob =
NULL;
290 (*thrdpool)->currentjobs->njobs = 0;
294 (*thrdpool)->finishedjobs->firstjob =
NULL;
295 (*thrdpool)->finishedjobs->lastjob =
NULL;
296 (*thrdpool)->finishedjobs->njobs = 0;
308 (*thrdpool)->currworkingthreads = 0;
314 for(
i = 0;
i < (unsigned)nthreads;
i++ )
316 if( thrd_create(&((*thrdpool)->threads[
i]),
threadPoolThread, (
void*)
i) != thrd_success )
320 _threadnumber = nthreads;
378 if( _threadpool->jobqueue->njobs == _threadpool->queuesize && _threadpool->blockwhenfull )
388 while( _threadpool->jobqueue->njobs == _threadpool->queuesize && !(_threadpool->shutdown || !_threadpool->queueopen) )
394 if( !_threadpool->queueopen )
400 else if( _threadpool->shutdown )
412 assert(_threadpool->jobqueue->njobs != _threadpool->queuesize);
464 if( !(*thrdpool)->queueopen || (*thrdpool)->shutdown )
472 (*thrdpool)->queueopen =
FALSE;
477 while( (*thrdpool)->jobqueue->njobs > 0 )
484 (*thrdpool)->shutdown =
TRUE;
497 for(
i = 0;
i < (*thrdpool)->nthreads;
i++ )
501 if( thrd_join((*thrdpool)->threads[
i], &thrdretcode) != thrd_success )
511 assert((*thrdpool)->currentjobs->njobs == 0);
513 assert((*thrdpool)->finishedjobs->njobs == 0);
543 if( currjob !=
NULL )
545 while( currjob != jobqueue->
lastjob )
547 if( currjob->
jobid == jobid )
553 if( currjob->
jobid == jobid )
578 return _threadpool !=
NULL ? _threadpool->nthreads : 0;
615 (*job)->jobid = jobid;
616 (*job)->jobfunc = jobfunc;
617 (*job)->args = jobarg;
618 (*job)->nextjob =
NULL;
632 id = ++_threadpool->currentid;
673 currjob = _threadpool->finishedjobs->firstjob;
678 if( currjob->
jobid == jobid )
688 if( currjob == _threadpool->finishedjobs->firstjob )
690 _threadpool->finishedjobs->firstjob = currjob->
nextjob;
698 if( currjob == _threadpool->finishedjobs->lastjob )
699 _threadpool->finishedjobs->lastjob = prevjob;
701 _threadpool->finishedjobs->njobs--;
735 if( mtx_init(&(*lock)->lock, mtx_plain) == thrd_success )
751 mtx_destroy(&(*lock)->lock);
760 if( mtx_lock(&lock->
lock) == thrd_success )
770 if( mtx_unlock(&lock->
lock) == thrd_success )
789 if( cnd_init(&(*condition)->condition) == thrd_success )
799 cnd_destroy(&(*condition)->condition);
808 if( cnd_signal(&condition->
condition) == thrd_success )
819 if( cnd_broadcast(&condition->
condition) == thrd_success )
832 if( cnd_wait(&condition->
condition, &lock->
lock) == thrd_success )
842 return _threadnumber;
859 (void)
SCIPsnprintf(name, namesize,
"TinyCThread %d.%d", TINYCTHREAD_VERSION_MAJOR, TINYCTHREAD_VERSION_MINOR);
870 (void)
SCIPsnprintf(desc, descsize,
"small portable implementation of the C11 threads API (tinycthread.github.io)");
#define SCIP_CALL_ABORT(x)
int SCIPsnprintf(char *t, int len, const char *s,...)
assert(minobj< SCIPgetCutoffbound(scip))
memory allocation routines
#define BMSfreeMemory(ptr)
#define BMSallocMemoryArray(ptr, num)
#define BMSfreeMemoryArray(ptr)
#define BMSallocMemory(ptr)
public methods for message output
public data structures and miscellaneous methods
struct SCIP_Job * nextjob
SCIP_RETCODE(* jobfunc)(void *args)
SCIP_JOBQUEUE * currentjobs
SCIP_JOBQUEUE * finishedjobs
the type definitions for the SCIP parallel interface
static SCIP_RETCODE freeJobQueue(void)
struct SCIP_JobQueue SCIP_JOBQUEUE
static SCIP_Bool isJobRunning(int jobid)
static SCIP_RETCODE threadPoolAddWork(SCIP_JOB *newjob, SCIP_SUBMITSTATUS *status)
static SCIP_JOBSTATUS checkJobQueue(SCIP_JOBQUEUE *jobqueue, int jobid)
SCIP_Bool SCIPtpiIsAvailable(void)
SCIP_RETCODE SCIPtpiWaitCondition(SCIP_CONDITION *condition, SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiCreateJob(SCIP_JOB **job, int jobid, SCIP_RETCODE(*jobfunc)(void *args), void *jobarg)
static SCIP_RETCODE threadPoolThreadRetcode(void *threadnum)
SCIP_RETCODE SCIPtpiSignalCondition(SCIP_CONDITION *condition)
SCIP_RETCODE SCIPtpiAcquireLock(SCIP_LOCK *lock)
#define SCIPtnyInitCondition(condition)
static SCIP_RETCODE createThreadPool(SCIP_THREADPOOL **thrdpool, int nthreads, int qsize, SCIP_Bool blockwhenfull)
static void jobQueueAddJob(SCIP_THREADPOOL *threadpool, SCIP_JOB *newjob)
SCIP_RETCODE SCIPtpiExit(void)
#define SCIPtnyInitLock(lock)
SCIP_RETCODE SCIPtpiBroadcastCondition(SCIP_CONDITION *condition)
#define SCIPtnyBroadcastCondition(condition)
SCIP_RETCODE SCIPtpiSubmitJob(SCIP_JOB *job, SCIP_SUBMITSTATUS *status)
static SCIP_Bool isJobRunning(SCIP_JOBQUEUE *currentjobs, int jobid)
void SCIPtpiDestroyLock(SCIP_LOCK **lock)
void SCIPtpiGetLibraryDesc(char *desc, int descsize)
SCIP_RETCODE SCIPtpiCollectJobs(int jobid)
#define SCIPtnyWaitCondition(condition, lock)
struct SCIP_ThreadPool SCIP_THREADPOOL
#define SCIPtnyReleaseLock(lock)
#define SCIPtnyDestroyCondition(condition)
#define SCIPtnySignalCondition(condition)
int SCIPtpiGetThreadNum(void)
int SCIPtpiGetNumThreads(void)
void SCIPtpiDestroyCondition(SCIP_CONDITION **condition)
int SCIPtpiGetNewJobID(void)
#define SCIPtnyDestroyLock(lock)
static int threadPoolThread(void *threadnum)
void SCIPtpiGetLibraryName(char *name, int namesize)
SCIP_RETCODE SCIPtpiInitLock(SCIP_LOCK **lock)
static SCIP_RETCODE freeThreadPool(SCIP_THREADPOOL **thrdpool, SCIP_Bool finishjobs, SCIP_Bool completequeue)
SCIP_RETCODE SCIPtpiReleaseLock(SCIP_LOCK *lock)
SCIP_RETCODE SCIPtpiInitCondition(SCIP_CONDITION **condition)
#define SCIPtnyAcquireLock(lock)
SCIP_RETCODE SCIPtpiInit(int nthreads, int queuesize, SCIP_Bool blockwhenfull)
enum SCIP_Retcode SCIP_RETCODE
enum SCIP_Submitstatus SCIP_SUBMITSTATUS
struct SCIP_Condition SCIP_CONDITION
enum SCIP_Jobstatus SCIP_JOBSTATUS
@ SCIP_SUBMIT_QUEUECLOSED
struct SCIP_Lock SCIP_LOCK