Skip to content

Commit 3a41835

Browse files
committed
feat: add Thread implementation
1 parent 369e9ef commit 3a41835

File tree

9 files changed

+1046
-1
lines changed

9 files changed

+1046
-1
lines changed

engine/foundation/core/core_files.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ set(FILES
131131

132132
# private/threading
133133
private/threading/runnable.cpp
134+
private/threading/thread.cpp
135+
private/threading/thread_impl.cpp
134136

135137
# private/time
136138
private/time/stopwatch.cpp

engine/foundation/core/core_linux_files.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(FILES
3434
private/linux/linux_mouse_device.cpp
3535
private/linux/linux_mutex.cpp
3636
private/linux/linux_platform.cpp
37+
private/linux/linux_thread.cpp
3738
private/linux/linux_window.cpp
3839
private/linux/linux_window_device.cpp
3940
private/linux/xcb_backend.cpp
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
////////////////////////////////////////////////////////////////////////////////////////////////////
2+
// Copyright (c) 2025 RacoonStudios
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
5+
// software and associated documentation files (the "Software"), to deal in the Software
6+
// without restriction, including without limitation the rights to use, copy, modify, merge,
7+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
8+
// to whom the Software is furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all copies or
11+
// substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
15+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
16+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18+
// DEALINGS IN THE SOFTWARE.
19+
////////////////////////////////////////////////////////////////////////////////////////////////////
20+
21+
22+
//[-------------------------------------------------------]
23+
//[ Includes ]
24+
//[-------------------------------------------------------]
25+
#include "core/linux/linux_thread.h"
26+
#include "core/log/log.h"
27+
#include "core/memory/memory.h"
28+
#include "core/platform/mutex.h"
29+
#include "core/threading/thread.h"
30+
#include "core/threading/types.h"
31+
32+
33+
//[-------------------------------------------------------]
34+
//[ Namespace ]
35+
//[-------------------------------------------------------]
36+
namespace core {
37+
38+
39+
//[-------------------------------------------------------]
40+
//[ Forward declarations ]
41+
//[-------------------------------------------------------]
42+
43+
44+
//[-------------------------------------------------------]
45+
//[ Classes ]
46+
//[-------------------------------------------------------]
47+
LinuxThread::LinuxThread(Thread &thread, bool useThreadId, handle id)
48+
: ThreadImpl(thread)
49+
, mThreadId(0)
50+
, mMutex(nullptr)
51+
, mPriorityClass(ThreadPriorityClass::TPC_Normal)
52+
, mPriority(ThreadPriority::TP_Normal) {
53+
if (useThreadId && id == NULL_HANDLE) {
54+
mThreadId = pthread_self();
55+
} else {
56+
mMutex = re_new<Mutex>();
57+
}
58+
}
59+
60+
LinuxThread::~LinuxThread() {
61+
if (mMutex) {
62+
re_delete(mMutex);
63+
}
64+
}
65+
66+
handle LinuxThread::get_id() const {
67+
return (handle)mThreadId;
68+
}
69+
70+
bool LinuxThread::is_active() const {
71+
return (mThreadId > 0);
72+
}
73+
74+
bool LinuxThread::start() {
75+
if (!mThreadId) {
76+
const int status = pthread_create(&mThreadId, nullptr, &run_thread, static_cast<void*>(&get_thread()));
77+
78+
if (!status) {
79+
return true;
80+
}
81+
}
82+
return false;
83+
}
84+
85+
bool LinuxThread::kill() {
86+
if (mThreadId) {
87+
pthread_cancel(mThreadId);
88+
89+
mThreadId = 0;
90+
91+
if (mMutex) {
92+
mMutex->unlock();
93+
}
94+
95+
return true;
96+
}
97+
return false;
98+
}
99+
100+
bool LinuxThread::join() {
101+
if (mThreadId) {
102+
if (!pthread_join(mThreadId, nullptr)) {
103+
mThreadId = 0;
104+
105+
return true;
106+
}
107+
}
108+
return false;
109+
}
110+
111+
bool LinuxThread::join(uint64 timeout) {
112+
return join();
113+
}
114+
115+
uint32 LinuxThread::get_priority_class() const {
116+
return mPriorityClass;
117+
}
118+
119+
bool LinuxThread::set_priority_class(uint32 priorityClass) {
120+
mPriorityClass = priorityClass;
121+
return true;
122+
}
123+
124+
uint32 LinuxThread::get_priority() const {
125+
return mPriority;
126+
}
127+
128+
bool LinuxThread::set_priority(uint32 priority) {
129+
mPriority = priority;
130+
131+
return true;
132+
}
133+
134+
void *LinuxThread::run_thread(void *parameter) {
135+
if (parameter) {
136+
Thread* thread = static_cast<Thread*>(parameter);
137+
138+
// Lock the thread
139+
Mutex* mutex = static_cast<LinuxThread*>(thread->mImpl)->mMutex;
140+
mutex->lock();
141+
142+
// run thread
143+
int returnValue = thread->run();
144+
145+
mutex->unlock();
146+
147+
return reinterpret_cast<void*>(&returnValue);
148+
}
149+
return nullptr;
150+
}
151+
152+
153+
//[-------------------------------------------------------]
154+
//[ Namespace ]
155+
//[-------------------------------------------------------]
156+
} // core
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
////////////////////////////////////////////////////////////////////////////////////////////////////
2+
// Copyright (c) 2025 RacoonStudios
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
5+
// software and associated documentation files (the "Software"), to deal in the Software
6+
// without restriction, including without limitation the rights to use, copy, modify, merge,
7+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
8+
// to whom the Software is furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all copies or
11+
// substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
15+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
16+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18+
// DEALINGS IN THE SOFTWARE.
19+
////////////////////////////////////////////////////////////////////////////////////////////////////
20+
21+
22+
//[-------------------------------------------------------]
23+
//[ Includes ]
24+
//[-------------------------------------------------------]
25+
#include "core/threading/thread.h"
26+
#include "core/threading/runnable.h"
27+
#if defined(LINUX)
28+
#include "core/linux/linux_thread.h"
29+
#endif
30+
31+
32+
//[-------------------------------------------------------]
33+
//[ Namespace ]
34+
//[-------------------------------------------------------]
35+
namespace core {
36+
37+
38+
//[-------------------------------------------------------]
39+
//[ Forward declarations ]
40+
//[-------------------------------------------------------]
41+
42+
43+
//[-------------------------------------------------------]
44+
//[ Classes ]
45+
//[-------------------------------------------------------]
46+
Thread::Thread()
47+
: mImpl(nullptr)
48+
, mRunnable(nullptr) {
49+
50+
}
51+
52+
Thread::Thread(Runnable *runnable, const String &name)
53+
: mRunnable(runnable)
54+
, mStaticFunction(nullptr)
55+
, mStaticData(nullptr)
56+
, mName(name) {
57+
#if defined(LINUX)
58+
mImpl = re_new<LinuxThread>(*this, false, NULL_HANDLE);
59+
#endif
60+
}
61+
62+
Thread::Thread(THREADFUNCTION threadFunction, void* data)
63+
: mRunnable(nullptr)
64+
, mStaticFunction(threadFunction)
65+
, mStaticData(data)
66+
, mName() {
67+
#if defined(LINUX)
68+
mImpl = re_new<LinuxThread>(*this, false, NULL_HANDLE);
69+
#endif
70+
}
71+
72+
Thread::Thread(handle threadId)
73+
: mImpl(nullptr)
74+
, mRunnable(nullptr) {
75+
#if defined(LINUX)
76+
mImpl = re_new<LinuxThread>(*this, true, threadId);
77+
#endif
78+
}
79+
80+
Thread::~Thread() {
81+
re_delete(mImpl);
82+
}
83+
84+
const String &Thread::get_name() const {
85+
return mName;
86+
}
87+
88+
void Thread::set_name(const String &name) {
89+
mName = name;
90+
}
91+
92+
handle Thread::get_id() const {
93+
return mImpl->get_id();
94+
}
95+
96+
bool Thread::is_active() const {
97+
return mImpl->is_active();
98+
}
99+
100+
int32 Thread::run() {
101+
if (mRunnable) {
102+
return mRunnable->run();
103+
} else if (mStaticFunction) {
104+
// Call the static function
105+
return mStaticFunction(mStaticData);
106+
}
107+
return 0;
108+
}
109+
110+
bool Thread::start() {
111+
return mImpl->start();
112+
}
113+
114+
void Thread::kill() {
115+
mImpl->kill();
116+
}
117+
118+
bool Thread::join() {
119+
return mImpl->join();
120+
}
121+
122+
bool Thread::join(uint64 timeout) {
123+
return mImpl->join(timeout);
124+
}
125+
126+
ThreadPriorityClass Thread::get_priority_class() const {
127+
return static_cast<ThreadPriorityClass>(mImpl->get_priority_class());
128+
}
129+
130+
bool Thread::set_priority_class(ThreadPriorityClass priorityClass) {
131+
return mImpl->set_priority_class(priorityClass);
132+
}
133+
134+
ThreadPriority Thread::get_priority() const {
135+
return static_cast<ThreadPriority>(mImpl->get_priority());
136+
}
137+
138+
bool Thread::set_priority(ThreadPriority priority) {
139+
return mImpl->set_priority(priority);
140+
}
141+
142+
143+
//[-------------------------------------------------------]
144+
//[ Namespace ]
145+
//[-------------------------------------------------------]
146+
} // core
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
////////////////////////////////////////////////////////////////////////////////////////////////////
2+
// Copyright (c) 2025 RacoonStudios
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
5+
// software and associated documentation files (the "Software"), to deal in the Software
6+
// without restriction, including without limitation the rights to use, copy, modify, merge,
7+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
8+
// to whom the Software is furnished to do so, subject to the following conditions:
9+
//
10+
// The above copyright notice and this permission notice shall be included in all copies or
11+
// substantial portions of the Software.
12+
//
13+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
15+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
16+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18+
// DEALINGS IN THE SOFTWARE.
19+
////////////////////////////////////////////////////////////////////////////////////////////////////
20+
21+
22+
//[-------------------------------------------------------]
23+
//[ Includes ]
24+
//[-------------------------------------------------------]
25+
#include "core/threading/thread_impl.h"
26+
27+
28+
//[-------------------------------------------------------]
29+
//[ Namespace ]
30+
//[-------------------------------------------------------]
31+
namespace core {
32+
33+
34+
//[-------------------------------------------------------]
35+
//[ Public methods ]
36+
//[-------------------------------------------------------]
37+
ThreadImpl::ThreadImpl(Thread &thread)
38+
: mThread(&thread) {
39+
40+
}
41+
42+
ThreadImpl::~ThreadImpl() {
43+
44+
}
45+
46+
47+
Thread& ThreadImpl::get_thread() const {
48+
return *mThread;
49+
}
50+
51+
52+
//[-------------------------------------------------------]
53+
//[ Namespace ]
54+
//[-------------------------------------------------------]
55+
} // core

0 commit comments

Comments
 (0)