The MASM Forum

General => The Campus => Topic started by: daydreamer on February 21, 2021, 12:47:43 AM

Title: same thread proc for many threads?
Post by: daydreamer on February 21, 2021, 12:47:43 AM
first I start 4 threads,1 thread=one animated object moving around
first call to random positions/direction and while loop keeping most things in registers,output to struct of data and input,and sleep some millis,exiting while loop if detect destroyed or moved far away from screen

how do I solve the get right data with lea ebx,struct+esi*size of struct,thread  #0,#1,#2,#3...to point to right struct of positions,directions,Iconhandle ...?

so if I spawn lots of threads,more than cores,I want to code it right so Sleep or other function,makes OS switch to another thread,while the thread sleeps
good idea to equate registers with variable names?

Title: Re: same thread proc for many threads?
Post by: TouEnMasm on February 21, 2021, 04:29:25 AM
Normal data accessing would work.
Perhaps a little code to explain the problem ?.
The Only one problem is with shared data,you don't seem to have this one ?.
https://docs.microsoft.com/en-us/windows/win32/procthread/thread-local-storage (https://docs.microsoft.com/en-us/windows/win32/procthread/thread-local-storage)
Title: Re: same thread proc for many threads?
Post by: daydreamer on February 22, 2021, 03:29:26 AM
If I use same threadloop for all objects,in array of struct
In global memory
For example
Db "spider",0
Maxhp,currenthp, level
Xpos,ypos,xsize,ysize,xdelta, ydelta,angle
Iconhandle
Status,alive,dead,destroyed
Followed by example mice,cat,dog
1: starting 4 threads,how do I get it right thread output to right struct?thread0 first structure, thread 4, fourth structure?

2: wmpaint drawing objects,mouseclick messages reads data+ one thread reads the others data for test collision detection

Sorry I got stuck on this
Title: Re: same thread proc for many threads?
Post by: TouEnMasm on February 22, 2021, 05:11:29 AM

The CreateThread  lpParameter allow to pass a parameter to the thread.
The first thhread recieve zero as parameter and the thread 4 recieve 3
.data
MyStruct MACHIN 4 dup(<>) ;MACHIN = a defined structure

Title: Re: same thread proc for many threads?
Post by: daydreamer on February 23, 2021, 05:48:52 AM
Quote from: TouEnMasm on February 22, 2021, 05:11:29 AM

The CreateThread  lpParameter allow to pass a parameter to the thread.
The first thhread recieve zero as parameter and the thread 4 recieve 3
.data
MyStruct MACHIN 4 dup(<>) ;MACHIN = a defined structure
thanks
https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread (https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread)
so stack space in 64bit,could be how low Hutch,because I can use loads of registers instead to save values, mov to unused register?
SUSPENDED flag,seem I am possible to create many number of threads/objects I gonna use and fill structs with data and activate when needed
was thinking of first understand howto use SIMT
Title: Re: same thread proc for many threads?
Post by: daydreamer on February 26, 2021, 06:56:16 AM
I am going thru exercises,tutorials,example programs so I solved that,but missing process.h header file,but seem some could be fixed with wrappers,like with createthread -_beginthread

unsynchronized thread exercise:its all random output order,printing out 0-max number of threads,if I have a threadripper or other cpu with many cores,would OS be able to start more threads in order?
Title: Re: same thread proc for many threads?
Post by: TouEnMasm on February 26, 2021, 07:23:00 PM

