/*************************************************************************** * 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 Codex (gpt 5.4). * 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 **************************************************************************/ // Some portions generated by Codex (gpt 5.5). #define TX_SOURCE_CODE #define TX_THREAD_SMP_SOURCE_CODE #include "tx_api.h" #include "tx_thread.h" #include static DWORD WINAPI _tx_win32_thread_entry(LPVOID ptr); VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) { TX_PARAMETER_NOT_USED(function_ptr); #if (TX_WIN32_USE_ADDRESS_WAIT != 0) thread_ptr -> tx_thread_win32_thread_run_semaphore = NULL; thread_ptr -> tx_thread_win32_thread_start_semaphore = NULL; #else thread_ptr -> tx_thread_win32_thread_run_semaphore = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); if (thread_ptr -> tx_thread_win32_thread_run_semaphore == NULL) { printf("ThreadX SMP Win64 error creating thread run semaphore!\n"); while (1) { } } thread_ptr -> tx_thread_win32_thread_start_semaphore = CreateSemaphore(NULL, 0, 1, NULL); if (thread_ptr -> tx_thread_win32_thread_start_semaphore == NULL) { printf("ThreadX SMP Win64 error creating thread start semaphore!\n"); while (1) { } } #endif thread_ptr -> tx_thread_win32_thread_handle = CreateThread(NULL, TX_WIN32_THREAD_STACK_SIZE, _tx_win32_thread_entry, (LPVOID) thread_ptr, CREATE_SUSPENDED, &thread_ptr -> tx_thread_win32_thread_id); if (thread_ptr -> tx_thread_win32_thread_handle == NULL) { printf("ThreadX SMP Win64 error creating thread!\n"); while (1) { } } SetThreadPriority(thread_ptr -> tx_thread_win32_thread_handle, TX_WIN32_PRIORITY_USER_THREAD); thread_ptr -> tx_thread_win32_suspension_type = 2U; thread_ptr -> tx_thread_win32_mutex_access = TX_FALSE; thread_ptr -> tx_thread_win32_int_disabled_flag = TX_FALSE; thread_ptr -> tx_thread_win32_deferred_preempt = TX_FALSE; thread_ptr -> tx_thread_win32_virtual_core = 0U; thread_ptr -> tx_thread_win32_run_sequence = 0L; thread_ptr -> tx_thread_win32_run_sequence_seen = 0L; thread_ptr -> tx_thread_win32_start_sequence = 0L; thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8); *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0UL; thread_ptr -> tx_thread_smp_core_control = 1U; ResumeThread(thread_ptr -> tx_thread_win32_thread_handle); } static DWORD WINAPI _tx_win32_thread_entry(LPVOID ptr) { TX_THREAD *thread_ptr; thread_ptr = (TX_THREAD *) ptr; _tx_win32_threadx_thread = 1; _tx_win32_debug_entry_insert("THREAD_ENTRY_wait", __FILE__, __LINE__); _tx_win32_wait_for_thread_run(thread_ptr); #ifdef TX_WIN32_PROFILE_ENABLE _tx_win32_profile_mark_run_wake(thread_ptr); #endif _tx_win32_debug_entry_insert("THREAD_ENTRY_wake", __FILE__, __LINE__); /* A delete/reset cleanup may wake a host thread that was never scheduled. Only treat the wakeup as terminal if the ThreadX thread is already in a terminal state; otherwise allow the normal startup race to complete. */ if ((thread_ptr -> tx_thread_smp_core_control != 0U) && ((thread_ptr -> tx_thread_state == TX_TERMINATED) || (thread_ptr -> tx_thread_state == TX_COMPLETED))) { ExitThread(0U); } _tx_win32_current_virtual_core = thread_ptr -> tx_thread_win32_virtual_core; #ifdef TX_WIN32_PROFILE_ENABLE _tx_win32_profile_mark_start_ack(thread_ptr); #endif _tx_win32_thread_start_ack_signal(thread_ptr); _tx_win32_debug_entry_insert("THREAD_ENTRY_ack", __FILE__, __LINE__); _tx_thread_shell_entry(); return(0U); }