summaryrefslogtreecommitdiff
path: root/test/posix/regression/posix_pthread_basic_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/posix/regression/posix_pthread_basic_test.c')
-rw-r--r--test/posix/regression/posix_pthread_basic_test.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/test/posix/regression/posix_pthread_basic_test.c b/test/posix/regression/posix_pthread_basic_test.c
new file mode 100644
index 00000000..afb8d4f3
--- /dev/null
+++ b/test/posix/regression/posix_pthread_basic_test.c
@@ -0,0 +1,192 @@
+/***************************************************************************/
+/* Copyright (c) 2026 Eclipse ThreadX contributors */
+/* */
+/* This program and the accompanying materials are made available under */
+/* the terms of the MIT License which is available at */
+/* https://opensource.org/licenses/MIT. */
+/* */
+/* AI Disclosure: This file was largely AI-generated by Claude Code */
+/* (Opus 5). The AI-generated portions may be considered public domain */
+/* (CC0-1.0) and not subject to the project's licence. The human */
+/* contributor has reviewed and verified that the code is correct. */
+/* */
+/* SPDX-License-Identifier: MIT and CC0-1.0 */
+/***************************************************************************/
+
+/* This test covers basic pthread and synchronisation operation: a pthread runs
+ and reports its own identity, a mutex serialises access to shared state, a
+ semaphore signals between two pthreads, and a join collects the worker's exit
+ value. */
+
+#include <stdio.h>
+#include "tx_api.h"
+/* The layer ships no semaphore.h; sem_t and the sem_* calls arrive through
+ pthread.h, which pulls in tx_posix.h. */
+#include "pthread.h"
+
+#define TEST_STACK_BYTES 4096
+
+static ULONG posix_region[192 * 1024 / sizeof(ULONG)];
+
+static pthread_t worker;
+static pthread_attr_t worker_attr;
+static pthread_t driver;
+static pthread_attr_t driver_attr;
+
+static pthread_mutex_t guard;
+static sem_t handoff;
+
+static volatile INT shared_counter;
+static pthread_t worker_self_id;
+
+static INT worker_result = 77;
+
+extern void test_control_return(UINT status);
+
+static VOID *worker_entry(VOID *input);
+static VOID *driver_entry(VOID *input);
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void posix_pthread_basic_application_define(void *first_unused_memory)
+#endif
+{
+
+struct sched_param param;
+VOID *storage_ptr;
+
+ (void) first_unused_memory;
+
+ storage_ptr = posix_initialize(posix_region);
+
+ if (pthread_mutex_init(&guard, NULL) != OK)
+ {
+
+ printf("Running POSIX Pthread Basic Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ if (sem_init(&handoff, 0, 0) != OK)
+ {
+
+ printf("Running POSIX Pthread Basic Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* The driver runs below the worker so that the worker reaches its first
+ blocking point before the driver inspects anything. */
+ pthread_attr_init(&worker_attr);
+ param.sched_priority = 15;
+ pthread_attr_setschedparam(&worker_attr, &param);
+ pthread_attr_setstackaddr(&worker_attr, storage_ptr);
+ storage_ptr = (ULONG *) storage_ptr + (TEST_STACK_BYTES / sizeof(ULONG));
+
+ pthread_attr_init(&driver_attr);
+ param.sched_priority = 10;
+ pthread_attr_setschedparam(&driver_attr, &param);
+ pthread_attr_setstackaddr(&driver_attr, storage_ptr);
+
+ if (pthread_create(&worker, &worker_attr, worker_entry, NULL) != OK)
+ {
+
+ printf("Running POSIX Pthread Basic Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ if (pthread_create(&driver, &driver_attr, driver_entry, NULL) != OK)
+ {
+
+ printf("Running POSIX Pthread Basic Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+static VOID *worker_entry(VOID *input)
+{
+
+INT i;
+
+ (void) input;
+
+ /* Record what this pthread believes its own ID to be, for the driver to
+ compare against the ID pthread_create() handed back. */
+ worker_self_id = pthread_self();
+
+ for (i = 0; i < 100; i++)
+ {
+
+ pthread_mutex_lock(&guard);
+ shared_counter++;
+ pthread_mutex_unlock(&guard);
+ }
+
+ /* Hand control to the driver. */
+ sem_post(&handoff);
+
+ return ((VOID *) &worker_result);
+}
+
+
+static VOID *driver_entry(VOID *input)
+{
+
+VOID *exit_value;
+
+ (void) input;
+
+ printf("Running POSIX Pthread Basic Test.................................. ");
+
+ /* Wait for the worker to finish its counting. */
+ if (sem_wait(&handoff) != OK)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ if (shared_counter != 100)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ if (worker_self_id != worker)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ exit_value = NULL;
+ if (pthread_join(worker, &exit_value) != OK)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ if (exit_value != (VOID *) &worker_result)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ if (pthread_mutex_destroy(&guard) != OK)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+ return (NULL);
+}