; Listing5-3.asm
;
; A program that demonstrates simple multithreading
; with critical sections.

            option     casemap:none
            option     prologue:none
            include    aoalib.inc   ;AoA library + constants
            includelib aoalib.lib   ;Link in aoalib library
            include    c:\masm32\include64\win64.inc
            include    c:\masm32\include64\kernel32.inc
            includelib c:\masm32\lib64\kernel32.lib  
            
            .const

; Program title:

            align   word
ttlStr      byte    "Listing 5-3", 0

            .data
            align   qword            
myCS        CRITICAL_SECTION {}
eventHandle dword   ?


            .code

saveRBX     textequ <[rbp-8]>
saveRCX     textequ <[rbp-16]>

; Here is the thread that will briefly run:

threadProc  proc    public
            push    rbp
            mov     rbp, rsp
            sub     rsp, 64
            mov     saveRBX, rbx
            mov     saveRCX, rcx
            
            LEA     RCX, myCS
            CALL    EnterCriticalSection
            mov     ebx, 20
rptLoop:    mov     edx, ebx
            call    print
            byte    "Thread loop: %d", nl, 0
            
            dec     ebx
            jnz     rptLoop

            lea     rcx, myCS
            call    LeaveCriticalSection
            
            mov     ecx, eventHandle
            call    SetEvent

; Terminate the thread:

            xor     rax, rax        ;Return result
            mov     rbx, saveRBX
            leave
            ret
threadProc  endp

        
; Here is the main assembly language function.

            
            public  asmMain
asmMain     proc
            
            push    rbp
            mov     rbp, rsp
            sub     rsp, 64
            mov     [rbp-8], rbx

            lea     rcx, myCS
            call    InitializeCriticalSection
            
            xor     ecx, ecx        ;No security attributes
            xor     edx, edx        ;Auto-reset mode
            xor     r8d, r8d        ;Initial: unsignaled
            xor     r9, r9          ;No event ID; local
            call    CreateEvent
            mov     eventHandle, eax
            
            
            call    print
            byte    "Creating thread:", nl, 0
            
; Start threadProc running:

            xor     rcx, rcx        ;No security attributes
            xor     rdx, rdx        ;Default stack size
            lea     r8, threadProc  ;Address of thread code
            xor     r9, r9          ;No thread parameter
            xor     rax, rax        ;Default thread flags
            mov     [rsp+32], rax   ;Must pass on stack.
            xor     rax, rax        ;Don't save threadID
            mov     [rsp+40], rax
            call    CreateThread
 
            lea     rcx, myCS
            call    EnterCriticalSection
            mov     ebx, 20
rptLoop:    
            
            mov     edx, ebx
            call    print
            byte    "Main loop: %d", nl, 0
            
            dec     ebx
            jnz     rptLoop
            lea     rcx, myCS
            call    LeaveCriticalSection
            

allDone:    mov     ecx, eventHandle
            mov     edx, INFINITE
            call    WaitForSingleObject
                
            lea     rcx, myCS
            call    DeleteCriticalSection
            
            mov     rbx, [rbp-8]
            leave
            ret     ;Returns to caller
        
asmMain     endp
            end