/*
* surf - visualizing algebraic curves and algebraic surfaces
* Copyright (C) 1996-1997 Friedrich-Alexander-Universitaet
* Erlangen-Nuernberg
* 1997-2000 Johannes Gutenberg-Universitaet Mainz
* Authors: Stephan Endrass, Hans Huelf, Ruediger Oertel,
* Kai Schneider, Ralf Schmitt, Johannes Beigel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <iostream.h>
#include <pthread.h>
#include "Thread.h"
// #define DEBUG
#include "debug.h"
static bool is_multithreaded=false;
static pthread_key_t threadPointer;
struct MyArgument {
void * (*startFunc) (void *);
void *arg;
Thread *thread;
};
void * Thread::myStartFunc (void *data)
{
MyArgument *arg = (MyArgument *) data;
pthread_setspecific (threadPointer, arg->thread);
arg->thread->mutex.lock();
arg->thread->mutex.unlock();
void *result = arg->startFunc(arg->arg);
arg->thread->mutex.lock();
arg->thread->is_ready = true;
arg->thread->mutex.unlock();
delete arg;
return result;
}
bool Thread::isReady ()
{
return is_ready;
}
void Thread::stop()
{
should_stop=true;
}
int Thread::start (void * (*startFunc) (void *), void *argument)
{
if (!is_multithreaded) {
pthread_key_create (&threadPointer, 0);
pthread_setspecific (threadPointer,0);
is_multithreaded=true;
}
mutex.lock();
bool can_start = is_ready;
if (is_ready) {
is_ready=false;
should_stop=false;
}
mutex.unlock();
if (!can_start)
return false;
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setstacksize (&attr, 0x1000000);
pthread_t pt;
MyArgument *arg = new MyArgument();
arg->arg = argument;
arg->startFunc = startFunc;
arg->thread = this;
int err = pthread_create (&pt, &attr, myStartFunc, arg);
pthread_attr_destroy(&attr);
return err;
}
Thread::Thread()
{
done = -1.0;
doing = 0;
is_ready = true;
}
Thread * Thread::getThread()
{
return is_multithreaded ? (Thread *)pthread_getspecific(threadPointer) : 0;
}
void Thread::setDoing (const char *str, double val)
{
if (!is_multithreaded) {
cout << str << endl;
return;
}
Thread *thread = getThread();
if (!thread)
return;
thread->mutex.lock();
thread->doing = str;
thread->done = val;
thread->mutex.unlock();
}
void Thread::setDone (double val)
{
Thread *thread = getThread();
if (!thread)
return;
thread->mutex.lock();
thread->done = val;
thread->mutex.unlock();
}
void Thread::getProgress(const char *&_doing, double &_done)
{
mutex.lock();
_doing = doing;
_done = done;
mutex.unlock();
}
syntax highlighted by Code2HTML, v. 0.9.1