Browse Source

Revamped thread manager to be useful -Thread are job independent now-

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
97b224f4fa
1 changed files with 50 additions and 55 deletions
  1. +50
    -55
      src/lol/sys/thread.h

+ 50
- 55
src/lol/sys/thread.h View File

@@ -45,61 +45,58 @@ public:
virtual ~Thread() {}
};

struct ThreadCommand
struct ThreadStatus
{
enum Value
{
NOTHING = 0,
THREAD_STARTED,
THREAD_STOPPED,
WORK_TODO,
WORK_DONE,
THREAD_STOP,

MAX
}
m_value;

inline ThreadCommand() : m_value(ThreadCommand::MAX) {}
inline ThreadCommand(Value v) : m_value(v) {}
bool operator==(const ThreadCommand& v) { return m_value == v.m_value; }
inline ThreadStatus() : m_value(ThreadStatus::NOTHING) {}
inline ThreadStatus(Value v) : m_value(v) {}
bool operator==(const ThreadStatus& v) { return m_value == v.m_value; }
};

template<typename T1>
struct JobCommand : public ThreadCommand
struct ThreadJobType
{
inline JobCommand()
: ThreadCommand(ThreadCommand::WORK_TODO)
{}

inline JobCommand(Value v)
: ThreadCommand(v)
{}
enum Value
{
NONE = 0,
WORK_TODO,
WORK_DONE,
THREAD_STOP,

inline JobCommand(T1 const &data)
: ThreadCommand(ThreadCommand::WORK_TODO),
m_data(data)
{}
MAX
}
m_value;

inline JobCommand(Value v, T1 const &data)
: ThreadCommand(v),
m_data(data)
{}
inline ThreadJobType() : m_value(ThreadJobType::MAX) {}
inline ThreadJobType(Value v) : m_value(v) {}
bool operator==(const ThreadJobType& o) { return m_value == o.m_value; }
};

inline void SetData(T1 const &data)
{
m_data = data;
}
class ThreadJob
{
friend class ThreadManager;

inline T1 GetData()
{
return m_data;
}
public:
ThreadJob() { m_type = ThreadJobType::NONE; }
ThreadJob(ThreadJobType type) { m_type = type; }
ThreadJobType GetJobType() { return m_type; }
void SetJobType(ThreadJobType type) { m_type = type; }
bool operator==(const ThreadJobType& o) { return GetJobType() == o; }
protected:
virtual bool DoWork() { return false; }

private:
T1 m_data;
ThreadJobType m_type;
};

template<typename T1, typename T2> class ThreadManager
class ThreadManager
{
public:
ThreadManager(int thread_count)
@@ -123,15 +120,15 @@ public:
return true;
}

bool AddWork(const JobCommand<T1>& job)
bool AddWork(ThreadJob* job)
{
if (m_jobqueue.TryPush(job))
return true;
return false;
}
bool FetchResult(Array<JobCommand<T2> >& results)
bool FetchResult(Array<ThreadJob*>& results)
{
JobCommand<T2> result;
ThreadJob* result;
while (m_resultqueue.TryPop(result))
results << result;
return results.Count() > 0;
@@ -140,28 +137,25 @@ public:
static void *BaseThreadWork(void* data)
{
ThreadManager *that = (ThreadManager *)data;
that->m_spawnqueue.Push(ThreadCommand::THREAD_STARTED);
that->m_spawnqueue.Push(ThreadStatus::THREAD_STARTED);
for ( ; ; )
{
JobCommand<T1> job = that->m_jobqueue.Pop();
if (job == ThreadCommand::THREAD_STOP)
ThreadJob* job = that->m_jobqueue.Pop();
if (job->GetJobType() == ThreadJobType::THREAD_STOP)
break;
else if (job == ThreadCommand::WORK_TODO)
else if (*job == ThreadJobType::WORK_TODO)
{
JobCommand<T2> result(ThreadCommand::WORK_DONE);
if (that->DoThreadWork(job, result))
that->m_resultqueue.Push(result);
if (job->DoWork())
{
job->SetJobType(ThreadJobType::WORK_DONE);
that->m_resultqueue.Push(job);
}
}
}
that->m_donequeue.Push(ThreadCommand::THREAD_STOPPED);
that->m_donequeue.Push(ThreadStatus::THREAD_STOPPED);
return NULL;
}

virtual bool DoThreadWork(JobCommand<T1>& job, JobCommand<T2>& result)
{
return false;
}

//Stop the thread
bool Stop()
{
@@ -170,8 +164,9 @@ public:

/* Signal worker threads for completion and wait for
* them to quit. */
ThreadJob stop_job(ThreadJobType::THREAD_STOP);
for (int i = 0; i < m_thread_count; i++)
m_jobqueue.Push(ThreadCommand::THREAD_STOP);
m_jobqueue.Push(&stop_job);
for (int i = 0; i < m_thread_count; i++)
m_donequeue.Pop();

@@ -182,9 +177,9 @@ protected:
/* Worker threads */
int m_thread_count;
Array<Thread*> m_threads;
Queue<ThreadCommand> m_spawnqueue, m_donequeue;
Queue<JobCommand<T1> > m_jobqueue;
Queue<JobCommand<T2> > m_resultqueue;
Queue<ThreadStatus> m_spawnqueue, m_donequeue;
Queue<ThreadJob*> m_jobqueue;
Queue<ThreadJob*> m_resultqueue;
};
#endif



Loading…
Cancel
Save