News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Next thread test.

Started by hutch--, September 24, 2009, 12:29:00 PM

Previous topic - Next topic

hutch--

The following is a test piece for starting and closing threads looking for the fastest way to perform this task while not locking the machine up. I have tried a number of techniques for getting the signalled state of the 4 threads in the test and so far the API WaitForMultipleObjects() gives both end the bests, speed and processor usage. I have left the commented out runtime code in the thread proc there as this allowed a loop test in the caller running the 4 threads 4096 times for a total of 16384 threads started and closed.

I am going to have to play with the API functions that wait for a signalled state to see if there are any suitable to stop a thread without wasting large amounts of processor time so that I can try using one in the taile end of a thread so it can loop back and be re-used but among the things that I need to quantify is whether its faster just to start new threads or re-use existing ones.

This is the code.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    start_thread PROTO :DWORD
    work_thread  PROTO :DWORD

    THREAD_ARGS STRUCT
      flag  dd ?            ; thread start flag
      arg1  dd ?
      arg2  dd ?
      arg3  dd ?
      arg4  dd ?
      arg5  dd ?
      arg6  dd ?
      arg7  dd ?
      arg8  dd ?
    THREAD_ARGS ENDS

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL thst      :THREAD_ARGS
    LOCAL th_arr[4] :DWORD          ; thread handle array, 4 x DWORD = 16 bytes
    LOCAL cntr      :DWORD

  ; -------------------------------
  ; load the THREAD_ARGS structure
  ; -------------------------------
    mov DWORD PTR thst.arg1, 1
    mov DWORD PTR thst.arg2, 2
    mov DWORD PTR thst.arg3, 3
    mov DWORD PTR thst.arg4, 4

    mov cntr, 4096

  @@:

  ; -----------------------------------------------
  ; start the four threads writing handles to array
  ; -----------------------------------------------
    m2m th_arr[0],  rv(start_thread,ADDR thst)
    m2m th_arr[4],  rv(start_thread,ADDR thst)
    m2m th_arr[8],  rv(start_thread,ADDR thst)
    m2m th_arr[12], rv(start_thread,ADDR thst)

    invoke WaitForMultipleObjects,4,ADDR th_arr,TRUE,5000      ; 5 seconds time out

  ; ------------------------
  ; close the thread handles
  ; ------------------------
    invoke CloseHandle,th_arr[0]
    invoke CloseHandle,th_arr[4]
    invoke CloseHandle,th_arr[8]
    invoke CloseHandle,th_arr[12]

    sub cntr, 1
    jnz @B

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

start_thread proc pstruct:DWORD

    LOCAL tID       :DWORD
    LOCAL hThread   :DWORD

    push esi
    mov esi, pstruct
    mov (THREAD_ARGS PTR [esi]).flag, 1    ; set the flag

    mov hThread, rv(CreateThread,NULL,NULL,ADDR work_thread,pstruct,NULL,ADDR tID)

  ; ---------------------------------------------
  ; block new threads from starting until args
  ; are saved in the current thread being created
  ; ---------------------------------------------
  spinlock:
    cmp (THREAD_ARGS PTR [esi]).flag, 0    ; loop until created thread clears the flag
    jne spinlock
  ; ---------------------------------------------

    mov eax, hThread
    pop esi

    ret

start_thread endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

work_thread proc pstruct:DWORD

    LOCAL args[4]:DWORD

  ; --------------------------------------------------------------
  ; load the args to local array before the caller flag is cleared
  ; --------------------------------------------------------------
    mov eax, pstruct
    m2m args[0],  (THREAD_ARGS PTR [eax]).arg1
    m2m args[4],  (THREAD_ARGS PTR [eax]).arg2
    m2m args[8],  (THREAD_ARGS PTR [eax]).arg3
    m2m args[12], (THREAD_ARGS PTR [eax]).arg4

  ; ------------------------------------
  ; release the thread starter procedure
  ; ------------------------------------
    mov (THREAD_ARGS PTR [eax]).flag, 0    ; clear the flag

  ; ********************************************************************
  ; ************* Thread specific runtime code goes here ***************
  ; ********************************************************************

;     invoke SleepEx,1,0   ; <<<< uncomment this to make the task really slow.

;     print str$(args[0])
;     print str$(args[4])
;     print str$(args[8])
;     print str$(args[12])
;     print ":"

  ; ********************************************************************
  ; ********************************************************************
  ; ********************************************************************

  ; -------------------------------------
  ; set the thread exit code if necessary
  ; -------------------------------------
    invoke ExitThread,0

    ret

work_thread endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php