process.h is in the windows SDK all versions and translated for masm in the translated sdk http://luce.yves.pagesperso-orange.fr/header.htm (http://luce.yves.pagesperso-orange.fr/header.htm)
Title: Re: same thread proc for many threads?
Post by: daydreamer on February 26, 2021, 09:26:46 PM
thanks Yves :thumbsup:
Title: Re: same thread proc for many threads?
Post by: daydreamer on March 02, 2021, 02:11:52 AM
Quote from: TouEnMasm on February 21, 2021, 04:29:25 AM
Normal data accessing would work.
Perhaps a little code to explain the problem ?.
The Only one problem is with shared data,you don't seem to have this one ?.
https://docs.microsoft.com/en-us/windows/win32/procthread/thread-local-storage (https://docs.microsoft.com/en-us/windows/win32/procthread/thread-local-storage)
seem after having several proc using ,LOCAL variables,LOCAL arrays,so I should measure esp at the start of thread and max esp,so I can use optimal stack size,because max 2048 thread with standard max 1mb stack size can become too big 2048*1mb
Title: Re: same thread proc for many threads?
Post by: daydreamer on March 03, 2021, 03:31:49 AM
I am testrunning 1 main thread and 4 workerthreads and use print
loc x,y together with print inside threads doesnt work,it text appears similar randomness that output from 4 threads does
,is that whats not threadsafe runtime?
Title: Re: same thread proc for many threads?
Post by: six_L on March 03, 2021, 03:52:17 AM
No codes, No facts.
are we guessing what's happen?
Title: Re: same thread proc for many threads?
Post by: hutch-- on March 03, 2021, 11:06:18 AM
 :tongue:
Title: Re: same thread proc for many threads?
Post by: daydreamer on March 04, 2021, 06:08:56 AM
loc macro doesnt work with print inside threads,only main thread it works
going local variables (c-style) ,so I can take advantage of each thread has separate 1mb stack, LOCAL variable will be threadspecific
Title: Re: same thread proc for many threads?
Post by: TouEnMasm on March 04, 2021, 08:05:14 PM

First step is to preserve the register esi edi ,startthread proc don't do that.
strange also

Quote
ret 16                            <<<<<<<<<<<<<<<<<<<<<<< ????
spawn endp

Title: Re: same thread proc for many threads?
Post by: daydreamer on March 05, 2021, 05:59:01 AM
Quote from: TouEnMasm on March 04, 2021, 08:05:14 PM

First step is to preserve the register esi edi ,startthread proc don't do that.
strange also

Quote
ret 16                            <<<<<<<<<<<<<<<<<<<<<<< ????
spawn endp

thanks,I fix the first
second is plan ahead
spawn proc has 4 arguments,so more control with read from readfile or som data section as alternative to randomized spawn and maybe I want to control spawns,so they trigger spawned directly when player comes close to some place/xyz coordinate
testing purposes random generator is good enough for now
Title: Re: same thread proc for many threads?
Post by: TouEnMasm on March 06, 2021, 04:44:15 AM
A good thing,,keep esp in a variable at the start of code.
at the end of code,verify that his value had not changed.
Normally,a compiler create the epilogue and had itself the ret16.

Title: Re: same thread proc for many threads?
Post by: daydreamer on March 07, 2021, 12:07:03 AM
Quote from: TouEnMasm on March 06, 2021, 04:44:15 AM
A good thing,,keep esp in a variable at the start of code.
at the end of code,verify that his value had not changed.
Normally,a compiler create the epilogue and had itself the ret16.
good to know max stack size used,saved esp can instead be used temporary pointing to LOCAL array you could do stack tricks,before restore it
Title: Re: same thread proc for many threads?
Post by: six_L on March 07, 2021, 05:04:15 AM
Hi, daydreamer
although you providid the source codes, but i don't understand which key is your question. in accordance with " use print loc x,y together with print inside threads doesnt work,it text appears similar randomness that output from 4 threads does", i only guessed and trying to give a bit of useful information. the TLS that TouEnMasm has been mentioned maybe handle this flaw.

testdll_2.dll
option casemap:none
option win64:7
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \UASM64\include\windows.inc

includelib \UASM64\Lib\user32.lib
includelib \UASM64\Lib\kernel32.lib
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
return  MACRO arg
        mov rax, arg
        ret
ENDM
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.DATA?
        hInstance dq ?
dwTlsIndex dd ? ;// address of shared memory
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.CODE
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
DllEntry proc hinstDLL:HINSTANCE, fdwReason:QWORD, lpvReserved:QWORD
LOCAL lpvData:LPVOID
         
;// The DLL is loading due to process
        ;// initialization or a call to LoadLibrary.
   
