20 #ifndef LUNCHBOX_THREAD_H
21 #define LUNCHBOX_THREAD_H
24 #include <lunchbox/debug.h>
25 #include <lunchbox/nonCopyable.h>
26 #include <lunchbox/threadID.h>
33 namespace detail {
class Thread; }
65 LUNCHBOX_API
virtual bool start();
78 virtual bool init(){
return true; }
88 virtual void run() = 0;
98 LUNCHBOX_API
virtual void exit();
106 LUNCHBOX_API
void cancel();
114 LUNCHBOX_API
bool join();
149 LUNCHBOX_API
static void yield();
152 static void pinCurrentThread();
155 LUNCHBOX_API
static void setName(
const std::string& name );
167 LUNCHBOX_API
static void setAffinity(
const int32_t affinity );
170 detail::Thread*
const _impl;
174 static void* runChild(
void* arg );
188 # define LB_CHECK_THREADSAFETY
192 #define LB_TS_VAR( NAME ) \
194 struct NAME ## Struct \
197 : extMutex( false ) \
199 mutable lunchbox::ThreadID id; \
200 mutable std::string name; \
202 mutable lunchbox::ThreadID inRegion; \
206 #ifdef LB_CHECK_THREADSAFETY
207 # define LB_TS_RESET( NAME ) NAME.id = lunchbox::ThreadID();
209 # define LB_TS_THREAD( NAME ) \
211 if( NAME.id == lunchbox::ThreadID( )) \
213 NAME.id = lunchbox::Thread::getSelfThreadID(); \
214 NAME.name = lunchbox::Log::instance().getThreadName(); \
215 LBVERB << "Functions for " << #NAME \
216 << " locked to this thread" << std::endl; \
218 if( !NAME.extMutex && NAME.id != lunchbox::Thread::getSelfThreadID( )) \
220 LBERROR << "Threadsafety check for " << #NAME \
221 << " failed on object of type " \
222 << lunchbox::className( this ) << ", thread " \
223 << lunchbox::Thread::getSelfThreadID() << " (" \
224 << lunchbox::Log::instance().getThreadName() << ") != " \
225 << NAME.id << " (" << NAME.name << ")" << std::endl; \
226 LBABORT( "Non-threadsave code called from two threads" ); \
230 # define LB_TS_NOT_THREAD( NAME ) \
232 if( !NAME.extMutex && NAME.id != lunchbox::ThreadID( )) \
234 if( NAME.id == lunchbox::Thread::getSelfThreadID( )) \
236 LBERROR << "Threadsafety check for not " << #NAME \
237 << " failed on object of type " \
238 << lunchbox::className( this ) << std::endl; \
239 LBABORT( "Code called from wrong thread" ); \
245 template<
typename T >
class ScopedThreadCheck :
public NonCopyable
248 explicit ScopedThreadCheck(
const T& data )
253 "Another thread already in critical region" );
261 "Another thread entered critical region" );
269 # define LB_TS_SCOPED( NAME ) \
270 lunchbox::ScopedThreadCheck< NAME ## Struct > scoped ## NAME ## Check(NAME);
273 # define LB_TS_RESET( NAME ) {}
274 # define LB_TS_THREAD( NAME ) {}
275 # define LB_TS_NOT_THREAD( NAME ) {}
276 # define LB_TS_SCOPED( NAME ) {}
280 #endif //LUNCHBOX_THREAD_H