Files
2026-06-22 11:49:35 +02:00

132 lines
2.5 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __JOB_SYSTEM__
#define __JOB_SYSTEM__
#define __USE_LOCK_FREE_JOB_QUEUE__ 1
#include "thread/thread_event.h"
#include "thread/thread.h"
#include "thread/mutex.h"
#include "container/nlist.h"
#if __USE_LOCK_FREE_JOB_QUEUE__
#include "container/mpmc_bounded_queue.h"
#else
#include "container/nstack.h"
#endif
#include "container/narray.h"
#include "memory/nauto_ptr.h"
#include "nstring/nstring.h"
#include "time/ntime.h"
namespace GS {
namespace ASync {
class JobManager;
//
class JobWorkerThread : public Threading::Thread
{
protected:
JobManager &manager;
Threading::Atomic32 running;
uint worker_id;
public:
/// Get worker id.
int GetWorkerId() const { return worker_id; }
/// Worker loop.
virtual void Execute();
/// Stop worker thread.
void Stop();
/// Is the worker thread running.
bool IsRunning() const;
JobWorkerThread(JobManager &m, uint id) : manager(m), worker_id(id) {}
};
/// Parallel job.
struct Job
{
String name;
Time time_start, time_end;
Threading::Atomic32 done;
/// Execute job.
virtual void Execute(uint worker_id) = 0;
Job(const char *_name) : name(_name), done(1) {}
virtual ~Job() {}
};
/// Job group.
class JobGroup
{
friend class JobManager;
AutoPtr <Threading::Mutex> job_list_mutex;
List <Job *> job_list;
public:
JobGroup();
};
//
class JobManager
{
friend class JobWorkerThread;
protected:
Array <JobWorkerThread *> pool;
#if __USE_LOCK_FREE_JOB_QUEUE__
mpmc_bounded_queue <Job *> pending_queue;
#else
AutoPtr <Mutex> pending_queue_mutex;
Stack <Job *> pending_queue;
#endif
public:
Threading::Event job_queued_event;
/// Wait for a job to complete.
bool JoinJob(Job *, bool blocking = true);
/// Wait for a job group to complete.
bool JoinGroup(JobGroup *, bool blocking = true);
/// Execute a pending job on the caller thread.
bool ExecutePendingJob(uint worker_id);
bool EnqueueJob(Job * = 0, JobGroup * = 0);
/// Get the number of worker.
uint GetWorkerPoolSize() const;
/// Create the job worker thread pool.
bool CreateJobThreadPool(uint count = 0);
/// Free the job worker thread pool.
void FreeJobThreadPool();
JobManager();
~JobManager();
};
} // ASync
} // GS
#endif // __JOB_SYSTEM__