.if fdwReason == DLL_PROCESS_ATTACH
mov rax, hinstDLL
mov hInstance,rax
;// Allocate a TLS index.
invoke TlsAlloc
mov dwTlsIndex,eax
.if dwTlsIndex == TLS_OUT_OF_INDEXES
return FALSE
.endif
return TRUE
;// No break: Initialize the index for first thread.
;// The attached process creates a new thread.

.elseif fdwReason == DLL_PROCESS_DETACH
;// DLL unload due to process termination or FreeLibrary.
;// Release the allocated memory for this thread.
invoke TlsGetValue,dwTlsIndex
mov lpvData,rax
.if lpvData != 0
invoke GlobalFree,lpvData
.endif
;// Release the TLS index.
invoke TlsFree,dwTlsIndex
return TRUE
.elseif fdwReason == DLL_THREAD_ATTACH
;// Initialize the TLS index for this thread.
invoke GlobalAlloc,LPTR,256
mov lpvData,rax
.if lpvData != NULL
invoke TlsSetValue,dwTlsIndex,lpvData
.if rax == NULL
return FALSE
.endif
.endif
return TRUE
.elseif fdwReason == DLL_THREAD_DETACH
;// The thread of the attached process terminates.
;// Release the allocated memory for this thread.
invoke TlsGetValue,dwTlsIndex
mov lpvData,rax
.if lpvData != 0
invoke GlobalFree,lpvData
.endif
return TRUE
.endif
return FALSE

DllEntry Endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_StoreData PROC _dq:QWORD
LOCAL lpvData:LPVOID ; the OS TLS stored data pointer
LOCAL pData:QWORD ; The stored data pointer
LOCAL _Data:QWORD ; The data

invoke TlsGetValue,dwTlsIndex
mov lpvData,rax
.if lpvData == 0
invoke GlobalAlloc,LPTR,256
mov lpvData,rax
.if lpvData == NULL
return FALSE
.endif
invoke TlsSetValue,dwTlsIndex,lpvData
.if rax == NULL
return FALSE
.endif
.endif
;// Cast to my data type.
;// In this example, it is only a pointer to a QWORD
;// but it can be a structure pointer to contain more complicated data.
;pData = (QWORD *) lpvData
;(*pData) = dq;
mov rax,_dq
mov _Data,rax
lea rax,_Data
mov pData,rax
mov rax,lpvData
mov rcx,pData
mov [rax],rcx
return TRUE

_StoreData ENDP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_GetData PROC _pdq:QWORD
LOCAL lpvData:LPVOID
LOCAL pData:QWORD ;The stored memory pointer

invoke TlsGetValue,dwTlsIndex
mov lpvData,rax
.if lpvData == 0
return FALSE
.endif
;   pData = (QWORD *) lpvData;
;   (*pdq) = (*pData);
mov rax,lpvData
mov rcx,[rax]
mov pData,rcx
mov rax,pData
mov rcx,[rax]
mov rax,_pdq
mov [rax],rcx ; data write into the address from outside.
return TRUE

_GetData ENDP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

End DllEntry


TlsTest_2.exe
option casemap:none
option win64:7
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \UASM64\include\windows.inc

includelib \UASM64\Lib\user32.lib
includelib \UASM64\Lib\kernel32.lib
includelib \UASM64\Lib\gdi32.lib
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include testdll_2.inc
includelib testdll_2.lib
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
MYTHREADTLSDATA struct
m_ID dd ?
m_Name db 12 dup(?)
m_xx dd ?
m_yy dd ?
m_Coror dd ?
MYTHREADTLSDATA ends
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
return  MACRO arg
        mov rax, arg
        ret
ENDM
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ICO_MAIN equ 1000
DLG_MAIN equ 100
IDC_STAR equ 101
IDC_EXIT equ 102
IDC_OUTPUT equ 103

