tests: Impl pthread tests: detach, exit, mutex

Signed-off-by: Max Logaev <maxlogaev@proton.me>
This commit is contained in:
2026-01-21 01:54:39 +03:00
parent b62d269c21
commit a8043361a0
6 changed files with 252 additions and 4 deletions

View File

@@ -5,7 +5,10 @@ project(tests C)
add_executable(hello hello.c)
add_executable(malloc malloc.c)
add_executable(pthread_create pthread.c)
target_link_options(malloc PRIVATE -Wl,-Map=malloc.map)
add_executable(detach pthread/detach.c)
add_executable(create pthread/create.c)
add_executable(exit pthread/exit.c)
add_executable(mutex pthread/mutex.c)
install(TARGETS hello malloc pthread_create DESTINATION tests)
install(TARGETS hello malloc DESTINATION tests)
install(TARGETS mutex create detach exit DESTINATION tests/pthread)

View File

@@ -45,7 +45,6 @@ main ()
// free()
for (size_t i = 0; i < MAX_ALLOCS; i++)
{
__kos_dbg_printf ("%u ", i);
free (allocs[i]);
}

78
tests/pthread/detach.c Normal file
View File

@@ -0,0 +1,78 @@
#include <pthread.h>
#include <string.h>
#include <kolibrios/dbg.h>
#include <kolibrios/syscall.h>
void *
thread_sleep (void *arg)
{
_ksys (SF_SLEEP, 500); // sleep 5 sec
__kos_dbg_puts ("I: thread_sleep: exit!");
return NULL;
}
void *
thread_no_sleep (void *arg)
{
__kos_dbg_puts ("I: thread_no_sleep: exit!");
return NULL;
}
int
main ()
{
int rc = 0;
pthread_t id1, id2;
rc = pthread_create (&id1, NULL, thread_sleep, NULL);
if (rc)
{
__kos_dbg_printf ("E: pthread_create() failed: %s\n", strerror (rc));
return 1;
}
__kos_dbg_puts ("I: Created thread_sleep");
rc = pthread_create (&id2, NULL, thread_no_sleep, NULL);
if (rc)
{
__kos_dbg_printf ("E: pthread_create() failed: %s\n", strerror (rc));
return 1;
}
__kos_dbg_puts ("I: Created thread_no_sleep");
rc = pthread_detach (id1);
if (rc)
{
__kos_dbg_printf ("E: pthread_detach() failed: %s\n", strerror (rc));
return 1;
}
rc = pthread_detach (id2);
if (rc)
{
__kos_dbg_printf ("E: pthread_detach() failed: %s\n", strerror (rc));
return 1;
}
rc = pthread_join (id1, NULL);
if (!rc)
{
__kos_dbg_puts ("E: 'thread_sleep' joined");
return 1;
}
_ksys (SF_SLEEP, 500); // sleep 5s
rc = pthread_join (id2, NULL);
if (!rc)
{
__kos_dbg_puts ("E: 'thread_no_sleep' joined");
return 1;
}
__kos_dbg_puts ("I: Detach test: OK!");
return 0;
}

79
tests/pthread/exit.c Normal file
View File

@@ -0,0 +1,79 @@
#include <pthread.h>
#include <string.h>
#include <stdatomic.h>
#include <stdlib.h>
#include <kolibrios/syscall.h>
static atomic_int count;
static pthread_spinlock_t spin;
static void *
thread (void *arg)
{
_ksys (SF_SLEEP, 50);
int c = 0;
pthread_spin_lock (&spin);
if (count >= 100)
{
__kos_dbg_puts (
"I: Test end. Please make sure all threads are terminated.");
pthread_spin_unlock (&spin);
exit (0);
}
c = count;
count++;
pthread_spin_unlock (&spin);
pthread_t id;
int rc = pthread_create (&id, NULL, thread, NULL);
if (rc)
{
__kos_dbg_printf ("E: %d pthread_create() failed: %s\n", c,
strerror (rc));
return NULL;
}
rc = pthread_detach (id);
if (rc)
{
__kos_dbg_printf ("E: pthread_detach() failed: %s\n", strerror (rc));
return NULL;
}
while (1)
{
_ksys (SF_SLEEP, 100);
}
return NULL;
}
int
main ()
{
pthread_t id;
int rc = pthread_create (&id, NULL, thread, NULL);
if (rc)
{
__kos_dbg_printf ("E: pthread_create() failed: %s\n", strerror (rc));
return 1;
}
rc = pthread_detach (id);
if (rc)
{
__kos_dbg_printf ("E: pthread_detach() failed: %s\n", strerror (rc));
return 1;
}
while (1)
{
_ksys (SF_SLEEP, 100);
}
return 0;
}

89
tests/pthread/mutex.c Normal file
View File

@@ -0,0 +1,89 @@
#include <pthread.h>
#include <string.h>
#include <kolibrios/syscall.h>
#include <kolibrios/dbg.h>
#define NUM_THREADS 5
#define NUM_ITERATIONS 3
int shared_counter = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *
thread_function (void *arg)
{
int thread_id = *(int *)arg;
for (int i = 0; i < NUM_ITERATIONS; i++)
{
// Lock mutex
pthread_mutex_lock (&mutex);
// Critical section
int temp = shared_counter;
__kos_dbg_printf ("I: Thread %d: reading value %d\n", thread_id, temp);
// Simulate work
_ksys (SF_SLEEP, 1); // 10 ms
temp++;
shared_counter = temp;
__kos_dbg_printf ("I: Thread %d: writing value %d\n", thread_id,
shared_counter);
// Unlock mutex
pthread_mutex_unlock (&mutex);
_ksys (SF_SLEEP, 5); // 50 ms
}
__kos_dbg_printf ("I: Thread %d completed\n", thread_id);
return NULL;
}
int
main ()
{
int rc = 0;
pthread_t threads[NUM_THREADS];
int thread_ids[NUM_THREADS];
__kos_dbg_printf ("I: Initial counter value: %d\n", shared_counter);
__kos_dbg_printf ("I: Creating %d threads...\n", NUM_THREADS);
// Create threads
for (int i = 0; i < NUM_THREADS; i++)
{
thread_ids[i] = i + 1;
rc = pthread_create (&threads[i], NULL, thread_function, &thread_ids[i]);
if (rc)
{
__kos_dbg_printf ("E: Thread creation error: %s\n", strerror (rc));
return 1;
}
}
// Wait for all threads to complete
for (int i = 0; i < NUM_THREADS; i++)
{
rc = pthread_join (threads[i], NULL);
if (rc)
{
__kos_dbg_printf ("E: Thread #%u join error: %s\n", threads[i],
strerror (rc));
return 1;
}
}
char dbg_prefix = shared_counter == NUM_THREADS * NUM_ITERATIONS ? 'I' : 'E';
__kos_dbg_printf ("\nI: Final counter value: %d\n", shared_counter);
__kos_dbg_printf ("%c: Expected value: %d\n", dbg_prefix, NUM_THREADS * NUM_ITERATIONS);
// Destroy mutex
pthread_mutex_destroy (&mutex);
return 0;
}