Compare commits

...

2 commits

Author SHA1 Message Date
ee8ff11712 feat: test for mutex (make this better) 2026-05-28 18:04:25 +02:00
aa57bab764 feat: alternate syntax for threads 2026-05-28 18:04:14 +02:00
6 changed files with 96 additions and 7 deletions

View file

@ -17,7 +17,8 @@
"inherits": "default",
"cacheVariables": {
"FISHBONE_BUILD_TESTS": "ON",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_BUILD_TYPE": "Debug"
}
}
],

View file

@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include <fstream>
#include <functional>
#include <cstdio>
#include <cstring>

View file

@ -14,7 +14,11 @@ namespace fishbone {
Impl* impl;
public:
Thread(void (*call)(fishbone::Thread* thread, void* arg), void* arg);
using Callable = void(*)(fishbone::Thread* thread, void* arg);
using CallableFunc = std::function<void(fishbone::Thread* thread)>;
Thread(Callable call, void* arg);
Thread(CallableFunc call);
~Thread();
void join();

View file

@ -3,9 +3,14 @@
#include <fishbone/foundation.h>
struct call_arg {
void (*call)(fishbone::Thread* thread, void* arg);
fishbone::Thread* thread;
void* arg;
fishbone::Thread::Callable call;
fishbone::Thread* thread;
void* arg;
};
struct call_arg2 {
fishbone::Thread::CallableFunc call;
fishbone::Thread* thread;
};
static int SDLCALL thread_call(void* data) {
@ -18,11 +23,21 @@ static int SDLCALL thread_call(void* data) {
return 0;
}
static int SDLCALL thread_call2(void* data) {
struct call_arg2* arg = (struct call_arg2*)data;
arg->call(arg->thread);
delete arg;
return 0;
}
struct fishbone::Thread::Impl {
SDL_Thread* thread;
};
fishbone::Thread::Thread(void (*call)(fishbone::Thread* thread, void* arg), void* arg) {
fishbone::Thread::Thread(Callable call, void* arg) {
struct call_arg* data = new struct call_arg();
data->call = call;
@ -33,6 +48,16 @@ fishbone::Thread::Thread(void (*call)(fishbone::Thread* thread, void* arg), void
this->impl->thread = SDL_CreateThread(thread_call, "FBThread", data);
}
fishbone::Thread::Thread(CallableFunc call) {
struct call_arg2* data = new struct call_arg2();
data->call = call;
data->thread = this;
this->impl = new fishbone::Thread::Impl();
this->impl->thread = SDL_CreateThread(thread_call2, "FBThread", data);
}
fishbone::Thread::~Thread() {
this->join();
}

View file

@ -1 +0,0 @@
#include <catch2/catch_test_macros.hpp>

View file

@ -0,0 +1,59 @@
#include "fishbone/thread.h"
#include <catch2/catch_test_macros.hpp>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
struct thread_arg {
int& a;
};
TEST_CASE("Thread") {
int a = 0;
fishbone::Thread th([&a](auto) {
for (int i = 0; i < 100; i++) {
a++;
}
});
th.join();
REQUIRE(a == 100);
a = 0;
thread_arg arg { a };
fishbone::Thread th2([](auto, void* data) {
thread_arg& arg = *static_cast<thread_arg*>(data);
for (int i = 0; i < 100; i++) {
arg.a++;
}
}, &arg);
th.join();
REQUIRE(a == 100);
}
TEST_CASE("Mutex") {
for (int i = 0; i < 100; i++) {
int a = 0;
fishbone::Mutex m;
fishbone::Thread::CallableFunc func = [&a, &m](auto) {
m.lock();
for (int j = 0; j < 2; j++) {
int b = a;
usleep((60 * rand()) / RAND_MAX);
a = ++b;
}
m.unlock();
};
fishbone::Thread th1(func), th2(func);
th1.join();
th2.join();
REQUIRE(a == 4);
}
}