THREADCOUNT equ 4
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data?
hInstance dq ?
hOutwnd dq ?
winClientW dd ?
winClientH dd ?
hFont dq ?
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data
hThreadBuf QWORD THREADCOUNT dup (0)
ThreadIndex QWORD 0
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.code
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ErrorMessage Proc USES RBX lpCaption:qword
Local lpErrorMessage:QWORD

call GetLastError
lea rbx,lpErrorMessage
invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, NULL, eax, LANG_NEUTRAL,rbx,0,NULL

invoke MessageBox, 0, lpErrorMessage, lpCaption, MB_OK
invoke LocalFree, lpErrorMessage
ret   

ErrorMessage EndP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
iRandom_A proc _dqMin:QWORD, _dqMax:QWORD

mov rax, 100                ; out of range number
rdtsc                           ; date time counter
pause                           ; spinlock pause
bswap rax                     ; reverse byte order
mov r11, rax                ; store rax in r11

mov rcx, 10                 ; loop count
@@:
rdtsc                           ; date time counter
pause                           ; spinlock pause
bswap rax                     ; reverse byte order
rol rax, 11                 ; rotate left by prime
xor r11, rax                ; xor rax to r11
rol r11, 7                  ; rotate left by prime
sub rcx, 1                  ; decrement counter

jnz @B
mov rax, r11                ; seed the value in r11

mov rcx, _dqMax
sub rcx, _dqMin
inc rcx
xor rdx, rdx
div rcx
mov rax, rdx
add rax,_dqMin ; rax = Rand_Number [ _dqMin, _dqMax ]

ret

iRandom_A endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
ThreadFunc PROC USES RBX _VOID:QWORD
LOCAL dqOut:QWORD
LOCAL szBuf[64]:BYTE
LOCAL thePrivateData:MYTHREADTLSDATA
LOCAL hdc:HDC

inc ThreadIndex
invoke RtlZeroMemory,ADDR thePrivateData,sizeof MYTHREADTLSDATA

;here, save the datas of thread private
lea rbx,thePrivateData

invoke GetCurrentThreadId
mov (MYTHREADTLSDATA PTR [rbx]).m_ID,eax

invoke RtlZeroMemory,ADDR szBuf,sizeof szBuf
invoke wsprintf,ADDR szBuf, CStr("position_%d"),ThreadIndex
invoke lstrcat,ADDR (MYTHREADTLSDATA PTR [rbx]).m_Name, ADDR szBuf

invoke iRandom_A, 0, winClientW
mov (MYTHREADTLSDATA PTR [rbx]).m_xx,eax
invoke iRandom_A, 0, winClientH
mov (MYTHREADTLSDATA PTR [rbx]).m_yy,eax

.if ThreadIndex == 1
mov (MYTHREADTLSDATA PTR [rbx]).m_Coror,0FF0000H
.elseif ThreadIndex == 2
mov (MYTHREADTLSDATA PTR [rbx]).m_Coror,000FF00H
.elseif ThreadIndex == 3
mov (MYTHREADTLSDATA PTR [rbx]).m_Coror,00000FFH
.elseif ThreadIndex == 4
mov (MYTHREADTLSDATA PTR [rbx]).m_Coror,0FFFF00H
.endif

invoke _StoreData,rbx
.if rax == NULL
invoke ErrorMessage,CStr("StoreData error")
return FALSE
.endif
;----------------------------------------------------------------------------------
;here, use the datas of thread private
invoke _GetData, addr dqOut
.if rax == FALSE
invoke ErrorMessage,CStr("GetData error")
return FALSE
.endif

invoke RtlZeroMemory,addr szBuf,sizeof szBuf
mov rbx,dqOut
invoke wsprintf,ADDR szBuf, CStr("ThreadId-%d: [ %s (%d, %d) ]"),(MYTHREADTLSDATA PTR [rbx]).m_ID ,\
ADDR (MYTHREADTLSDATA PTR [rbx]).m_Name,(MYTHREADTLSDATA PTR [rbx]).m_xx,(MYTHREADTLSDATA PTR [rbx]).m_yy

Invoke GetDC, hOutwnd 
mov hdc, rax
invoke SelectObject,hdc,hFont
invoke SetBkMode,hdc,TRANSPARENT
invoke SetTextColor,hdc,(MYTHREADTLSDATA PTR [rbx]).m_Coror
invoke TextOut,hdc,(MYTHREADTLSDATA PTR [rbx]).m_xx,(MYTHREADTLSDATA PTR [rbx]).m_yy,addr szBuf,sizeof szBuf
Invoke ReleaseDC, hOutwnd, hdc

return TRUE

ThreadFunc ENDP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
StartThread PROC USES RBX RDI Parameters:QWORD
Local hm:QWORD
Local dwThreadID:DWORD
LOCAL rc:RECT

;// Load the DLL
invoke LoadLibrary,CStr("testdll_2.dll")
.if rax == NULL
invoke ErrorMessage,CStr("DLL failed to load")
return FALSE
.else
mov hm,rax
.endif

invoke GetClientRect, hOutwnd, ADDR rc

mov eax,rc.right
sub eax,rc.left
mov winClientW,eax

mov eax,rc.bottom
sub eax,rc.top
mov winClientH,eax

xor rbx,rbx
lea rdi,hThreadBuf
.while rbx < THREADCOUNT
invoke CreateThread, NULL, 0, offset ThreadFunc,NULL,NULL, addr dwThreadID
.if rax == NULL
invoke ErrorMessage,CStr("CreateThread error")
return FALSE
.endif
mov [rdi+8*rbx],rax
inc rbx
.endw
invoke WaitForMultipleObjects,THREADCOUNT,addr hThreadBuf,TRUE, INFINITE
invoke FreeLibrary,hm

return TRUE

StartThread ENDP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_CloseThreadHandle Proc USES RBX RDI phThread:qword,tNum:qword

xor rbx,rbx
lea rdi,phThread
.while rbx < tNum
mov rax,[rdi+8*rbx]
invoke CloseHandle,rax
inc rbx
.endw
ret   

_CloseThreadHandle EndP
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
_ProcDlgMain proc  hWnd:qword,wMsg:dword,wParam:qword,lParam:qword
Local dwThreadID:DWORD

mov eax,wMsg
.if eax == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke GetDlgItem,hWnd,IDC_OUTPUT
mov hOutwnd,rax

invoke  CreateFont,14,0,0,0,FW_BOLD,FALSE,FALSE,FALSE, \
    DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, \
    DEFAULT_QUALITY,FIXED_PITCH, CStr("Cambria")
mov hFont, rax

.elseif eax == WM_COMMAND
mov rax,wParam
.if ax == IDC_EXIT
invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL

.elseif ax == IDC_STAR
mov ThreadIndex,0
invoke CreateThread, NULL, 0, offset StartThread,NULL,NULL, addr dwThreadID
invoke CloseHandle,rax
.endif
.elseif eax == WM_CLOSE
invoke _CloseThreadHandle,hThreadBuf,THREADCOUNT
invoke DeleteObject, hFont
invoke EndDialog,hWnd,NULL
.else
mov rax,FALSE
ret
.endif
mov rax,TRUE
ret

_ProcDlgMain endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
WinMainCRTStartup Proc
invoke GetModuleHandle,NULL
mov hInstance,rax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
WinMainCRTStartup Endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end


TlsTest_2.rc
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <\UASM64\include\resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 1000
#define DLG_MAIN 100
#define IDC_STAR 101
#define IDC_EXIT 102
#define IDC_OUTPUT 103
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 0, 0, 357, 164
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "TLS_Test2"
FONT 10, "Consolas"
{
LTEXT "", IDC_OUTPUT,2, 2, 352, 145, WS_BORDER
PUSHBUTTON "Start", IDC_STAR,2, 148, 40, 14
PUSHBUTTON "Exit", IDC_EXIT, 314, 148, 40, 14, WS_TABSTOP
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "MICON.ico"

Title: Re: same thread proc for many threads?
Post by: daydreamer on March 07, 2021, 08:05:04 AM
Thanks six_l :thumbsup:
I am new to this SIMT,except going thru few c examples/ tutorials and make asm versions of them