Commit 038874df authored by berenger-bramas's avatar berenger-bramas
Browse files

Remove useless file.

This file were added to prepare a generic multi-threading system.
But it may not be used until a long time (so we delete them maybe temporary).

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@26 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 69deecb3
#ifndef FABSTRACTTHREAD_HPP
#define FABSTRACTTHREAD_HPP
// /!\ Please, you must read the license at the bottom of this page
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractThreaded
* Please read the license
*
* This class is an interface for threaded class.
* Each class that wants to use thread must inherited from FOpenMPThreaded or FPosixThreaded.
*
* Please refere to testThread.cpp to see an example.
* <code>
* // Example with FOpenMPThread <br>
* class TOpen : public FOpenMPThread<TOpen>{ <br>
* public: <br>
* void threadCallback(const int inThreadId, const int){ <br>
* printf("I am %d\n",inThreadId); <br>
* } <br>
* }; <br>
* // ... <br>
* TOpen open; <br>
* open.executeThreads(10); <br>
* </code>
*/
template <class Derived>
class FAbstractThread{
public:
/**
* This function is used to create inThreadsNumber threads with inCallback as the callback.
* @param inCallback the callback (must be a object method)
* @param inThreadsNumber the number of threads to create
*/
virtual void executeThreads(void (Derived::*inCallback)(const int,const int), const int inThreadsNumber) = 0;
/**
* This function is used to create inThreadsNumber threads with Object::threadCallback as the callback.
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* @warning You have to implement threadCallback
*/
virtual void executeThreads(const int inThreadsNumber) = 0;
/**
* This function executed by each thread after executeThreads has been called
* @param inThreadId the current thread index
* @param inThreadNumbers the number of threads started
* @warning Must be impleted in the derived class
*/
virtual void threadCallback(const int inThreadId,const int inThreadNumbers) = 0;
/** Useless Virtual Destructor */
virtual ~FAbstractThread(){}
protected:
/**
* This function lock a thread-type spefic mutex
*/
virtual void lock() const = 0;
/**
* This function unlock a thread-type spefic mutex
*/
virtual void unlock() const = 0;
/**
* Barrier to sync all thread
*/
virtual void barrier() const = 0;
};
#endif //FABSTRACTTHREAD_HPP
// [--LICENSE--]
#ifndef FNOTHREAD_HPP
#define FNOTHREAD_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <omp.h>
#include "FAbstractThread.hpp"
#include "FDebug.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FNoThread
* Please read the license
*
* This class do not use thread. It is used on system that do not allow openmp or posix threads,
* or to make some test without these libs.
*
* @warning You have to put your class name as the template when inheriting.
*
* <code>
* // Example with FNoThread <br>
* class TNo : public FNoThread<TNo>{ <br>
* public: <br>
* void threadCallback(const int inThreadId, const int){ <br>
* printf("I am %d\n",inThreadId); <br>
* } <br>
* }; <br>
* // ... <br>
* TNo notd; <br>
* notd.executeThreads(10); <br>
* </code>
*/
template <class Derived, int DefaultThreadsNumber = 1>
class FNoThread : public FAbstractThread<Derived> {
public:
/**
* This function is used to create inThreadsNumber threads with inCallback as the callback.
* @param inCallback the callback (must be a object method)
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* <code> open.executeThreads(&TOpen::threadCallback,10); </code>
*/
void executeThreads(void (Derived::*inCallback)(const int, const int), const int inThreadsNumber = DefaultThreadsNumber){
Derived* const thisDerived = dynamic_cast<Derived*>(this);
(thisDerived->*inCallback)(0, 1);
}
/**
* This function is used to create inThreadsNumber threads with Object::threadCallback as the callback.
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* @warning You have to implement threadCallback
*/
void executeThreads(const int inThreadsNumber = DefaultThreadsNumber){
threadCallback(0, 1);
}
/**
* This function executed by each thread after executeThreads has been called
* @param inThreadId the current thread index (equal 0 for no thread)
* @param inThreadNumbers the number of threads started (equal 1 for no thread)
* @warning Must be impleted in the derived class
*/
virtual void threadCallback(const int inThreadId, const int inThreadNumbers){
FDEBUG( FDebug::Controller.writeFromLine("[W] You called executeThreads() but did not implement threadCallback", __LINE__, __FILE__); )
};
/** Useless Virtual Destructor */
virtual ~FNoThread(){}
protected:
/**
* This function lock a thread-type spefic mutex - here it does nothing
*/
void lock() const {}
/**
* This function unlock a thread-type spefic mutex - here it does nothing
*/
void unlock() const {}
/**
* Barrier to sync all thread - here it does nothing
*/
void barrier() const {}
};
#endif //FNoThread_HPP
// [--LICENSE--]
#ifndef FOPENMPTHREAD_HPP
#define FOPENMPTHREAD_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <omp.h>
#include "FAbstractThread.hpp"
#include "FDebug.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FOpenMPThread
* Please read the license
*
* This class enable openmp threading.
*
* @warning You have to put your class name as the template when inheriting.
*
* <code>
* // Example with FOpenMPThread <br>
* class TOpen : public FOpenMPThread<TOpen>{ <br>
* public: <br>
* void threadCallback(const int inThreadId, const int){ <br>
* printf("I am %d\n",inThreadId); <br>
* } <br>
* }; <br>
* // ... <br>
* TOpen open; <br>
* open.executeThreads(10); <br>
* </code>
*/
template <class Derived, int DefaultThreadsNumber = 5>
class FOpenMPThread : public FAbstractThread<Derived> {
private:
mutable omp_lock_t mutex; //< openmp mutex
public:
/**
* Constructor
* just init mutex
*/
FOpenMPThread(){
omp_init_lock(&this->mutex);
}
/**
* Copy constructor
* just init mutex
*/
FOpenMPThread(const FOpenMPThread&){
omp_init_lock(&this->mutex);
}
/**
* Destructor
* just destroy mutex
*/
virtual ~FOpenMPThread(){
omp_destroy_lock(&this->mutex);
}
/**
* This function is used to create inThreadsNumber threads with inCallback as the callback.
* @param inCallback the callback (must be a object method)
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* <code> open.executeThreads(&TOpen::threadCallback,10); </code>
*/
void executeThreads(void (Derived::*inCallback)(const int, const int), const int inThreadsNumber = DefaultThreadsNumber){
Derived* const thisDerived = dynamic_cast<Derived*>(this);
#pragma omp parallel num_threads(inThreadsNumber)
{
(thisDerived->*inCallback)(omp_get_thread_num(), omp_get_num_threads());
}
}
/**
* This function is used to create inThreadsNumber threads with Object::threadCallback as the callback.
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* @warning You have to implement threadCallback
*/
void executeThreads(const int inThreadsNumber = DefaultThreadsNumber){
#pragma omp parallel num_threads(inThreadsNumber)
{
threadCallback(omp_get_thread_num(), omp_get_num_threads());
}
}
/**
* This function executed by each thread after executeThreads has been called
* @param inThreadId the current thread index
* @param inThreadNumbers the number of threads started
* @warning Must be impleted in the derived class
*/
virtual void threadCallback(const int inThreadId, const int inThreadNumbers){
FDEBUG( FDebug::Controller.writeFromLine("[W] You called executeThreads() but did not implement threadCallback", __LINE__, __FILE__); )
}
protected:
/**
* This function lock an openmp mutex
*/
void lock() const {
omp_set_lock(&this->mutex);
}
/**
* This function unlock an openmp mutex
*/
void unlock() const {
omp_unset_lock(&this->mutex);
}
/**
* Barrier to sync all thread
*/
void barrier() const {
#pragma omp barrier
}
};
#endif //FOPENMPTHREAD_HPP
// [--LICENSE--]
#ifndef FPOSIXTHREAD_HPP
#define FPOSIXTHREAD_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <pthread.h>
#include "FAbstractThread.hpp"
#include "FDebug.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FPosixThread
* Please read the license
*
* This class enable posix threading.
*
* @warning You have to put your class name as the template when inheriting.
*
* <code>
* // Example with FPosixThread <br>
* class TPosix : public FPosixThread<TOpen>{ <br>
* public: <br>
* void threadCallback(const int inThreadId, const int){ <br>
* printf("I am %d\n",inThreadId); <br>
* } <br>
* }; <br>
* // ... <br>
* TPosix posix; <br>
* posix.executeThreads(10); <br>
* </code>
*/
template <class Derived, int DefaultThreadsNumber = 5>
class FPosixThread : public FAbstractThread<Derived> {
private:
mutable pthread_mutex_t mutex; //< Posix mutex
mutable pthread_barrier_t pbarrier; //< To use a barrier
public:
/**
* Constructor
* just init mutex
*/
FPosixThread(){
initMutex();
}
/**
* Copy constructor
* just init mutex
*/
FPosixThread(const FPosixThread&){
initMutex();
}
/**
* Destructor
* just destroy mutex
*/
virtual ~FPosixThread(){
pthread_mutex_unlock(&this->mutex);
pthread_mutex_destroy(&this->mutex);
}
/**
* This function is used to create inThreadsNumber threads with inCallback as the callback.
* @param inCallback the callback (must be a object method)
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* <code> posix.executeThreads(&TPosix::threadCallback,10); </code>
*/
void executeThreads(void (Derived::*inCallback)(const int, const int), const int inThreadsNumber = DefaultThreadsNumber){
// init barrier
pthread_barrier_init( &this->pbarrier, 0, inThreadsNumber);
// Get current object address as a Derived class
Derived* const thisDerived = dynamic_cast<Derived*>(this);
// One descriptor per thread
PosixDescriptor descriptors[inThreadsNumber];
// Create thread
for(long indexThread = 1 ; indexThread < inThreadsNumber ; ++indexThread){
descriptors[indexThread].target = thisDerived;
descriptors[indexThread].callback = inCallback;
descriptors[indexThread].threadId = indexThread;
descriptors[indexThread].numThreads = inThreadsNumber;
pthread_create(&descriptors[indexThread].thread, 0, PthreadCallback, (void*)&descriptors[indexThread]);
}
// Master thread
(thisDerived->*inCallback)(0 , inThreadsNumber);
// Wait each thread to finish
for(long indexThread = 1 ; indexThread < inThreadsNumber ; ++indexThread){
pthread_join(descriptors[indexThread].thread, 0);
}
// destroy barrier
pthread_barrier_destroy( &this->pbarrier );
}
/**
* This function is used to create inThreadsNumber threads with Object::threadCallback as the callback.
* @param inThreadsNumber the number of threads to create (default is DefaultThreadsNumber)
* @warning You have to implement threadCallback
*/
void executeThreads(const int inThreadsNumber = DefaultThreadsNumber){
executeThreads( &FPosixThread::threadCallback , inThreadsNumber);
}
/**
* This function executed by each thread after executeThreads has been called
* @param inThreadId the current thread index
* @param inThreadNumbers the number of threads started
* @warning Must be impleted in the derived class
*/
virtual void threadCallback(const int inThreadId, const int inThreadNumbers){
FDEBUG( FDebug::Controller.writeFromLine("[W] You called executeThreads() but did not implement threadCallback", __LINE__, __FILE__); )
};
protected:
/**
* Init mutext
* Equal this->mutex = PTHREAD_MUTEX_INITIALIZER;
*/
void initMutex(){
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&this->mutex,&attr);
pthread_mutexattr_destroy(&attr);
}
/**
* This function lock a posix mutex
*/
void lock() const {
pthread_mutex_lock( &this->mutex );
}
/**
* This function unlock a posix mutex
*/
void unlock() const {
pthread_mutex_unlock( &this->mutex );
}
/**
* Barrier to sync all thread
*/
void barrier() const {
pthread_barrier_wait( &this->pbarrier );
}
private:
/**
* This struct is useless for users, it is use to describe a posix thread
*/
typedef void (Derived::*Callback)(const int, const int);
struct PosixDescriptor{
Derived * target; //< object to call
Callback callback; //< method to call
int threadId; //< current thread position
int numThreads; //< number of threads
pthread_t thread; //< posix descriptor to enable wait/join functions
};
/**
* This function is the normal posix thread callback
* @param inThreadDescriptor a PosixDescriptor of the current thread
* @return 0
*/
static void* PthreadCallback(void* const inThreadDescriptor)
{
// Simply cast the parameter and call the function
PosixDescriptor* const threadDescriptor = (PosixDescriptor*) inThreadDescriptor;
(threadDescriptor->target->*threadDescriptor->callback)(threadDescriptor->threadId,threadDescriptor->numThreads);
return 0;
}
};
#endif //FPOSIXTHREAD_HPP
// [--LICENSE--]
// /!\ Please, you must read the license at the bottom of this page
// Compile by g++ testThread.cpp ../Sources/Utils/FDebug.cpp -lgomp -lpthread -fopenmp -o testThread.exe
/**
* In this file we show how to use the thread module.
* Thread can be Posix or OpenMP.
* Here we define two classes, each one use a type.
* As you can see there is no difference in the inheriting.
*/
#include "../Sources/Utils/FAbstractThread.hpp"
#include "../Sources/Utils/FOpenMPThread.hpp"
#include "../Sources/Utils/FPosixThread.hpp"
#include "../Sources/Utils/FNoThread.hpp"
#include <stdio.h>
/**
* TOpen is an example of the FOpenMPThreaded implementation class
*/
class TOpen : public FOpenMPThread<TOpen>{
public:
void threadCallback(const int inThreadId, const int inThreadsNum){
printf("I am %d on %d, \n",inThreadId, inThreadsNum);
}
void threadCallbackMutex(const int inThreadId, const int inThreadsNum){
lock();
for(long idx = 0 ; idx < 50000000 ; ++idx) {++idx;--idx;}
printf("I am %d on %d, \n",inThreadId, inThreadsNum);
unlock();
barrier();
printf("I am %d ok\n",inThreadId);
}
};
/**
* TPosix is an example of the FPosixThreaded implementation class
*/
class TPosix : public FPosixThread<TPosix>{
public:
void threadCallback(const int inThreadId, const int inThreadsNum){
printf("I am %d on %d, \n",inThreadId, inThreadsNum);
}
void threadCallbackMutex(const int inThreadId, const int inThreadsNum){
lock();
for(long idx = 0 ; idx < 50000000 ; ++idx) {++idx;--idx;}
printf("I am %d on %d, \n",inThreadId, inThreadsNum);
unlock();
barrier();
printf("I am %d ok\n",inThreadId);
}
};
int main(void){
// create openmp thread derived class
TOpen open;
open.executeThreads(10);
open.executeThreads(&TOpen::threadCallbackMutex,5);
// create posix thread derived class
TPosix posix;
posix.executeThreads(10);
posix.executeThreads(&TPosix::threadCallbackMutex,5);
return 0;
}
// [--LICENSE--]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment