mirror of
https://github.com/AfonsoCMSousa/Thread-Master.git
synced 2026-06-23 12:51:13 +01:00
First Commit and release of a stable build.
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
#include "threadlib/threadlib.h"
|
||||
|
||||
int __max_threads;
|
||||
unsigned char isThreadMasterRunning = 0;
|
||||
thread *listT = NULL;
|
||||
thread_master_param_t *param = NULL;
|
||||
pthread_t thread_master;
|
||||
|
||||
static pthread_mutex_t mutex;
|
||||
|
||||
void __thread_mutex_init__(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (pthread_mutex_init(mutex, NULL) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Failed to initialize mutex.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_mutex_init(pthread_mutex_t *mutex)
|
||||
{
|
||||
__thread_mutex_init__(mutex);
|
||||
}
|
||||
|
||||
void __thread_mutex_destroy__(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (pthread_mutex_destroy(mutex) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Failed to destroy mutex.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
__thread_mutex_destroy__(mutex);
|
||||
}
|
||||
|
||||
void *__thread_master_init__(void *params)
|
||||
{
|
||||
thread_master_param_t *param = (thread_master_param_t *)params;
|
||||
|
||||
listT = (thread *)malloc(param->max_threads * sizeof(thread));
|
||||
if (listT == NULL)
|
||||
{
|
||||
fprintf(stderr, "Tread Master - Error: Failed to allocate memory for thread pool.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thread_mutex_init(&mutex);
|
||||
|
||||
__max_threads = param->max_threads;
|
||||
|
||||
for (int i = 0; i < param->max_threads; i++)
|
||||
{
|
||||
listT[i].worker_param.thread_id = i + 1;
|
||||
listT[i].worker_param.mutex = &mutex;
|
||||
listT[i].worker_param.status = IDLE;
|
||||
listT[i].worker_param.custom_params = param->custom_params;
|
||||
}
|
||||
|
||||
printf("Thread Master - Success: Ready.\n");
|
||||
|
||||
thread_master_assign_new_job(param->__thread_worker__, param->custom_params);
|
||||
|
||||
/* for (int i = 0; i < param->max_threads; i++)
|
||||
{
|
||||
// 3 - Create the threads
|
||||
if (pthread_create(&(listT[i].thread), NULL, param->__thread_worker__, &(listT[i].worker_param)) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Failed to create thread %d.\n", i + 1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
listT[i].worker_param.status = BUSY;
|
||||
}
|
||||
|
||||
for (int i = 0; i < param->max_threads; i++)
|
||||
{
|
||||
pthread_join(listT[i].thread, NULL);
|
||||
}*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void thread_master_init(int max_threads, void *(*__thread_worker__)(void *), void *custom_params)
|
||||
{
|
||||
param = (thread_master_param_t *)malloc(sizeof(thread_master_param_t));
|
||||
|
||||
param->max_threads = max_threads;
|
||||
param->__thread_worker__ = __thread_worker__;
|
||||
param->mutex = mutex;
|
||||
param->custom_params = custom_params;
|
||||
|
||||
static pthread_mutex_t mutex;
|
||||
__thread_mutex_init__(&mutex);
|
||||
|
||||
param->mutex = mutex;
|
||||
|
||||
if (pthread_create(&thread_master, NULL, __thread_master_init__, (void *)param) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Failed to create thread master.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
isThreadMasterRunning = 1;
|
||||
|
||||
pthread_detach(thread_master);
|
||||
printf("Thread Master - Created\n");
|
||||
}
|
||||
|
||||
void thread_master_assign_new_job(void *(*__thread_worker__)(void *), void *custom_params)
|
||||
{
|
||||
for (int i = 0; i < __max_threads; i++)
|
||||
{
|
||||
if (listT[i].worker_param.status == IDLE)
|
||||
{
|
||||
listT[i].worker_param.status = BUSY;
|
||||
listT[i].worker_param.custom_params = custom_params;
|
||||
pthread_create(&(listT[i].thread), NULL, __thread_worker__, &(listT[i].worker_param));
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == __max_threads - 1)
|
||||
{
|
||||
sleep_ms(10);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void thread_master_get_status()
|
||||
{
|
||||
printf("\n\nSTATUS\n");
|
||||
do
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Thread Master - Waiting for status\n");
|
||||
printf("Thread Master - Max Threads: %d\n", __max_threads);
|
||||
printf("Param: %d\n", param->max_threads);
|
||||
#endif // DEBUG
|
||||
sleep(1);
|
||||
} while (__max_threads == 0);
|
||||
|
||||
pthread_mutex_lock(¶m->mutex);
|
||||
for (int i = 0; i < __max_threads; i++)
|
||||
{
|
||||
switch (listT[i].worker_param.status)
|
||||
{
|
||||
case IDLE:
|
||||
printf("Thread %d - IDLE\n", listT[i].worker_param.thread_id);
|
||||
break;
|
||||
case BUSY:
|
||||
printf("Thread %d - BUSY\n", listT[i].worker_param.thread_id);
|
||||
isThreadMasterRunning = 1;
|
||||
break;
|
||||
default:
|
||||
printf("Thread %d - UNKNOWN\n", listT[i].worker_param.thread_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(¶m->mutex);
|
||||
printf("END STATUS\n");
|
||||
}
|
||||
|
||||
void thread_master_free()
|
||||
{
|
||||
while (isThreadMasterRunning)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("Thread Master - Waiting for workers to finish\n");
|
||||
#endif // DEBUG
|
||||
|
||||
for (int i = 0; i < __max_threads; i++)
|
||||
{
|
||||
// check if all threads are IDLE
|
||||
if (listT[i].worker_param.status == BUSY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == __max_threads - 1)
|
||||
{
|
||||
isThreadMasterRunning = 0;
|
||||
}
|
||||
}
|
||||
sleep_ms(100);
|
||||
}
|
||||
|
||||
__thread_mutex_destroy__(¶m->mutex);
|
||||
free(param);
|
||||
free(listT);
|
||||
printf("Thread Master - Free and Stopped\n");
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
#ifndef THREADLIB_H
|
||||
#define THREADLIB_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define sleep_ms(x) Sleep(x)
|
||||
#else
|
||||
#define sleep_ms(x) usleep(x * 1000)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
typedef struct worker_param_t
|
||||
{
|
||||
int thread_id;
|
||||
enum status
|
||||
{
|
||||
IDLE,
|
||||
BUSY
|
||||
} status;
|
||||
pthread_mutex_t *mutex;
|
||||
void *custom_params; // User-defined parameters
|
||||
} worker_param_t;
|
||||
|
||||
typedef struct thread
|
||||
{
|
||||
pthread_t thread;
|
||||
worker_param_t worker_param;
|
||||
} thread;
|
||||
|
||||
typedef struct thread_master_param_t
|
||||
{
|
||||
int max_threads;
|
||||
pthread_mutex_t mutex;
|
||||
void *(*__thread_worker__)(void *); // task to be done by the worker
|
||||
void *custom_params; // User-defined parameters
|
||||
} thread_master_param_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the thread master with a specified number of threads and a worker function.
|
||||
*
|
||||
* @param max_threads The maximum possible number of threads to be used.
|
||||
* @param thread_worker The function pointer to the worker function that each thread will execute.
|
||||
* @param custom_params Custom parameters to be passed to the worker function.
|
||||
*/
|
||||
void thread_master_init(int max_threads, void *(*__thread_worker__)(void *), void *custom_params);
|
||||
|
||||
/**
|
||||
* @brief Initializes a mutex.
|
||||
*
|
||||
* @param mutex Pointer to the mutex to be initialized.
|
||||
*/
|
||||
void thread_mutex_init(pthread_mutex_t *mutex);
|
||||
|
||||
/**
|
||||
* @brief Destroys a mutex.
|
||||
*
|
||||
* @param mutex Pointer to the mutex to be destroyed.
|
||||
*/
|
||||
void thread_mutex_destroy(pthread_mutex_t *mutex);
|
||||
|
||||
/**
|
||||
* @brief Frees resources allocated by the thread master.
|
||||
*/
|
||||
void thread_master_free();
|
||||
|
||||
/**
|
||||
* @brief Retrieves the status of the thread master.
|
||||
*/
|
||||
void thread_master_get_status();
|
||||
|
||||
/**
|
||||
* @brief Assigns a new job to the thread workers.
|
||||
*
|
||||
* @param thread_worker The function pointer to the worker function that each thread will execute.
|
||||
* @param custom_params Custom parameters to be passed to the worker function.
|
||||
*/
|
||||
void thread_master_assign_new_job(void *(*__thread_worker__)(void *), void *custom_params);
|
||||
|
||||
/**
|
||||
* Example of usage:
|
||||
*
|
||||
* void *worker_function(void *param) {
|
||||
* worker_param_t *worker_param = (worker_param_t *)param;
|
||||
* printf("Thread %d is working\n", worker_param->thread_id);
|
||||
* sleep_ms(1000); // Simulate work
|
||||
* return NULL;
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* thread_master_init(4, worker_function, NULL);
|
||||
* // Do some work
|
||||
* thread_master_free();
|
||||
* return 0;
|
||||
* }
|
||||
*/
|
||||
|
||||
#endif // !THREADLIB_H
|
||||
Reference in New Issue
Block a user