From 6f93b3d7c80f9dee2d95fac1bbc4f781a6f45979 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 18 Sep 2006 06:24:53 +0000 Subject: Work on loading old (deprecated) patches. More error tolerance in Store, related bugfixes. Patch port adding (threading) bug fixed (made event blocking). Better PatchView cacheing. Moved generic things from engine to util (shared) Bug fixes, features, etc. git-svn-id: http://svn.drobilla.net/lad/ingen@142 a436a847-0d15-0410-975c-d299462d15a1 --- src/common/util/Condition.h | 42 +++++++++++++++++++ src/common/util/Makefile.am | 4 ++ src/common/util/Mutex.h | 41 ++++++++++++++++++ src/common/util/Semaphore.h | 2 +- src/common/util/Slave.h | 57 +++++++++++++++++++++++++ src/common/util/Thread.h | 100 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 src/common/util/Condition.h create mode 100644 src/common/util/Mutex.h create mode 100644 src/common/util/Slave.h create mode 100644 src/common/util/Thread.h (limited to 'src/common/util') diff --git a/src/common/util/Condition.h b/src/common/util/Condition.h new file mode 100644 index 00000000..1ee28dbd --- /dev/null +++ b/src/common/util/Condition.h @@ -0,0 +1,42 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONDITION_H +#define CONDITION_H + +#include + + +/** Trivial (but pretty) wrapper around POSIX Conditions (zero memory overhead). + * + * A semaphore that isn't a counter and is slow and NOT realtime safe. + */ +class Condition { +public: + inline Condition() { pthread_cond_init(&_cond, NULL); } + + inline ~Condition() { pthread_cond_destroy(&_cond); } + + inline void signal() { pthread_cond_signal(&_cond); } + inline void wait(Mutex& mutex) { pthread_cond_wait(&_cond, &mutex._mutex); } + +private: + pthread_cond_t _cond; +}; + + +#endif // CONDITION_H + diff --git a/src/common/util/Makefile.am b/src/common/util/Makefile.am index 46bc3691..845a5d9a 100644 --- a/src/common/util/Makefile.am +++ b/src/common/util/Makefile.am @@ -3,5 +3,9 @@ EXTRA_DIST = \ Path.h \ Queue.h \ Semaphore.h \ + Mutex.h \ + Condition.h \ + Thread.h \ + Slave.h \ Atom.h \ LibloAtom.h diff --git a/src/common/util/Mutex.h b/src/common/util/Mutex.h new file mode 100644 index 00000000..c5aaf3ae --- /dev/null +++ b/src/common/util/Mutex.h @@ -0,0 +1,41 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MUTEX_H +#define MUTEX_H + +#include + + +/** Trivial (but pretty) wrapper around POSIX Mutexes (zero memory overhead). + */ +class Mutex { +public: + inline Mutex() { pthread_mutex_init(&_mutex, NULL); } + + inline ~Mutex() { pthread_mutex_destroy(&_mutex); } + + inline bool try_lock() { return (pthread_mutex_trylock(&_mutex) == 0); } + inline void lock() { pthread_mutex_lock(&_mutex); } + inline void unlock() { pthread_mutex_unlock(&_mutex); } + +private: + friend class Condition; + pthread_mutex_t _mutex; +}; + + +#endif // MUTEX_H diff --git a/src/common/util/Semaphore.h b/src/common/util/Semaphore.h index a98124bf..168a7059 100644 --- a/src/common/util/Semaphore.h +++ b/src/common/util/Semaphore.h @@ -20,7 +20,7 @@ #include -/** Trivial wrapper around POSIX semaphores. +/** Trivial wrapper around POSIX semaphores (zero memory overhead). * * This was created to provide an alternative debuggable implementation of * semaphores based on a cond/mutex pair because semaphore's appeared not to diff --git a/src/common/util/Slave.h b/src/common/util/Slave.h new file mode 100644 index 00000000..0d0976b8 --- /dev/null +++ b/src/common/util/Slave.h @@ -0,0 +1,57 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SLAVE_H +#define SLAVE_H + +#include +#include "util/Semaphore.h" +#include "util/Thread.h" + + +/** Thread driven by (realtime safe) signals. + * + * \ingroup engine + */ +class Slave : public Thread +{ +public: + Slave() : _whip(0) {} + + /** Tell the slave to do whatever work it does. Realtime safe. */ + inline void whip() { _whip.post(); } + +protected: + virtual void _whipped() = 0; + + Semaphore _whip; + +private: + // Prevent copies (undefined) + Slave(const Slave&); + Slave& operator=(const Slave&); + + inline void _run() + { + while (true) { + _whip.wait(); + _whipped(); + } + } +}; + + +#endif // SLAVE_H diff --git a/src/common/util/Thread.h b/src/common/util/Thread.h new file mode 100644 index 00000000..c139434b --- /dev/null +++ b/src/common/util/Thread.h @@ -0,0 +1,100 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * Ingen 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. + * + * Ingen 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 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., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef THREAD_H +#define THREAD_H + +#include +#include +#include + + +/** Abstract base class for a thread. + * + * Extend this and override the _run method to easily create a thread + * to perform some task. + * + * \ingroup engine + */ +class Thread +{ +public: + Thread() : _pthread_exists(false) {} + + virtual ~Thread() { stop(); } + + void set_name(const std::string& name) { _name = name; } + + virtual void start() { + std::cout << "[" << _name << " Thread] Starting." << std::endl; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 1500000); + + pthread_create(&_pthread, &attr, _static_run, this); + _pthread_exists = true; + } + + virtual void stop() { + if (_pthread_exists) { + pthread_cancel(_pthread); + pthread_join(_pthread, NULL); + _pthread_exists = false; + } + } + + void set_scheduling(int policy, unsigned int priority) { + sched_param sp; + sp.sched_priority = priority; + int result = pthread_setschedparam(_pthread, SCHED_FIFO, &sp); + if (!result) { + std::cout << "[" << _name << "] Set scheduling policy to "; + switch (policy) { + case SCHED_FIFO: std::cout << "SCHED_FIFO"; break; + case SCHED_RR: std::cout << "SCHED_RR"; break; + case SCHED_OTHER: std::cout << "SCHED_OTHER"; break; + default: std::cout << "UNKNOWN"; break; + } + std::cout << ", priority " << sp.sched_priority << std::endl; + } else { + std::cout << "[" << _name << "] Unable to set scheduling policy (" + << strerror(result) << ")" << std::endl; + } + } + + +protected: + virtual void _run() = 0; + +private: + // Prevent copies (undefined) + Thread(const Thread&); + Thread& operator=(const Thread&); + + inline static void* _static_run(void* me) { + Thread* myself = (Thread*)me; + myself->_run(); + return NULL; // and I + } + + std::string _name; + bool _pthread_exists; + pthread_t _pthread; +}; + + +#endif // THREAD_H -- cgit v1.2.1