/***************************************************************************/ /* 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 is designed to test basic POSIX message queue operation: open a queue, send a message through it, receive the message back and confirm both the contents and the priority survived the round trip. */ #include #include "tx_api.h" #include "pthread.h" #define TEST_MESSAGE_SIZE 40 #define TEST_QUEUE_DEPTH 10 #define TEST_PRIORITY 3 /* Memory the POSIX layer carves its own objects out of. */ static ULONG posix_region[192 * 1024 / sizeof(ULONG)]; static pthread_t worker; static pthread_attr_t worker_attr; static mqd_t queue_des; static struct mq_attr queue_attr; extern void test_control_return(UINT status); static VOID *worker_entry(VOID *input); /* Define what the initial system looks like. */ #ifdef CTEST void test_application_define(void *first_unused_memory) #else void posix_mq_basic_application_define(void *first_unused_memory) #endif { struct sched_param param; VOID *storage_ptr; (void) first_unused_memory; /* Bring the POSIX layer up. It returns the first address beyond its own structures, which is where pthread stacks are taken from. */ storage_ptr = posix_initialize(posix_region); queue_attr.mq_maxmsg = TEST_QUEUE_DEPTH; queue_attr.mq_msgsize = TEST_MESSAGE_SIZE; queue_des = mq_open("mq_basic", O_CREAT | O_RDWR, 0, &queue_attr); if (queue_des == (mqd_t) ERROR) { printf("Running POSIX Message Queue Basic Test............................. ERROR #1\n"); test_control_return(1); } pthread_attr_init(&worker_attr); param.sched_priority = 10; pthread_attr_setschedparam(&worker_attr, ¶m); pthread_attr_setstackaddr(&worker_attr, storage_ptr); if (pthread_create(&worker, &worker_attr, worker_entry, NULL) != OK) { printf("Running POSIX Message Queue Basic Test............................. ERROR #2\n"); test_control_return(1); } } static VOID *worker_entry(VOID *input) { CHAR sent[TEST_MESSAGE_SIZE]; CHAR received[TEST_MESSAGE_SIZE]; ULONG received_priority; ssize_t received_length; INT i; (void) input; printf("Running POSIX Message Queue Basic Test............................. "); /* Build a recognisable payload rather than a constant one, so a message that is dropped or truncated cannot pass by accident. */ for (i = 0; i < TEST_MESSAGE_SIZE; i++) { sent[i] = (CHAR) (i + 1); received[i] = (CHAR) 0; } if (mq_send(queue_des, sent, TEST_MESSAGE_SIZE, TEST_PRIORITY) != OK) { printf("ERROR #3\n"); test_control_return(1); } received_priority = 0; received_length = mq_receive(queue_des, received, TEST_MESSAGE_SIZE, &received_priority); if (received_length != (ssize_t) TEST_MESSAGE_SIZE) { printf("ERROR #4\n"); test_control_return(1); } if (received_priority != (ULONG) TEST_PRIORITY) { printf("ERROR #5\n"); test_control_return(1); } for (i = 0; i < TEST_MESSAGE_SIZE; i++) { if (received[i] != sent[i]) { printf("ERROR #6\n"); test_control_return(1); } } if (mq_close(queue_des) != OK) { printf("ERROR #7\n"); test_control_return(1); } if (mq_unlink("mq_basic") != OK) { printf("ERROR #8\n"); test_control_return(1); } printf("SUCCESS!\n"); test_control_return(0); return (NULL); }