Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6811 clevermous 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
6812 clevermous 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
6811 clevermous 69
        or      eax, -1
6812 clevermous 70
        int     0x40
6811 clevermous 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