summaryrefslogtreecommitdiff
path: root/ports_smp/win64/vs_2022/src/tx_thread_stack_build.c
blob: 0531fb3b6e6bfb80a3b6b76aa3896cf731a3fd64 (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
/***************************************************************************
 * 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 <stdio.h>

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);
}