/*************************************************************************** * 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.4). // Some portions generated by GitHub Copilot (claude-sonnet-4.6). #define TX_SOURCE_CODE #define TX_THREAD_SMP_SOURCE_CODE #include "tx_api.h" #include "tx_thread.h" #include "tx_timer.h" VOID _tx_thread_context_save(VOID) { TX_THREAD *thread_ptr; UINT interrupt_posture; interrupt_posture = _tx_thread_smp_protect(); if (interrupt_posture != TX_FALSE) { _tx_win32_system_error++; } _tx_win32_debug_entry_insert("CONTEXT_SAVE", __FILE__, __LINE__); thread_ptr = _tx_thread_current_ptr[0]; if ((thread_ptr != TX_NULL) && (_tx_thread_system_state[0] == 0UL)) { if (thread_ptr -> tx_thread_win32_mutex_access == TX_FALSE) { if (_tx_thread_preempt_disable == 0U) { /* Thread is not in a preempt-disabled section; suspend it normally so * context_restore can preempt it if a higher-priority thread is ready. */ _tx_win32_thread_suspend(thread_ptr -> tx_thread_win32_thread_handle); _tx_win32_debug_entry_insert("CONTEXT_SAVE-suspend_thread", __FILE__, __LINE__); } else { /* Thread holds the SMP preemption lock (_tx_thread_preempt_disable != 0). * Issuing SuspendThread/ResumeThread here would cost ~100 µs for zero * benefit: context_restore will skip preemption anyway because * _tx_thread_preempt_disable is still non-zero when it runs (the ISR * cannot lower the count below its value at ISR entry while it holds the * Win32 critical section). Flag the thread so context_restore knows not * to issue a matching ResumeThread. * * MISRA C 2012 Rule 10.3 deviation: suspension_type is a UINT field used * as a small state tag; value 3 is a port-local extension of the existing * 0/1/2 enumeration. */ thread_ptr -> tx_thread_win32_suspension_type = 3U; } } else { /* Thread is spinning on the Win32 critical section (mutex_access TRUE). * It is blocked waiting to acquire the CS and cannot execute any protected * ThreadX code, so SuspendThread is unnecessary. Tag the thread with * suspension_type 4 so context_restore handles it correctly: * - no-preemption path: just clear the flag (no ResumeThread). * - preemption path: call SuspendThread retrospectively and proceed. * * MISRA C 2012 Rule 10.3 deviation: value 4 is a port-local extension. */ thread_ptr -> tx_thread_win32_suspension_type = 4U; } } _tx_thread_system_state[0]++; }