summaryrefslogtreecommitdiff
path: root/ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c
blob: e59caffc5f2b5c0c630b3d8edcb68dc8d164bb0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/***************************************************************************
 * 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 "tx_timer.h"

UINT  _tx_thread_smp_protect(void)
{
DWORD       current_thread_id;
UINT        core;
UINT        interrupt_posture;
TX_THREAD   *current_thread;
UINT        current_state;

    do
    {
        do
        {
            _tx_win32_critical_section_obtain(&_tx_win32_critical_section);

            current_thread_id =  GetCurrentThreadId();
            core =               _tx_thread_smp_core_get();
            current_thread =     _tx_thread_current_ptr[core];

            if ((_tx_win32_threadx_thread != 0) &&
                ((current_thread == TX_NULL) || (current_thread -> tx_thread_win32_thread_id != current_thread_id)))
            {
                _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
                ExitThread(0);
            }

            if (_tx_win32_threadx_thread == 0)
            {
                break;
            }

            if ((current_thread != TX_NULL) && (_tx_thread_preempt_disable == 0U))
            {
                current_state =  current_thread -> tx_thread_state;
                if ((current_state == TX_TERMINATED) || (current_state == TX_COMPLETED))
                {
                    current_thread -> tx_thread_win32_deferred_preempt =  TX_FALSE;
                    current_thread -> tx_thread_win32_suspension_type =   1U;

                    if (_tx_timer_time_slice[core] != 0U)
                    {
                        current_thread -> tx_thread_time_slice =  _tx_timer_time_slice[core];
                        _tx_timer_time_slice[core] =  0U;
                    }

                    _tx_thread_current_ptr[core] =  TX_NULL;
                    _tx_win32_virtual_cores[core].tx_thread_smp_core_mapping_thread =        TX_NULL;
                    _tx_win32_virtual_cores[core].tx_thread_smp_core_mapping_thread_handle = NULL;
                    _tx_win32_virtual_cores[core].tx_thread_smp_core_mapping_thread_id =     0U;
                    current_thread -> tx_thread_smp_core_control =  1U;

                    _tx_win32_debug_entry_insert("SCHEDULE-thread_terminate_preempt_complete", __FILE__, __LINE__);
                    if (SetEvent(_tx_win32_scheduler_event) == 0)
                    {
                        _tx_win32_system_error++;
                    }
                    _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
                    ExitThread(0);
                }
            }

            if ((current_thread != TX_NULL) && (current_thread -> tx_thread_win32_deferred_preempt != TX_FALSE))
            {
                if (SetEvent(_tx_win32_scheduler_event) == 0)
                {
                    _tx_win32_system_error++;
                }
                _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
                _tx_win32_thread_yield();
            }
            else
            {
                break;
            }
        } while (1);

        interrupt_posture =  (UINT) _tx_win32_global_int_disabled_flag;

        if (_tx_thread_smp_protection.tx_thread_smp_protect_core == core)
        {
            _tx_thread_smp_protection.tx_thread_smp_protect_count++;
            _tx_win32_global_int_disabled_flag =  TX_TRUE;
            _tx_win32_debug_entry_insert("PROTECT-obtained-nested", __FILE__, __LINE__);
            break;
        }
        else if (_tx_thread_smp_protection.tx_thread_smp_protect_core == 0xFFFFFFFFUL)
        {
            _tx_thread_smp_protection.tx_thread_smp_protect_in_force =   TX_TRUE;
            _tx_thread_smp_protection.tx_thread_smp_protect_thread =     current_thread;
            _tx_thread_smp_protection.tx_thread_smp_protect_core =       core;
            _tx_thread_smp_protection.tx_thread_smp_protect_count =      1U;
            _tx_thread_smp_protection.tx_thread_smp_protect_thread_id =  current_thread_id;
            _tx_win32_global_int_disabled_flag =  TX_TRUE;
            _tx_win32_debug_entry_insert("PROTECT-obtained", __FILE__, __LINE__);
            break;
        }
        else
        {
            _tx_win32_critical_section_release(&_tx_win32_critical_section);
        }
    } while (1);

    _tx_win32_global_int_disabled_flag =  TX_TRUE;
    return(interrupt_posture);
}