mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-08-02 03:16:11 -04:00
Added sharedThread library
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Thread.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedThread/Thread.h"
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
#include <cstdio>
|
||||
|
||||
class MainThread: public Thread
|
||||
{
|
||||
public:
|
||||
MainThread(const std::string &name): Thread(name) {}
|
||||
protected:
|
||||
void run() {}
|
||||
private:
|
||||
MainThread(const MainThread &o);
|
||||
MainThread &operator =(const MainThread &o);
|
||||
};
|
||||
|
||||
pthread_key_t Thread::implindex;
|
||||
Thread * Thread::mainThread;
|
||||
|
||||
void Thread::install()
|
||||
{
|
||||
DEBUG_FATAL(mainThread, ("Thread::install: already installed"));
|
||||
ExitChain::add(remove, "Thread::remove");
|
||||
|
||||
pthread_key_create(&implindex, 0);
|
||||
mainThread = new MainThread("Main");
|
||||
mainThread->attach();
|
||||
}
|
||||
|
||||
void Thread::remove()
|
||||
{
|
||||
DEBUG_FATAL(!mainThread, ("Thread::remove: not installed"));
|
||||
DEBUG_FATAL(mainThread->refcount > 1, ("Someone still holds the main thread"));
|
||||
delete mainThread;
|
||||
pthread_key_delete(implindex);
|
||||
|
||||
mainThread = 0;
|
||||
}
|
||||
|
||||
Thread::Thread(const std::string &i_name)
|
||||
: refcount(1), name(i_name)
|
||||
{
|
||||
doneFlag = false;
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
pthread_create(&thread, 0, threadFunc, this);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
}
|
||||
|
||||
void Thread::attach()
|
||||
{
|
||||
thread = pthread_self();
|
||||
pthread_setspecific(implindex, this);
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
pthread_detach(thread);
|
||||
}
|
||||
|
||||
void * Thread::threadFunc(void * i)
|
||||
{
|
||||
Thread * impl = static_cast<Thread *>(i);
|
||||
pthread_setspecific(implindex, impl);
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
Os::setThreadName(impl->thread, impl->name.c_str());
|
||||
PerThreadData::threadInstall(true);
|
||||
impl->run();
|
||||
PerThreadData::threadRemove();
|
||||
impl->kill();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Thread::kill()
|
||||
{
|
||||
int t = getCurrentThread()->thread;
|
||||
doneFlag = true;
|
||||
deref();
|
||||
if (this == getCurrentThread())
|
||||
{
|
||||
pthread_exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_cancel(t);
|
||||
}
|
||||
}
|
||||
|
||||
bool Thread::done()
|
||||
{
|
||||
return doneFlag;
|
||||
}
|
||||
|
||||
void Thread::wait()
|
||||
{
|
||||
if (!doneFlag)
|
||||
{
|
||||
void * junk;
|
||||
pthread_join(thread, &junk);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int interpPriority(float t, int policy)
|
||||
{
|
||||
return (int)(sched_get_priority_max(policy)*t + sched_get_priority_min(policy)*(1-t));
|
||||
}
|
||||
|
||||
void Thread::setPriority(ePriority priority)
|
||||
{
|
||||
static int policies[] =
|
||||
{
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_OTHER,
|
||||
SCHED_FIFO
|
||||
};
|
||||
static int priorities[] =
|
||||
{
|
||||
interpPriority(0.0, SCHED_OTHER),
|
||||
interpPriority(0.25, SCHED_OTHER),
|
||||
interpPriority(0.5, SCHED_OTHER),
|
||||
interpPriority(0.75, SCHED_OTHER),
|
||||
interpPriority(0.75, SCHED_FIFO)
|
||||
};
|
||||
sched_param p;
|
||||
p.sched_priority = priorities[priority];
|
||||
pthread_setschedparam(thread, policies[priority], &p);
|
||||
}
|
||||
|
||||
// Make sure the header-only files compile :)
|
||||
|
||||
#if 0
|
||||
|
||||
#include "sharedSynchronization/CountingSemaphore.h"
|
||||
#include "sharedSynchronization/BlockingPointer.h"
|
||||
#include "sharedSynchronization/BlockingQueue.h"
|
||||
#include "sharedSynchronization/WriteOnce.h"
|
||||
|
||||
Mutex t;
|
||||
BlockingQueue<int> bqint(t, 0, 0);
|
||||
BlockingPointer<int> bpint(t, 0, 0);
|
||||
WriteOnce<int> woint;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Thread.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Thread_h
|
||||
#define INCLUDED_Thread_h
|
||||
|
||||
#include "sharedSynchronization/InterlockedInteger.h"
|
||||
#include <string>
|
||||
|
||||
class Thread
|
||||
{
|
||||
template <class T> friend class TypedThreadHandle;
|
||||
public:
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
Thread(const std::string &i_name=std::string());
|
||||
|
||||
void kill();
|
||||
bool done();
|
||||
void wait();
|
||||
|
||||
enum ePriority
|
||||
{
|
||||
kIdle = 0,
|
||||
kLow = 1,
|
||||
kNormal = 2,
|
||||
kHigh = 3,
|
||||
kCritical = 4
|
||||
};
|
||||
void setPriority(ePriority priority);
|
||||
|
||||
const std::string &getName() const;
|
||||
void setName(const std::string &i_name);
|
||||
|
||||
static Thread * getCurrentThread();
|
||||
static Thread * getMainThread();
|
||||
protected:
|
||||
virtual ~Thread();
|
||||
virtual void run()=0;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
InterlockedInteger refcount;
|
||||
private:
|
||||
Thread(const Thread &o);
|
||||
Thread &operator =(const Thread &o);
|
||||
|
||||
void start();
|
||||
void attach(); // pick up the currently running thread
|
||||
|
||||
void ref();
|
||||
void deref();
|
||||
|
||||
bool doneFlag;
|
||||
|
||||
std::string name;
|
||||
|
||||
static pthread_key_t implindex;
|
||||
static Thread * mainThread;
|
||||
static void * threadFunc(void * data);
|
||||
};
|
||||
|
||||
inline void Thread::ref()
|
||||
{
|
||||
++refcount;
|
||||
}
|
||||
|
||||
inline void Thread::deref()
|
||||
{
|
||||
if (--refcount == 0) delete this;
|
||||
}
|
||||
|
||||
inline Thread * Thread::getCurrentThread()
|
||||
{
|
||||
return static_cast<Thread *>(pthread_getspecific(implindex));
|
||||
}
|
||||
|
||||
inline Thread * Thread::getMainThread()
|
||||
{
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
inline const std::string &Thread::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void Thread::setName(const std::string &i_name)
|
||||
{
|
||||
name = i_name;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user