archivemuh

This commit is contained in:
2025-08-20 19:18:38 -05:00
parent 1411c2e96b
commit fbfcbe9578
173 changed files with 2802 additions and 13 deletions

19
src/thread/CMakeLists.txt Normal file
View File

@@ -0,0 +1,19 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
thread.c
threadmutex.c
)
# Compiler flags.
if(DUSK_TARGET_SYSTEM STREQUAL "linux")
target_compile_definitions(${DUSK_TARGET_NAME}
PRIVATE
DUSK_THREAD_PTHREAD=1
)
endif()

101
src/thread/thread.c Normal file
View File

@@ -0,0 +1,101 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "thread.h"
#include "util/memory.h"
#include "assert/assert.h"
void threadInit(thread_t *thread, const threadcallback_t callback) {
assertNotNull(thread, "Thread cannot be NULL.");
assertNotNull(callback, "Thread callback cannot be NULL.");
memoryZero(thread, sizeof(thread_t));
thread->state = THREAD_STATE_STOPPED;
thread->callback = callback;
#if DUSK_THREAD_PTHREAD
thread->threadId = 0;
#endif
}
void threadStartRequest(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
printf("Starting thread...\n");
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_STARTING;
threadMutexUnlock(&thread->stateMutex);
printf("Thread marked starting.\n");
#if DUSK_THREAD_PTHREAD
assertTrue(thread->threadId == 0, "Thread id not 0.");
pthread_create(
&thread->threadId,
NULL,
(void * (*)(void *))threadHandler,
thread
);
pthread_detach(thread->threadId);
#endif
printf("Thread created.\n");
}
void threadStopRequest(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
if(thread->state != THREAD_STATE_STOPPED) {
thread->state = THREAD_STATE_STOP_REQUESTED;
}
threadMutexUnlock(&thread->stateMutex);
}
void threadStart(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadStartRequest(thread);
threadMutexLock(&thread->stateMutex);
threadMutexWaitLock(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
printf("Thread is now running.\n");
}
void threadStop(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadStopRequest(thread);
threadMutexLock(&thread->stateMutex);
while(thread->state != THREAD_STATE_STOPPED) {
threadMutexWaitLock(&thread->stateMutex);
}
threadMutexUnlock(&thread->stateMutex);
}
#if DUSK_THREAD_PTHREAD
void * threadHandler(thread_t *thread) {
assertNotNull(thread, "Thread cannot be NULL.");
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_RUNNING;
threadMutexSignal(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
// Send to callback.
thread->callback(thread);
threadMutexLock(&thread->stateMutex);
thread->state = THREAD_STATE_STOPPED;
threadMutexSignal(&thread->stateMutex);
threadMutexUnlock(&thread->stateMutex);
thread->threadId = 0;
return NULL;
}
#endif

93
src/thread/thread.h Normal file
View File

@@ -0,0 +1,93 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "thread/threadmutex.h"
#if DUSK_THREAD_PTHREAD
#include <pthread.h>
#else
#error "At least one threading implementation must be defined."
#endif
typedef struct thread_s thread_t;
typedef void (*threadcallback_t)(thread_t *thread);
typedef enum {
// Thread is definitely not running.
THREAD_STATE_STOPPED,
// Start has been requested, it may even be started by the time you
// see this value.
THREAD_STATE_STARTING,
// Thread has definitely started and is running.
THREAD_STATE_RUNNING,
// Something has requested the thread to stop, but it may not have
// stopped yet.
THREAD_STATE_STOP_REQUESTED,
} threadstate_t;
typedef struct thread_s {
threadstate_t state;
threadmutex_t stateMutex;
threadcallback_t callback;
void *data;
#if DUSK_THREAD_PTHREAD
pthread_t threadId;
#endif
} thread_t;
/**
* Initializes a thread structure.
*
* @param thread Pointer to the thread structure to initialize.
* @param callback The callback function to be called when the thread runs.
*/
void threadInit(thread_t *thread, const threadcallback_t callback);
/**
* Starts the thread, does not wait for it to finish starting.
*
* @param thread Pointer to the thread structure to start.
*/
void threadStartRequest(thread_t *thread);
/**
* Requests the thread to stop, does not block the calling thread.
*
* @param thread Pointer to the thread structure to stop.
*/
void threadStopRequest(thread_t *thread);
/**
* Starts the thread, blocking until it has started. Does this as efficiently as
* possible depending on the threading implementation. Note that it is possible
* for the thread to fully COMPLETE before this function returns.
*
* @param thread Pointer to the thread structure to start.
*/
void threadStart(thread_t *thread);
/**
* Stops the thread, blocking until it has stopped. Does this as efficiently as
* possible depending on the threading implementation.
*
* @param thread Pointer to the thread structure to stop.
*/
void threadStop(thread_t *thread);
#if DUSK_THREAD_PTHREAD
/**
* Handles the thread's lifecycle for pthreads.
* @param thread Pointer to the thread structure to handle.
*/
void * threadHandler(thread_t *thread);
#endif

50
src/thread/threadmutex.c Normal file
View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "threadmutex.h"
void threadMutexInit(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_mutex_init(&lock->mutex, NULL);
#endif
}
void threadMutexLock(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_mutex_lock(&lock->mutex);
#endif
}
bool_t threadMutexTryLock(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
return pthread_mutex_trylock(&lock->mutex) == 0;
#endif
}
void threadMutexUnlock(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_mutex_unlock(&lock->mutex);
#endif
}
void threadMutexWaitLock(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_cond_wait(&lock->cond, &lock->mutex);
#endif
}
void threadMutexSignal(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_cond_signal(&lock->cond);
#endif
}
void threadMutexDispose(threadmutex_t *lock) {
#if DUSK_THREAD_PTHREAD
pthread_mutex_destroy(&lock->mutex);
#endif
}

73
src/thread/threadmutex.h Normal file
View File

@@ -0,0 +1,73 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#if DUSK_THREAD_PTHREAD
#include <pthread.h>
#else
#error "At least one threading implementation must be defined."
#endif
typedef struct threadlock_t {
#if DUSK_THREAD_PTHREAD
pthread_mutex_t mutex;
pthread_cond_t cond;
#endif
} threadmutex_t;
/**
* Initializes a thread mutex.
*
* @param lock Pointer to the thread mutex structure to initialize.
*/
void threadMutexInit(threadmutex_t *lock);
/**
* Locks the thread mutex.
*
* @param lock Pointer to the thread mutex structure to lock.
*/
void threadMutexLock(threadmutex_t *lock);
/**
* Attempts to lock the thread mutex without blocking.
*
* @param lock Pointer to the thread mutex structure to try locking.
* @return true if the lock was acquired, false otherwise.
*/
bool_t threadMutexTryLock(threadmutex_t *lock);
/**
* Unlocks the thread mutex.
*
* @param lock Pointer to the thread mutex structure to unlock.
*/
void threadMutexUnlock(threadmutex_t *lock);
/**
* Releases the thread mutex and waits for it to be locked again.
*
* @param lock Pointer to the thread mutex structure to wait on.
*/
void threadMutexWaitLock(threadmutex_t *lock);
/**
* Signals the thread mutex, allowing a waiting thread to proceed as soon as
* this mutex is unlocked.
*
* @param lock Pointer to the thread mutex structure to signal.
*/
void threadMutexSignal(threadmutex_t *lock);
/**
* Disposes of the thread mutex.
*
* @param lock Pointer to the thread mutex structure to dispose.
*/
void threadMutexDispose(threadmutex_t *lock);