4 * This file is part of OpenTTD.
5 * OpenTTD 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, version 2.
6 * OpenTTD 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.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file thread.h Base of all threads. */
15 /** Definition of all thread entry functions. */
16 typedef void (*OTTDThreadFunc
)(void *);
18 /** Signal used for signalling we knowingly want to end the thread. */
19 class OTTDThreadExitSignal
{ };
22 * A Thread Object which works on all our supported OSes.
27 * Virtual destructor to allow 'delete' operator to work properly.
29 virtual ~ThreadObject() {};
34 virtual bool Exit() = 0;
39 virtual void Join() = 0;
42 * Create a thread; proc will be called as first function inside the thread,
43 * with optional params.
44 * @param proc The procedure to call inside the thread.
45 * @param param The params to give with 'proc'.
46 * @param thread Place to store a pointer to the thread in. May be NULL.
47 * @param name A name for the thread. May be NULL.
48 * @return True if the thread was started correctly.
50 static bool New(OTTDThreadFunc proc
, void *param
, ThreadObject
**thread
= NULL
, const char *name
= NULL
);
54 * Cross-platform Mutex
61 static ThreadMutex
*New();
64 * Virtual Destructor to avoid compiler warnings.
66 virtual ~ThreadMutex() {};
69 * Begin the critical section
70 * @param allow_recursive Whether recursive locking is intentional.
71 * If false, NOT_REACHED() will be called when the mutex is already locked
72 * by the current thread.
74 virtual void BeginCritical(bool allow_recursive
= false) = 0;
77 * End of the critical section
78 * @param allow_recursive Whether recursive unlocking is intentional.
79 * If false, NOT_REACHED() will be called when the mutex was locked more
80 * than once by the current thread.
82 virtual void EndCritical(bool allow_recursive
= false) = 0;
85 * Wait for a signal to be send.
86 * @pre You must be in the critical section.
87 * @note While waiting the critical section is left.
88 * @post You will be in the critical section.
90 virtual void WaitForSignal() = 0;
93 * Send a signal and wake the 'thread' that was waiting for it.
95 virtual void SendSignal() = 0;
99 * Simple mutex locker to keep a mutex locked until the locker goes out of scope.
101 class ThreadMutexLocker
{
104 * Lock the mutex and keep it locked for the life time of this object.
105 * @param mutex Mutex to be locked.
107 ThreadMutexLocker(ThreadMutex
*mutex
) : mutex(mutex
) { mutex
->BeginCritical(); }
112 ~ThreadMutexLocker() { this->mutex
->EndCritical(); }
115 ThreadMutexLocker(const ThreadMutexLocker
&) { NOT_REACHED(); }
116 ThreadMutexLocker
&operator=(const ThreadMutexLocker
&) { NOT_REACHED(); return *this; }
121 * Get number of processor cores in the system, including HyperThreading or similar.
122 * @return Total number of processor cores.
124 uint
GetCPUCoreCount();
126 #endif /* THREAD_H */