3
/****************************************************************************
4
Copyright (C) 2012-2014, rncbc aka Rui Nuno Capela. All rights reserved.
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License along
17
with this program; if not, write to the Free Software Foundation, Inc.,
18
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
*****************************************************************************/
22
#include "drumkv1_sched.h"
26
#include <QWaitCondition>
31
//-------------------------------------------------------------------------
32
// drumkv1_sched_thread - worker/schedule thread decl.
35
class drumkv1_sched_thread : public QThread
40
drumkv1_sched_thread(uint32_t nsize = 8);
43
~drumkv1_sched_thread();
45
// schedule processing and wake from wait condition.
46
void schedule(drumkv1_sched *sched);
50
// main thread executive.
55
// sync queue instance reference.
59
drumkv1_sched **m_items;
61
volatile uint32_t m_iread;
62
volatile uint32_t m_iwrite;
64
// whether the thread is logically running.
65
volatile bool m_running;
67
// thread synchronization objects.
69
QWaitCondition m_cond;
73
static drumkv1_sched_thread *g_sched_thread = NULL;
74
static uint32_t g_sched_refcount = 0;
77
//-------------------------------------------------------------------------
78
// drumkv1_sched_thread - worker/schedule thread impl.
82
drumkv1_sched_thread::drumkv1_sched_thread ( uint32_t nsize ) : QThread()
85
while (m_nsize < nsize)
87
m_nmask = (m_nsize - 1);
88
m_items = new drumkv1_sched * [m_nsize];
93
::memset(m_items, 0, m_nsize * sizeof(drumkv1_sched *));
100
drumkv1_sched_thread::~drumkv1_sched_thread (void)
102
// fake sync and wait
103
if (m_running && isRunning()) do {
104
if (m_mutex.tryLock()) {
109
} while (!wait(100));
115
// schedule processing and wake from wait condition.
116
void drumkv1_sched_thread::schedule ( drumkv1_sched *sched )
118
if (!sched->sync_wait()) {
119
const uint32_t w = (m_iwrite + 1) & m_nmask;
121
m_items[m_iwrite] = sched;
126
if (m_mutex.tryLock()) {
133
// main thread executive.
134
void drumkv1_sched_thread::run (void)
141
// do whatever we must...
142
uint32_t r = m_iread;
143
while (r != m_iwrite) {
144
drumkv1_sched *sched = m_items[r];
146
sched->sync_process();
153
m_cond.wait(&m_mutex);
160
//-------------------------------------------------------------------------
161
// drumkv1_sched - worker/scheduled stuff (pure virtual).
165
drumkv1_sched::drumkv1_sched (void) : m_sync_wait(false)
167
if (++g_sched_refcount == 1 && g_sched_thread == NULL) {
168
g_sched_thread = new drumkv1_sched_thread();
169
g_sched_thread->start();
175
drumkv1_sched::~drumkv1_sched (void)
177
if (--g_sched_refcount == 0 && g_sched_thread) {
178
delete g_sched_thread;
179
g_sched_thread = NULL;
185
void drumkv1_sched::schedule (void)
188
g_sched_thread->schedule(this);
193
bool drumkv1_sched::sync_wait (void)
195
const bool sync_wait = m_sync_wait;
204
// scheduled processor.
205
void drumkv1_sched::sync_process (void)
213
// end of drumkv1_sched.cpp