Subversion Repositories Kolibri OS

Rev

Rev 6811 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; Threads management.
  2.  
  3. ; int create_thread(int (*proc)(void *param), void *param, int stack_size)
  4. ; Creates a thread that executes the given function proc(param).
  5. ; Returns -1 on error, TID otherwise.
  6. ; If proc(param) returns, the returned value is passed to exit_thread().
  7. ; If stack_size is zero, uses the value from PE header of the executable.
  8. proc create_thread stdcall uses ebx, thread_proc, param, stack_size
  9. ; 1. Determine stack size.
  10. ; Align stack_size up to page boundary;
  11.         mov     ecx, [stack_size]
  12.         add     ecx, 0xFFF
  13.         and     ecx, not 0xFFF
  14.         jnz     .stack_size_ok
  15. ; if this results in zero, read the value from the header of main module.
  16.         mov     eax, [modules_list + MODULE.next]
  17.         mov     eax, [eax + MODULE.base]
  18.         mov     ecx, [eax+STRIPPED_PE_HEADER.SizeOfStackReserve]
  19.         cmp     byte [eax], 'M'
  20.         jnz     .stack_size_ok
  21.         mov     ecx, [eax+3Ch]
  22.         mov     ecx, [eax+ecx+IMAGE_NT_HEADERS.OptionalHeader.SizeOfStackReserve]
  23. .stack_size_ok:
  24.         mov     [stack_size], ecx
  25. ; 2. Allocate the stack.
  26.         mov     eax, 68
  27.         mov     ebx, 12
  28.         call    FS_SYSCALL_PTR
  29.         test    eax, eax
  30.         jz      .fail
  31. ; 3. Copy parameters to the stack.
  32.         lea     edx, [eax+ecx-16]
  33.         mov     [edx], ecx
  34.         mov     ebx, FS_SYSCALL_PTR
  35.         mov     [edx+4], ebx
  36.         mov     ebx, [thread_proc]
  37.         mov     [edx+8], ebx
  38.         mov     ebx, [param]
  39.         mov     [edx+12], ebx
  40. ; 4. Call the kernel to create the thread.
  41.         mov     eax, 51
  42.         mov     ebx, 1
  43.         mov     ecx, internal_thread_start
  44.         call    FS_SYSCALL_PTR
  45.         cmp     eax, -1
  46.         jz      .fail_free
  47.         ret
  48. .fail_free:
  49.         mov     eax, 68
  50.         mov     ebx, 13
  51.         lea     ecx, [edx+12]
  52.         sub     ecx, [stack_size]
  53.         call    FS_SYSCALL_PTR
  54.         xor     eax, eax
  55. .fail:
  56.         dec     eax
  57.         ret
  58. endp
  59.  
  60. ; void exit_thread(int exit_code)
  61. ; Terminates the current thread.
  62. ; exit_code is reserved; currently ignored
  63. proc exit_thread stdcall, exit_code
  64. ; Use int 0x40 instead of call FS_SYSCALL_PTR, because we are freeing the stack.
  65.         mov     eax, 68
  66.         mov     ebx, 13
  67.         mov     ecx, FS_STACK_MIN
  68.         int     0x40
  69.         or      eax, -1
  70.         int     0x40
  71. endp
  72.  
  73. ; Real entry point of threads created by create_thread.
  74. ; Provides user-space initialization of the thread,
  75. ; calls user-provided thread routine,
  76. ; passes the returned value to exit_thread.
  77. proc internal_thread_start
  78.         pop     eax     ; stack_size
  79.         lea     ecx, [esp+12]
  80.         mov     FS_STACK_MAX, ecx
  81.         sub     ecx, eax
  82.         mov     FS_STACK_MIN, ecx
  83.         pop     FS_SYSCALL_PTR ; from caller's FS_SYSCALL_PTR
  84.         pop     eax     ; thread_proc
  85.         call    eax     ; param is still on the stack
  86.         push    eax     ; exit_code
  87.         push    0       ; no return address
  88.         jmp     exit_thread
  89. endp
  90.