Commit ff54f802 authored by ahoms's avatar ahoms
Browse files

* added ThreadUtils and AutoObj

* started Simulator main object and interfaces


git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@24 45c4679d-1946-429d-baad-37912b19538b
parent 139e4bd2
#ifndef SIMUHWINTERFACE_H
#define SIMUHWINTERFACE_H
#include "HwInterface.h"
#include "Simulator.h"
namespace lima
{
class SimuHwInterface: public HwInterface
{
public:
SimuHwInterface(Simulator& simu);
virtual ~SimuHwInterface();
virtual const CapList& getCapList() const;
virtual void reset(ResetLevel reset_level);
virtual void prepareAcq();
virtual void startAcq();
virtual void stopAcq();
virtual void getStatus(StatusType& status);
virtual int getNbAcquiredFrames();
virtual double getStartTimeStamp();
private:
Simulator& m_simu;
CapList m_cap_list;
};
}
#endif // SIMUHWINTERFACE_H
#ifndef SIMULATOR_H
#define SIMULATOR_H
#include "HwBufferMgr.h"
#include "FrameBuilder.h"
#include "ThreadUtils.h"
namespace lima
{
class Simulator
{
public:
enum Status {
Ready, Exposure, Readout,
};
Simulator();
~Simulator();
BufferCtrlMgr& getBufferMgr();
void startAcq();
void stopAcq();
void setNbFrames(int nb_frames);
void getNbFrames(int& nb_frames);
void setExpTime(double exp_time);
void getExpTime(double& exp_time);
private:
class SimuThread : public CmdThread
{
public:
enum { // Status
Ready = MaxThreadStatus, Exposure, Readout,
};
enum { // Cmd
StartAcq = MaxThreadCmd, StopAcq,
};
SimuThread(Simulator& simu);
protected:
virtual void init();
virtual void execCmd(int cmd);
private:
Simulator& m_simu;
};
friend class SimuThread;
BufferCtrlMgr m_buffer_mgr;
FrameBuilder m_frame_builder;
double m_exp_time;
int m_nb_frames;
SimuThread m_thread;
};
} // namespace lima
#endif // SIMULATOR_H
objs = FrameBuilder.o
objs = FrameBuilder.o Simulator.o
CXX = g++
CXXFLAGS += -I../include -I../../../common/include -Wall
INC = -I../include -I../../../common/include -I../../../hardware/include
CXXFLAGS += $(INC) -Wall -pthread
all: clean $(objs)
......
#include "SimuHwInterface.h"
using namespace lima;
SimuHwInterface::SimuHwInterface(Simulator& simu)
: m_simu(simu)
{
}
#include "Simulator.h"
using namespace lima;
Simulator::SimuThread::SimuThread(Simulator& simu)
: m_simu(simu)
{
start();
waitStatus(Ready);
}
void Simulator::SimuThread::init()
{
setStatus(Ready);
}
void Simulator::SimuThread::execCmd(int cmd)
{
}
Simulator::Simulator()
: m_thread(*this)
{
m_exp_time = 1.0;
m_nb_frames = 1;
}
Simulator::~Simulator()
{
}
BufferCtrlMgr& Simulator::getBufferMgr()
{
return m_buffer_mgr;
}
#ifndef AUTOOBJ_H
#define AUTOOBJ_H
namespace lima
{
/********************************************************************
* AutoCounter
********************************************************************/
class AutoCounter
{
public:
AutoCounter() : r(1)
{}
void get()
{ r++; }
bool put()
{ return --r == 0; }
int count() const
{ return r; }
private:
int r;
};
/********************************************************************
* AutoLock
********************************************************************/
template <class M>
class AutoLock
{
public:
enum { UnLocked, Locked, TryLocked };
AutoLock(M& mutex, int state=Locked)
{ d = new AutoLockData(mutex, state); }
AutoLock(const AutoLock& o)
{ d = o.getData(); }
~AutoLock()
{ putData(); }
void lock()
{ d->lock(); }
void unlock()
{ d->unlock(); }
bool tryLock()
{ return d->tryLock(); }
M& mutex() const
{ return d->mutex(); }
bool locked() const
{ return d->locked(); }
private:
class AutoLockData
{
public:
AutoLockData(M& mutex, int state=Locked)
: m(mutex), l(false)
{
switch (state) {
case Locked: lock(); break;
case TryLocked: tryLock(); break;
default: break;
}
}
~AutoLockData()
{
if (l)
unlock();
}
AutoLockData *get()
{
c.get();
return this;
}
bool put()
{
return c.put();
}
void lock()
{
m.lock();
l = true;
}
void unlock()
{
m.unlock();
l = false;
}
bool tryLock()
{
l = m.tryLock();
return l;
}
M& mutex() const
{ return m; }
bool locked() const
{ return l; }
private:
AutoCounter c;
M& m;
bool l;
};
AutoLockData *getData() const
{ return d->get(); }
void putData()
{
if (d->put())
delete d;
d = NULL;
}
AutoLockData *d;
};
/********************************************************************
* AutoPtr
********************************************************************/
template <class T, bool array=false>
class AutoPtr
{
public:
AutoPtr()
{ d = new AutoPtrData(); }
AutoPtr(T *ptr)
{ d = new AutoPtrData(ptr); }
AutoPtr(const AutoPtr& o)
{ d = o.getData(); }
~AutoPtr()
{ putData(); }
T *getPtr() const
{ return d->getPtr(); }
void setPtr(T *ptr)
{
putData();
d = new AutoPtrData(ptr);
}
operator T*() const
{ return getPtr(); }
T *operator ->() const
{ return getPtr(); }
T& operator[](int i)
{ return getPtr()[i]; }
const T& operator[](int i) const
{ return getPtr()[i]; }
AutoPtr& operator =(T *ptr)
{
setPtr(ptr);
return *this;
}
AutoPtr& operator =(AutoPtr& o)
{
AutoPtrData *od = o.getData(); // protects against "a = a"
putData();
d = od;
return *this;
}
void free()
{ d->free(); }
T *forget()
{
T *ptr = d->forget();
putData();
d = new AutoPtrData();
return ptr;
}
private:
class AutoPtrData
{
public:
AutoPtrData(T *ptr = NULL) : p(ptr)
{}
~AutoPtrData()
{
free();
}
AutoPtrData *get()
{
c.get();
return this;
}
bool put()
{
return c.put();
}
void free()
{
if (!p)
return;
if (array)
delete [] p;
else
delete p;
p = NULL;
}
T *forget()
{
T *ptr = getPtr();
if (c.count() == 1)
p = NULL;
return ptr;
}
T *getPtr() const
{ return p; }
void setPtr(T *ptr)
{ p = ptr; }
private:
T *p;
AutoCounter c;
};
AutoPtrData *getData() const
{ return d->get(); }
void putData()
{
if (d->put())
delete d;
d = NULL;
}
AutoPtrData *d;
};
} // namespace lima
#endif // AUTOOBJ_H
#ifndef THREADUTILS_H
#define THREADUTILS_H
#include "Exceptions.h"
#include "AutoObj.h"
#include <pthread.h>
namespace lima
{
class Mutex;
class Cond;
class MutexAttr
{
public:
enum Type {
Normal, Recursive, ErrorCheck,
};
MutexAttr(Type type = Recursive);
MutexAttr(const MutexAttr& mutex_attr);
~MutexAttr();
void setType(Type type);
Type getType() const;
MutexAttr& operator =(Type type);
MutexAttr& operator =(const MutexAttr& mutex_attr);
private:
void destroy();
friend class Mutex;
pthread_mutexattr_t m_mutex_attr;
};
class Mutex
{
public:
Mutex(MutexAttr mutex_attr = MutexAttr::Recursive);
~Mutex();
void lock();
void unlock();
bool tryLock();
MutexAttr getAttr();
private:
friend class Cond;
MutexAttr m_mutex_attr;
pthread_mutex_t m_mutex;
};
typedef AutoLock<Mutex> AutoMutex;
class Cond
{
public:
Cond();
~Cond();
void wait(Mutex& mutex);
void signal();
private:
pthread_cond_t m_cond;
};
class Thread
{
public:
Thread();
virtual ~Thread();
virtual void start();
virtual void abort();
bool hasStarted();
bool hasFinished();
protected:
virtual void threadFunction() = 0;
private:
static void *staticThreadFunction(void *data);
pthread_t m_thread;
bool m_started;
bool m_finished;
};
class CmdThread
{
public:
enum { // Status
InInit, Stopped, Finished, MaxThreadStatus,
};
enum { // Cmd
None, Init, Stop, Abort, MaxThreadCmd,
};
CmdThread();
virtual ~CmdThread();
virtual void start();
virtual void abort();
void sendCmd(int cmd);
int getStatus();
void waitStatus(int status);
int waitNotStatus(int status);
protected:
virtual void init() = 0;
virtual void execCmd(int cmd) = 0;
int waitNextCmd();
void setStatus(int status);
AutoMutex lock();
AutoMutex tryLock();
private:
class AuxThread : public Thread
{
public:
AuxThread(CmdThread& master);
virtual ~AuxThread();
protected:
void threadFunction();
CmdThread& m_master;
};
friend class AuxThread;
void cmdLoop();
AuxThread m_thread;
Mutex m_mutex;
Cond m_cond;
int m_status;
int m_cmd;
};
}
#endif // THREADUTILS_H
common-objs := SizeUtils.o Timestamp.o
common-objs := SizeUtils.o Timestamp.o ThreadUtils.o
CXXFLAGS += -I../include -Wall
CXXFLAGS += -I../include -Wall -pthread
all: clean Common.o
......
#include "ThreadUtils.h"
#include <errno.h>
using namespace lima;
MutexAttr::MutexAttr(Type type)
{
if (pthread_mutexattr_init(&m_mutex_attr) != 0)
throw LIMA_COM_EXC(Error, "Error initializing mutex attr");
try {
setType(type);
} catch (...) {
destroy();
throw;