Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
c168fd06
Commit
c168fd06
authored
Aug 08, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move fiber functions to kernelbase.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
296da1fb
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
442 additions
and
464 deletions
+442
-464
Makefile.in
dlls/kernel32/Makefile.in
+0
-1
fiber.c
dlls/kernel32/fiber.c
+0
-438
kernel32.spec
dlls/kernel32/kernel32.spec
+12
-12
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+12
-12
thread.c
dlls/kernelbase/thread.c
+418
-1
No files found.
dlls/kernel32/Makefile.in
View file @
c168fd06
...
...
@@ -17,7 +17,6 @@ C_SRCS = \
editline.c
\
environ.c
\
except.c
\
fiber.c
\
file.c
\
format_msg.c
\
heap.c
\
...
...
dlls/kernel32/fiber.c
deleted
100644 → 0
View file @
296da1fb
/*
* Fiber support
*
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* FIXME:
* - proper handling of 16-bit stack and signal stack
*/
#include "config.h"
#include <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "wine/exception.h"
#include "wine/asm.h"
struct
fiber_data
{
LPVOID
param
;
/* 00/00 fiber param */
void
*
except
;
/* 04/08 saved exception handlers list */
void
*
stack_base
;
/* 08/10 top of fiber stack */
void
*
stack_limit
;
/* 0c/18 fiber stack low-water mark */
void
*
stack_allocation
;
/* 10/20 base of the fiber stack allocation */
CONTEXT
context
;
/* 14/30 fiber context */
DWORD
flags
;
/* fiber flags */
LPFIBER_START_ROUTINE
start
;
/* start routine */
void
**
fls_slots
;
/* fiber storage slots */
};
extern
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
);
#ifdef __i386__
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movl 4(%esp),%ecx
\n\t
"
/* old */
"movl %edi,0x9c(%ecx)
\n\t
"
/* old->Edi */
"movl %esi,0xa0(%ecx)
\n\t
"
/* old->Esi */
"movl %ebx,0xa4(%ecx)
\n\t
"
/* old->Ebx */
"movl %ebp,0xb4(%ecx)
\n\t
"
/* old->Ebp */
"movl 0(%esp),%eax
\n\t
"
"movl %eax,0xb8(%ecx)
\n\t
"
/* old->Eip */
"leal 12(%esp),%eax
\n\t
"
"movl %eax,0xc4(%ecx)
\n\t
"
/* old->Esp */
"movl 8(%esp),%ecx
\n\t
"
/* new */
"movl 0x9c(%ecx),%edi
\n\t
"
/* new->Edi */
"movl 0xa0(%ecx),%esi
\n\t
"
/* new->Esi */
"movl 0xa4(%ecx),%ebx
\n\t
"
/* new->Ebx */
"movl 0xb4(%ecx),%ebp
\n\t
"
/* new->Ebp */
"movl 0xc4(%ecx),%esp
\n\t
"
/* new->Esp */
"jmp *0xb8(%ecx)"
)
/* new->Eip */
#elif defined(__x86_64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movq %rbx,0x90(%rcx)
\n\t
"
/* old->Rbx */
"leaq 0x8(%rsp),%rax
\n\t
"
"movq %rax,0x98(%rcx)
\n\t
"
/* old->Rsp */
"movq %rbp,0xa0(%rcx)
\n\t
"
/* old->Rbp */
"movq %rsi,0xa8(%rcx)
\n\t
"
/* old->Rsi */
"movq %rdi,0xb0(%rcx)
\n\t
"
/* old->Rdi */
"movq %r12,0xd8(%rcx)
\n\t
"
/* old->R12 */
"movq %r13,0xe0(%rcx)
\n\t
"
/* old->R13 */
"movq %r14,0xe8(%rcx)
\n\t
"
/* old->R14 */
"movq %r15,0xf0(%rcx)
\n\t
"
/* old->R15 */
"movq (%rsp),%rax
\n\t
"
"movq %rax,0xf8(%rcx)
\n\t
"
/* old->Rip */
"movdqa %xmm6,0x200(%rcx)
\n\t
"
/* old->Xmm6 */
"movdqa %xmm7,0x210(%rcx)
\n\t
"
/* old->Xmm7 */
"movdqa %xmm8,0x220(%rcx)
\n\t
"
/* old->Xmm8 */
"movdqa %xmm9,0x230(%rcx)
\n\t
"
/* old->Xmm9 */
"movdqa %xmm10,0x240(%rcx)
\n\t
"
/* old->Xmm10 */
"movdqa %xmm11,0x250(%rcx)
\n\t
"
/* old->Xmm11 */
"movdqa %xmm12,0x260(%rcx)
\n\t
"
/* old->Xmm12 */
"movdqa %xmm13,0x270(%rcx)
\n\t
"
/* old->Xmm13 */
"movdqa %xmm14,0x280(%rcx)
\n\t
"
/* old->Xmm14 */
"movdqa %xmm15,0x290(%rcx)
\n\t
"
/* old->Xmm15 */
"movq 0x90(%rdx),%rbx
\n\t
"
/* new->Rbx */
"movq 0xa0(%rdx),%rbp
\n\t
"
/* new->Rbp */
"movq 0xa8(%rdx),%rsi
\n\t
"
/* new->Rsi */
"movq 0xb0(%rdx),%rdi
\n\t
"
/* new->Rdi */
"movq 0xd8(%rdx),%r12
\n\t
"
/* new->R12 */
"movq 0xe0(%rdx),%r13
\n\t
"
/* new->R13 */
"movq 0xe8(%rdx),%r14
\n\t
"
/* new->R14 */
"movq 0xf0(%rdx),%r15
\n\t
"
/* new->R15 */
"movdqa 0x200(%rdx),%xmm6
\n\t
"
/* new->Xmm6 */
"movdqa 0x210(%rdx),%xmm7
\n\t
"
/* new->Xmm7 */
"movdqa 0x220(%rdx),%xmm8
\n\t
"
/* new->Xmm8 */
"movdqa 0x230(%rdx),%xmm9
\n\t
"
/* new->Xmm9 */
"movdqa 0x240(%rdx),%xmm10
\n\t
"
/* new->Xmm10 */
"movdqa 0x250(%rdx),%xmm11
\n\t
"
/* new->Xmm11 */
"movdqa 0x260(%rdx),%xmm12
\n\t
"
/* new->Xmm12 */
"movdqa 0x270(%rdx),%xmm13
\n\t
"
/* new->Xmm13 */
"movdqa 0x280(%rdx),%xmm14
\n\t
"
/* new->Xmm14 */
"movdqa 0x290(%rdx),%xmm15
\n\t
"
/* new->Xmm15 */
"movq 0x98(%rdx),%rsp
\n\t
"
/* new->Rsp */
"jmp *0xf8(%rdx)"
)
/* new->Rip */
#elif defined(__arm__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"str r4, [r0, #0x14]
\n\t
"
/* old->R4 */
"str r5, [r0, #0x18]
\n\t
"
/* old->R5 */
"str r6, [r0, #0x1c]
\n\t
"
/* old->R6 */
"str r7, [r0, #0x20]
\n\t
"
/* old->R7 */
"str r8, [r0, #0x24]
\n\t
"
/* old->R8 */
"str r9, [r0, #0x28]
\n\t
"
/* old->R9 */
"str r10, [r0, #0x2c]
\n\t
"
/* old->R10 */
"str r11, [r0, #0x30]
\n\t
"
/* old->R11 */
"str sp, [r0, #0x38]
\n\t
"
/* old->Sp */
"str lr, [r0, #0x40]
\n\t
"
/* old->Pc */
"ldr r4, [r1, #0x14]
\n\t
"
/* new->R4 */
"ldr r5, [r1, #0x18]
\n\t
"
/* new->R5 */
"ldr r6, [r1, #0x1c]
\n\t
"
/* new->R6 */
"ldr r7, [r1, #0x20]
\n\t
"
/* new->R7 */
"ldr r8, [r1, #0x24]
\n\t
"
/* new->R8 */
"ldr r9, [r1, #0x28]
\n\t
"
/* new->R9 */
"ldr r10, [r1, #0x2c]
\n\t
"
/* new->R10 */
"ldr r11, [r1, #0x30]
\n\t
"
/* new->R11 */
"ldr sp, [r1, #0x38]
\n\t
"
/* new->Sp */
"ldr r2, [r1, #0x40]
\n\t
"
/* new->Pc */
"bx r2"
)
#elif defined(__aarch64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"stp x19, x20, [x0, #0xa0]
\n\t
"
/* old->X19,X20 */
"stp x21, x22, [x0, #0xb0]
\n\t
"
/* old->X21,X22 */
"stp x23, x24, [x0, #0xc0]
\n\t
"
/* old->X23,X24 */
"stp x25, x26, [x0, #0xd0]
\n\t
"
/* old->X25,X26 */
"stp x27, x28, [x0, #0xe0]
\n\t
"
/* old->X27,X28 */
"str x29, [x0, #0xf0]
\n\t
"
/* old->Fp */
"mov x2, sp
\n\t
"
"str x2, [x0, #0x100]
\n\t
"
/* old->Sp */
"str x30, [x0, #0x108]
\n\t
"
/* old->Pc */
"ldp x19, x20, [x1, #0xa0]
\n\t
"
/* new->X19,X20 */
"ldp x21, x22, [x1, #0xb0]
\n\t
"
/* new->X21,X22 */
"ldp x23, x24, [x1, #0xc0]
\n\t
"
/* new->X23,X24 */
"ldp x25, x26, [x1, #0xd0]
\n\t
"
/* new->X25,X26 */
"ldp x27, x28, [x1, #0xe0]
\n\t
"
/* new->X27,X28 */
"ldr x29, [x1, #0xf0]
\n\t
"
/* new->Fp */
"ldr x2, [x1, #0x100]
\n\t
"
/* new->Sp */
"ldr x30, [x1, #0x108]
\n\t
"
/* new->Pc */
"mov sp, x2
\n\t
"
"ret"
)
#else
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
)
{
DbgBreakPoint
();
}
#endif
/* call the fiber initial function once we have switched stack */
static
void
CDECL
start_fiber
(
void
)
{
struct
fiber_data
*
fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
LPFIBER_START_ROUTINE
start
=
fiber
->
start
;
__TRY
{
start
(
fiber
->
param
);
ExitThread
(
1
);
}
__EXCEPT
(
UnhandledExceptionFilter
)
{
TerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
}
static
void
init_fiber_context
(
struct
fiber_data
*
fiber
)
{
#ifdef __i386__
fiber
->
context
.
Esp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
4
;
fiber
->
context
.
Eip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__x86_64__)
fiber
->
context
.
Rsp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
0x28
;
fiber
->
context
.
Rip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__arm__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__aarch64__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#endif
}
/***********************************************************************
* CreateFiber (KERNEL32.@)
*/
LPVOID
WINAPI
CreateFiber
(
SIZE_T
stack
,
LPFIBER_START_ROUTINE
start
,
LPVOID
param
)
{
return
CreateFiberEx
(
stack
,
0
,
0
,
start
,
param
);
}
/***********************************************************************
* CreateFiberEx (KERNEL32.@)
*/
LPVOID
WINAPI
CreateFiberEx
(
SIZE_T
stack_commit
,
SIZE_T
stack_reserve
,
DWORD
flags
,
LPFIBER_START_ROUTINE
start
,
LPVOID
param
)
{
struct
fiber_data
*
fiber
;
INITIAL_TEB
stack
;
NTSTATUS
status
;
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
fiber
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
}
if
((
status
=
RtlCreateUserStack
(
stack_commit
,
stack_reserve
,
0
,
1
,
1
,
&
stack
)))
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
NULL
;
}
fiber
->
stack_allocation
=
stack
.
DeallocationStack
;
fiber
->
stack_base
=
stack
.
StackBase
;
fiber
->
stack_limit
=
stack
.
StackLimit
;
fiber
->
param
=
param
;
fiber
->
except
=
(
void
*
)
-
1
;
fiber
->
start
=
start
;
fiber
->
flags
=
flags
;
init_fiber_context
(
fiber
);
return
fiber
;
}
/***********************************************************************
* DeleteFiber (KERNEL32.@)
*/
void
WINAPI
DeleteFiber
(
LPVOID
fiber_ptr
)
{
struct
fiber_data
*
fiber
=
fiber_ptr
;
if
(
!
fiber
)
return
;
if
(
fiber
==
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
)
{
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
ExitThread
(
1
);
}
RtlFreeUserStack
(
fiber
->
stack_allocation
);
HeapFree
(
GetProcessHeap
(),
0
,
fiber
->
fls_slots
);
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
}
/***********************************************************************
* ConvertThreadToFiber (KERNEL32.@)
*/
LPVOID
WINAPI
ConvertThreadToFiber
(
LPVOID
param
)
{
return
ConvertThreadToFiberEx
(
param
,
0
);
}
/***********************************************************************
* ConvertThreadToFiberEx (KERNEL32.@)
*/
LPVOID
WINAPI
ConvertThreadToFiberEx
(
LPVOID
param
,
DWORD
flags
)
{
struct
fiber_data
*
fiber
;
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
fiber
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
}
fiber
->
param
=
param
;
fiber
->
except
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
fiber
->
stack_base
=
NtCurrentTeb
()
->
Tib
.
StackBase
;
fiber
->
stack_limit
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
fiber
->
stack_allocation
=
NtCurrentTeb
()
->
DeallocationStack
;
fiber
->
start
=
NULL
;
fiber
->
flags
=
flags
;
fiber
->
fls_slots
=
NtCurrentTeb
()
->
FlsSlots
;
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
fiber
;
return
fiber
;
}
/***********************************************************************
* ConvertFiberToThread (KERNEL32.@)
*/
BOOL
WINAPI
ConvertFiberToThread
(
void
)
{
struct
fiber_data
*
fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
if
(
fiber
)
{
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
NULL
;
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
}
return
TRUE
;
}
/***********************************************************************
* SwitchToFiber (KERNEL32.@)
*/
void
WINAPI
SwitchToFiber
(
LPVOID
fiber
)
{
struct
fiber_data
*
new_fiber
=
fiber
;
struct
fiber_data
*
current_fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
current_fiber
->
except
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
current_fiber
->
stack_limit
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
current_fiber
->
fls_slots
=
NtCurrentTeb
()
->
FlsSlots
;
/* stack_allocation and stack_base never change */
/* FIXME: should save floating point context if requested in fiber->flags */
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
new_fiber
;
NtCurrentTeb
()
->
Tib
.
ExceptionList
=
new_fiber
->
except
;
NtCurrentTeb
()
->
Tib
.
StackBase
=
new_fiber
->
stack_base
;
NtCurrentTeb
()
->
Tib
.
StackLimit
=
new_fiber
->
stack_limit
;
NtCurrentTeb
()
->
DeallocationStack
=
new_fiber
->
stack_allocation
;
NtCurrentTeb
()
->
FlsSlots
=
new_fiber
->
fls_slots
;
switch_fiber
(
&
current_fiber
->
context
,
&
new_fiber
->
context
);
}
/***********************************************************************
* FlsAlloc (KERNEL32.@)
*/
DWORD
WINAPI
FlsAlloc
(
PFLS_CALLBACK_FUNCTION
callback
)
{
DWORD
index
;
PEB
*
const
peb
=
NtCurrentTeb
()
->
Peb
;
RtlAcquirePebLock
();
if
(
!
peb
->
FlsCallback
&&
!
(
peb
->
FlsCallback
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
index
=
FLS_OUT_OF_INDEXES
;
}
else
{
index
=
RtlFindClearBitsAndSet
(
peb
->
FlsBitmap
,
1
,
1
);
if
(
index
!=
~
0U
)
{
if
(
!
NtCurrentTeb
()
->
FlsSlots
&&
!
(
NtCurrentTeb
()
->
FlsSlots
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
RtlClearBits
(
peb
->
FlsBitmap
,
index
,
1
);
index
=
FLS_OUT_OF_INDEXES
;
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
}
else
{
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
0
;
/* clear the value */
peb
->
FlsCallback
[
index
]
=
callback
;
}
}
else
SetLastError
(
ERROR_NO_MORE_ITEMS
);
}
RtlReleasePebLock
();
return
index
;
}
/***********************************************************************
* FlsFree (KERNEL32.@)
*/
BOOL
WINAPI
FlsFree
(
DWORD
index
)
{
BOOL
ret
;
RtlAcquirePebLock
();
ret
=
RtlAreBitsSet
(
NtCurrentTeb
()
->
Peb
->
FlsBitmap
,
index
,
1
);
if
(
ret
)
RtlClearBits
(
NtCurrentTeb
()
->
Peb
->
FlsBitmap
,
index
,
1
);
if
(
ret
)
{
/* FIXME: call Fls callback */
/* FIXME: add equivalent of ThreadZeroTlsCell here */
if
(
NtCurrentTeb
()
->
FlsSlots
)
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
0
;
}
else
SetLastError
(
ERROR_INVALID_PARAMETER
);
RtlReleasePebLock
();
return
ret
;
}
/***********************************************************************
* FlsGetValue (KERNEL32.@)
*/
PVOID
WINAPI
FlsGetValue
(
DWORD
index
)
{
if
(
!
index
||
index
>=
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
)
||
!
NtCurrentTeb
()
->
FlsSlots
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
SetLastError
(
ERROR_SUCCESS
);
return
NtCurrentTeb
()
->
FlsSlots
[
index
];
}
/***********************************************************************
* FlsSetValue (KERNEL32.@)
*/
BOOL
WINAPI
FlsSetValue
(
DWORD
index
,
PVOID
data
)
{
if
(
!
index
||
index
>=
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
if
(
!
NtCurrentTeb
()
->
FlsSlots
&&
!
(
NtCurrentTeb
()
->
FlsSlots
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
data
;
return
TRUE
;
}
/***********************************************************************
* IsThreadAFiber (KERNEL32.@)
*/
BOOL
WINAPI
IsThreadAFiber
(
void
)
{
return
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
!=
NULL
;
}
dlls/kernel32/kernel32.spec
View file @
c168fd06
...
...
@@ -249,11 +249,11 @@
@ stdcall ContinueDebugEvent(long long long)
# @ stub ConvertCalDateTimeToSystemTime
@ stdcall ConvertDefaultLocale (long)
@ stdcall ConvertFiberToThread()
@ stdcall
-import
ConvertFiberToThread()
# @ stub ConvertNLSDayOfWeekToWin32DayOfWeek
# @ stub ConvertSystemTimeToCalDateTime
@ stdcall ConvertThreadToFiber(ptr)
@ stdcall ConvertThreadToFiberEx(ptr long)
@ stdcall
-import
ConvertThreadToFiber(ptr)
@ stdcall
-import
ConvertThreadToFiberEx(ptr long)
@ stdcall ConvertToGlobalHandle(long)
# @ stub CopyContext
@ stdcall CopyFileA(str str long)
...
...
@@ -278,8 +278,8 @@
@ stdcall -import CreateEventExA(ptr str long long)
@ stdcall -import CreateEventExW(ptr wstr long long)
@ stdcall -import CreateEventW(ptr long long wstr)
@ stdcall CreateFiber(long ptr ptr)
@ stdcall CreateFiberEx(long long long ptr ptr)
@ stdcall
-import
CreateFiber(long ptr ptr)
@ stdcall
-import
CreateFiberEx(long long long ptr ptr)
@ stdcall CreateFile2(wstr long long long ptr)
@ stdcall CreateFileA(str long long ptr long long long)
@ stdcall CreateFileMappingA(long ptr long long long str)
...
...
@@ -360,7 +360,7 @@
@ stdcall DeleteAtom(long)
# @ stub DeleteBoundaryDescriptor
@ stdcall DeleteCriticalSection(ptr) ntdll.RtlDeleteCriticalSection
@ stdcall DeleteFiber(ptr)
@ stdcall
-import
DeleteFiber(ptr)
@ stdcall DeleteFileA(str)
# @ stub DeleteFileTransactedA
# @ stub DeleteFileTransactedW
...
...
@@ -511,10 +511,10 @@
@ stdcall FindStringOrdinal(long wstr long wstr long long)
@ stdcall FindVolumeClose(ptr)
@ stdcall FindVolumeMountPointClose(ptr)
@ stdcall FlsAlloc(ptr)
@ stdcall FlsFree(long)
@ stdcall FlsGetValue(long)
@ stdcall FlsSetValue(long ptr)
@ stdcall
-import
FlsAlloc(ptr)
@ stdcall
-import
FlsFree(long)
@ stdcall
-import
FlsGetValue(long)
@ stdcall
-import
FlsSetValue(long ptr)
@ stdcall FlushConsoleInputBuffer(long)
@ stdcall FlushFileBuffers(long)
@ stdcall FlushInstructionCache(long long long)
...
...
@@ -985,7 +985,7 @@
@ stdcall IsProcessorFeaturePresent(long)
@ stub -i386 IsSLCallback
@ stdcall IsSystemResumeAutomatic()
@ stdcall IsThreadAFiber()
@ stdcall
-import
IsThreadAFiber()
@ stdcall IsThreadpoolTimerSet(ptr) ntdll.TpIsTimerSet
# @ stub IsTimeZoneRedirectionEnabled
# @ stub IsValidCalDateTime
...
...
@@ -1490,7 +1490,7 @@
# @ stub StartThreadpoolIo
@ stdcall SubmitThreadpoolWork(ptr) ntdll.TpPostWork
@ stdcall -import SuspendThread(long)
@ stdcall SwitchToFiber(ptr)
@ stdcall
-import
SwitchToFiber(ptr)
@ stdcall -import SwitchToThread()
@ stdcall SystemTimeToFileTime(ptr ptr)
@ stdcall SystemTimeToTzSpecificLocalTime (ptr ptr ptr)
...
...
dlls/kernelbase/kernelbase.spec
View file @
c168fd06
...
...
@@ -160,9 +160,9 @@
@ stdcall ConnectNamedPipe(long ptr)
@ stdcall ContinueDebugEvent(long long long) kernel32.ContinueDebugEvent
@ stdcall ConvertDefaultLocale(long) kernel32.ConvertDefaultLocale
@ stdcall ConvertFiberToThread()
kernel32.ConvertFiberToThread
@ stdcall ConvertThreadToFiber(ptr)
kernel32.ConvertThreadToFiber
@ stdcall ConvertThreadToFiberEx(ptr long)
kernel32.ConvertThreadToFiberEx
@ stdcall ConvertFiberToThread()
@ stdcall ConvertThreadToFiber(ptr)
@ stdcall ConvertThreadToFiberEx(ptr long)
@ stdcall ConvertToAutoInheritPrivateObjectSecurity(ptr ptr ptr ptr long ptr)
# @ stub CopyContext
# @ stub CopyFile2
...
...
@@ -183,8 +183,8 @@
@ stdcall CreateEventExA(ptr str long long)
@ stdcall CreateEventExW(ptr wstr long long)
@ stdcall CreateEventW(ptr long long wstr)
@ stdcall CreateFiber(long ptr ptr)
kernel32.CreateFiber
@ stdcall CreateFiberEx(long long long ptr ptr)
kernel32.CreateFiberEx
@ stdcall CreateFiber(long ptr ptr)
@ stdcall CreateFiberEx(long long long ptr ptr)
@ stdcall CreateFile2(wstr long long long ptr) kernel32.CreateFile2
@ stdcall CreateFileA(str long long ptr long long long) kernel32.CreateFileA
# @ stub CreateFileMappingFromApp
...
...
@@ -249,7 +249,7 @@
@ stdcall DeleteAce(ptr long)
# @ stub DeleteBoundaryDescriptor
@ stdcall DeleteCriticalSection(ptr) ntdll.RtlDeleteCriticalSection
@ stdcall DeleteFiber(ptr)
kernel32.DeleteFiber
@ stdcall DeleteFiber(ptr)
@ stdcall DeleteFileA(str) kernel32.DeleteFileA
@ stdcall DeleteFileW(wstr) kernel32.DeleteFileW
@ stdcall DeleteProcThreadAttributeList(ptr) kernel32.DeleteProcThreadAttributeList
...
...
@@ -375,10 +375,10 @@
@ stdcall FindResourceW(long wstr wstr)
@ stdcall FindStringOrdinal(long wstr long wstr long long) kernel32.FindStringOrdinal
@ stdcall FindVolumeClose(ptr) kernel32.FindVolumeClose
@ stdcall FlsAlloc(ptr)
kernel32.FlsAlloc
@ stdcall FlsFree(long)
kernel32.FlsFree
@ stdcall FlsGetValue(long)
kernel32.FlsGetValue
@ stdcall FlsSetValue(long ptr)
kernel32.FlsSetValue
@ stdcall FlsAlloc(ptr)
@ stdcall FlsFree(long)
@ stdcall FlsGetValue(long)
@ stdcall FlsSetValue(long ptr)
@ stdcall FlushConsoleInputBuffer(long) kernel32.FlushConsoleInputBuffer
@ stdcall FlushFileBuffers(long) kernel32.FlushFileBuffers
@ stdcall FlushInstructionCache(long long long) kernel32.FlushInstructionCache
...
...
@@ -870,7 +870,7 @@
# @ stub IsSideloadingEnabled
# @ stub IsSideloadingPolicyApplied
# @ stub IsSyncForegroundPolicyRefresh
@ stdcall IsThreadAFiber()
kernel32.IsThreadAFiber
@ stdcall IsThreadAFiber()
@ stdcall IsThreadpoolTimerSet(ptr) ntdll.TpIsTimerSet
# @ stub IsTimeZoneRedirectionEnabled
@ stdcall IsTokenRestricted(long)
...
...
@@ -1589,7 +1589,7 @@
# @ stub SubscribeEdpEnabledStateChange
# @ stub SubscribeStateChangeNotification
@ stdcall SuspendThread(long)
@ stdcall SwitchToFiber(ptr)
kernel32.SwitchToFiber
@ stdcall SwitchToFiber(ptr)
@ stdcall SwitchToThread()
@ stdcall SystemTimeToFileTime(ptr ptr) kernel32.SystemTimeToFileTime
@ stdcall SystemTimeToTzSpecificLocalTime(ptr ptr ptr) kernel32.SystemTimeToTzSpecificLocalTime
...
...
dlls/kernelbase/thread.c
View file @
c168fd06
/*
* Win32 threads
*
* Copyright 1996 Alexandre Julliard
* Copyright 1996
, 2002, 2019
Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -29,6 +29,8 @@
#include "winternl.h"
#include "kernelbase.h"
#include "wine/exception.h"
#include "wine/asm.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
thread
);
...
...
@@ -496,6 +498,421 @@ BOOL WINAPI DECLSPEC_HOTPATCH TerminateThread( HANDLE handle, DWORD exit_code )
/***********************************************************************
* Fibers
***********************************************************************/
struct
fiber_data
{
LPVOID
param
;
/* 00/00 fiber param */
void
*
except
;
/* 04/08 saved exception handlers list */
void
*
stack_base
;
/* 08/10 top of fiber stack */
void
*
stack_limit
;
/* 0c/18 fiber stack low-water mark */
void
*
stack_allocation
;
/* 10/20 base of the fiber stack allocation */
CONTEXT
context
;
/* 14/30 fiber context */
DWORD
flags
;
/* fiber flags */
LPFIBER_START_ROUTINE
start
;
/* start routine */
void
**
fls_slots
;
/* fiber storage slots */
};
extern
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
);
#ifdef __i386__
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movl 4(%esp),%ecx
\n\t
"
/* old */
"movl %edi,0x9c(%ecx)
\n\t
"
/* old->Edi */
"movl %esi,0xa0(%ecx)
\n\t
"
/* old->Esi */
"movl %ebx,0xa4(%ecx)
\n\t
"
/* old->Ebx */
"movl %ebp,0xb4(%ecx)
\n\t
"
/* old->Ebp */
"movl 0(%esp),%eax
\n\t
"
"movl %eax,0xb8(%ecx)
\n\t
"
/* old->Eip */
"leal 12(%esp),%eax
\n\t
"
"movl %eax,0xc4(%ecx)
\n\t
"
/* old->Esp */
"movl 8(%esp),%ecx
\n\t
"
/* new */
"movl 0x9c(%ecx),%edi
\n\t
"
/* new->Edi */
"movl 0xa0(%ecx),%esi
\n\t
"
/* new->Esi */
"movl 0xa4(%ecx),%ebx
\n\t
"
/* new->Ebx */
"movl 0xb4(%ecx),%ebp
\n\t
"
/* new->Ebp */
"movl 0xc4(%ecx),%esp
\n\t
"
/* new->Esp */
"jmp *0xb8(%ecx)"
)
/* new->Eip */
#elif defined(__x86_64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"movq %rbx,0x90(%rcx)
\n\t
"
/* old->Rbx */
"leaq 0x8(%rsp),%rax
\n\t
"
"movq %rax,0x98(%rcx)
\n\t
"
/* old->Rsp */
"movq %rbp,0xa0(%rcx)
\n\t
"
/* old->Rbp */
"movq %rsi,0xa8(%rcx)
\n\t
"
/* old->Rsi */
"movq %rdi,0xb0(%rcx)
\n\t
"
/* old->Rdi */
"movq %r12,0xd8(%rcx)
\n\t
"
/* old->R12 */
"movq %r13,0xe0(%rcx)
\n\t
"
/* old->R13 */
"movq %r14,0xe8(%rcx)
\n\t
"
/* old->R14 */
"movq %r15,0xf0(%rcx)
\n\t
"
/* old->R15 */
"movq (%rsp),%rax
\n\t
"
"movq %rax,0xf8(%rcx)
\n\t
"
/* old->Rip */
"movdqa %xmm6,0x200(%rcx)
\n\t
"
/* old->Xmm6 */
"movdqa %xmm7,0x210(%rcx)
\n\t
"
/* old->Xmm7 */
"movdqa %xmm8,0x220(%rcx)
\n\t
"
/* old->Xmm8 */
"movdqa %xmm9,0x230(%rcx)
\n\t
"
/* old->Xmm9 */
"movdqa %xmm10,0x240(%rcx)
\n\t
"
/* old->Xmm10 */
"movdqa %xmm11,0x250(%rcx)
\n\t
"
/* old->Xmm11 */
"movdqa %xmm12,0x260(%rcx)
\n\t
"
/* old->Xmm12 */
"movdqa %xmm13,0x270(%rcx)
\n\t
"
/* old->Xmm13 */
"movdqa %xmm14,0x280(%rcx)
\n\t
"
/* old->Xmm14 */
"movdqa %xmm15,0x290(%rcx)
\n\t
"
/* old->Xmm15 */
"movq 0x90(%rdx),%rbx
\n\t
"
/* new->Rbx */
"movq 0xa0(%rdx),%rbp
\n\t
"
/* new->Rbp */
"movq 0xa8(%rdx),%rsi
\n\t
"
/* new->Rsi */
"movq 0xb0(%rdx),%rdi
\n\t
"
/* new->Rdi */
"movq 0xd8(%rdx),%r12
\n\t
"
/* new->R12 */
"movq 0xe0(%rdx),%r13
\n\t
"
/* new->R13 */
"movq 0xe8(%rdx),%r14
\n\t
"
/* new->R14 */
"movq 0xf0(%rdx),%r15
\n\t
"
/* new->R15 */
"movdqa 0x200(%rdx),%xmm6
\n\t
"
/* new->Xmm6 */
"movdqa 0x210(%rdx),%xmm7
\n\t
"
/* new->Xmm7 */
"movdqa 0x220(%rdx),%xmm8
\n\t
"
/* new->Xmm8 */
"movdqa 0x230(%rdx),%xmm9
\n\t
"
/* new->Xmm9 */
"movdqa 0x240(%rdx),%xmm10
\n\t
"
/* new->Xmm10 */
"movdqa 0x250(%rdx),%xmm11
\n\t
"
/* new->Xmm11 */
"movdqa 0x260(%rdx),%xmm12
\n\t
"
/* new->Xmm12 */
"movdqa 0x270(%rdx),%xmm13
\n\t
"
/* new->Xmm13 */
"movdqa 0x280(%rdx),%xmm14
\n\t
"
/* new->Xmm14 */
"movdqa 0x290(%rdx),%xmm15
\n\t
"
/* new->Xmm15 */
"movq 0x98(%rdx),%rsp
\n\t
"
/* new->Rsp */
"jmp *0xf8(%rdx)"
)
/* new->Rip */
#elif defined(__arm__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"str r4, [r0, #0x14]
\n\t
"
/* old->R4 */
"str r5, [r0, #0x18]
\n\t
"
/* old->R5 */
"str r6, [r0, #0x1c]
\n\t
"
/* old->R6 */
"str r7, [r0, #0x20]
\n\t
"
/* old->R7 */
"str r8, [r0, #0x24]
\n\t
"
/* old->R8 */
"str r9, [r0, #0x28]
\n\t
"
/* old->R9 */
"str r10, [r0, #0x2c]
\n\t
"
/* old->R10 */
"str r11, [r0, #0x30]
\n\t
"
/* old->R11 */
"str sp, [r0, #0x38]
\n\t
"
/* old->Sp */
"str lr, [r0, #0x40]
\n\t
"
/* old->Pc */
"ldr r4, [r1, #0x14]
\n\t
"
/* new->R4 */
"ldr r5, [r1, #0x18]
\n\t
"
/* new->R5 */
"ldr r6, [r1, #0x1c]
\n\t
"
/* new->R6 */
"ldr r7, [r1, #0x20]
\n\t
"
/* new->R7 */
"ldr r8, [r1, #0x24]
\n\t
"
/* new->R8 */
"ldr r9, [r1, #0x28]
\n\t
"
/* new->R9 */
"ldr r10, [r1, #0x2c]
\n\t
"
/* new->R10 */
"ldr r11, [r1, #0x30]
\n\t
"
/* new->R11 */
"ldr sp, [r1, #0x38]
\n\t
"
/* new->Sp */
"ldr r2, [r1, #0x40]
\n\t
"
/* new->Pc */
"bx r2"
)
#elif defined(__aarch64__)
__ASM_STDCALL_FUNC
(
switch_fiber
,
8
,
"stp x19, x20, [x0, #0xa0]
\n\t
"
/* old->X19,X20 */
"stp x21, x22, [x0, #0xb0]
\n\t
"
/* old->X21,X22 */
"stp x23, x24, [x0, #0xc0]
\n\t
"
/* old->X23,X24 */
"stp x25, x26, [x0, #0xd0]
\n\t
"
/* old->X25,X26 */
"stp x27, x28, [x0, #0xe0]
\n\t
"
/* old->X27,X28 */
"str x29, [x0, #0xf0]
\n\t
"
/* old->Fp */
"mov x2, sp
\n\t
"
"str x2, [x0, #0x100]
\n\t
"
/* old->Sp */
"str x30, [x0, #0x108]
\n\t
"
/* old->Pc */
"ldp x19, x20, [x1, #0xa0]
\n\t
"
/* new->X19,X20 */
"ldp x21, x22, [x1, #0xb0]
\n\t
"
/* new->X21,X22 */
"ldp x23, x24, [x1, #0xc0]
\n\t
"
/* new->X23,X24 */
"ldp x25, x26, [x1, #0xd0]
\n\t
"
/* new->X25,X26 */
"ldp x27, x28, [x1, #0xe0]
\n\t
"
/* new->X27,X28 */
"ldr x29, [x1, #0xf0]
\n\t
"
/* new->Fp */
"ldr x2, [x1, #0x100]
\n\t
"
/* new->Sp */
"ldr x30, [x1, #0x108]
\n\t
"
/* new->Pc */
"mov sp, x2
\n\t
"
"ret"
)
#else
void
WINAPI
switch_fiber
(
CONTEXT
*
old
,
CONTEXT
*
new
)
{
FIXME
(
"not implemented
\n
"
);
DbgBreakPoint
();
}
#endif
/* call the fiber initial function once we have switched stack */
static
void
CDECL
start_fiber
(
void
)
{
struct
fiber_data
*
fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
LPFIBER_START_ROUTINE
start
=
fiber
->
start
;
__TRY
{
start
(
fiber
->
param
);
ExitThread
(
1
);
}
__EXCEPT
(
UnhandledExceptionFilter
)
{
TerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
}
static
void
init_fiber_context
(
struct
fiber_data
*
fiber
)
{
#ifdef __i386__
fiber
->
context
.
Esp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
4
;
fiber
->
context
.
Eip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__x86_64__)
fiber
->
context
.
Rsp
=
(
ULONG_PTR
)
fiber
->
stack_base
-
0x28
;
fiber
->
context
.
Rip
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__arm__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#elif defined(__aarch64__)
fiber
->
context
.
Sp
=
(
ULONG_PTR
)
fiber
->
stack_base
;
fiber
->
context
.
Pc
=
(
ULONG_PTR
)
start_fiber
;
#endif
}
/***********************************************************************
* CreateFiber (kernelbase.@)
*/
LPVOID
WINAPI
DECLSPEC_HOTPATCH
CreateFiber
(
SIZE_T
stack
,
LPFIBER_START_ROUTINE
start
,
LPVOID
param
)
{
return
CreateFiberEx
(
stack
,
0
,
0
,
start
,
param
);
}
/***********************************************************************
* CreateFiberEx (kernelbase.@)
*/
LPVOID
WINAPI
DECLSPEC_HOTPATCH
CreateFiberEx
(
SIZE_T
stack_commit
,
SIZE_T
stack_reserve
,
DWORD
flags
,
LPFIBER_START_ROUTINE
start
,
LPVOID
param
)
{
struct
fiber_data
*
fiber
;
INITIAL_TEB
stack
;
NTSTATUS
status
;
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
fiber
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
}
if
((
status
=
RtlCreateUserStack
(
stack_commit
,
stack_reserve
,
0
,
1
,
1
,
&
stack
)))
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
NULL
;
}
fiber
->
stack_allocation
=
stack
.
DeallocationStack
;
fiber
->
stack_base
=
stack
.
StackBase
;
fiber
->
stack_limit
=
stack
.
StackLimit
;
fiber
->
param
=
param
;
fiber
->
except
=
(
void
*
)
-
1
;
fiber
->
start
=
start
;
fiber
->
flags
=
flags
;
init_fiber_context
(
fiber
);
return
fiber
;
}
/***********************************************************************
* ConvertFiberToThread (kernelbase.@)
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
ConvertFiberToThread
(
void
)
{
struct
fiber_data
*
fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
if
(
fiber
)
{
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
NULL
;
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
}
return
TRUE
;
}
/***********************************************************************
* ConvertThreadToFiber (kernelbase.@)
*/
LPVOID
WINAPI
DECLSPEC_HOTPATCH
ConvertThreadToFiber
(
LPVOID
param
)
{
return
ConvertThreadToFiberEx
(
param
,
0
);
}
/***********************************************************************
* ConvertThreadToFiberEx (kernelbase.@)
*/
LPVOID
WINAPI
DECLSPEC_HOTPATCH
ConvertThreadToFiberEx
(
LPVOID
param
,
DWORD
flags
)
{
struct
fiber_data
*
fiber
;
if
(
!
(
fiber
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
fiber
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
}
fiber
->
param
=
param
;
fiber
->
except
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
fiber
->
stack_base
=
NtCurrentTeb
()
->
Tib
.
StackBase
;
fiber
->
stack_limit
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
fiber
->
stack_allocation
=
NtCurrentTeb
()
->
DeallocationStack
;
fiber
->
start
=
NULL
;
fiber
->
flags
=
flags
;
fiber
->
fls_slots
=
NtCurrentTeb
()
->
FlsSlots
;
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
fiber
;
return
fiber
;
}
/***********************************************************************
* DeleteFiber (kernelbase.@)
*/
void
WINAPI
DECLSPEC_HOTPATCH
DeleteFiber
(
LPVOID
fiber_ptr
)
{
struct
fiber_data
*
fiber
=
fiber_ptr
;
if
(
!
fiber
)
return
;
if
(
fiber
==
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
)
{
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
ExitThread
(
1
);
}
RtlFreeUserStack
(
fiber
->
stack_allocation
);
HeapFree
(
GetProcessHeap
(),
0
,
fiber
->
fls_slots
);
HeapFree
(
GetProcessHeap
(),
0
,
fiber
);
}
/***********************************************************************
* IsThreadAFiber (kernelbase.@)
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
IsThreadAFiber
(
void
)
{
return
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
!=
NULL
;
}
/***********************************************************************
* SwitchToFiber (kernelbase.@)
*/
void
WINAPI
DECLSPEC_HOTPATCH
SwitchToFiber
(
LPVOID
fiber
)
{
struct
fiber_data
*
new_fiber
=
fiber
;
struct
fiber_data
*
current_fiber
=
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
;
current_fiber
->
except
=
NtCurrentTeb
()
->
Tib
.
ExceptionList
;
current_fiber
->
stack_limit
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
current_fiber
->
fls_slots
=
NtCurrentTeb
()
->
FlsSlots
;
/* stack_allocation and stack_base never change */
/* FIXME: should save floating point context if requested in fiber->flags */
NtCurrentTeb
()
->
Tib
.
u
.
FiberData
=
new_fiber
;
NtCurrentTeb
()
->
Tib
.
ExceptionList
=
new_fiber
->
except
;
NtCurrentTeb
()
->
Tib
.
StackBase
=
new_fiber
->
stack_base
;
NtCurrentTeb
()
->
Tib
.
StackLimit
=
new_fiber
->
stack_limit
;
NtCurrentTeb
()
->
DeallocationStack
=
new_fiber
->
stack_allocation
;
NtCurrentTeb
()
->
FlsSlots
=
new_fiber
->
fls_slots
;
switch_fiber
(
&
current_fiber
->
context
,
&
new_fiber
->
context
);
}
/***********************************************************************
* FlsAlloc (kernelbase.@)
*/
DWORD
WINAPI
DECLSPEC_HOTPATCH
FlsAlloc
(
PFLS_CALLBACK_FUNCTION
callback
)
{
DWORD
index
;
PEB
*
const
peb
=
NtCurrentTeb
()
->
Peb
;
RtlAcquirePebLock
();
if
(
!
peb
->
FlsCallback
&&
!
(
peb
->
FlsCallback
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
index
=
FLS_OUT_OF_INDEXES
;
}
else
{
index
=
RtlFindClearBitsAndSet
(
peb
->
FlsBitmap
,
1
,
1
);
if
(
index
!=
~
0U
)
{
if
(
!
NtCurrentTeb
()
->
FlsSlots
&&
!
(
NtCurrentTeb
()
->
FlsSlots
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
RtlClearBits
(
peb
->
FlsBitmap
,
index
,
1
);
index
=
FLS_OUT_OF_INDEXES
;
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
}
else
{
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
0
;
/* clear the value */
peb
->
FlsCallback
[
index
]
=
callback
;
}
}
else
SetLastError
(
ERROR_NO_MORE_ITEMS
);
}
RtlReleasePebLock
();
return
index
;
}
/***********************************************************************
* FlsFree (kernelbase.@)
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FlsFree
(
DWORD
index
)
{
BOOL
ret
;
RtlAcquirePebLock
();
ret
=
RtlAreBitsSet
(
NtCurrentTeb
()
->
Peb
->
FlsBitmap
,
index
,
1
);
if
(
ret
)
RtlClearBits
(
NtCurrentTeb
()
->
Peb
->
FlsBitmap
,
index
,
1
);
if
(
ret
)
{
/* FIXME: call Fls callback */
/* FIXME: add equivalent of ThreadZeroTlsCell here */
if
(
NtCurrentTeb
()
->
FlsSlots
)
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
0
;
}
else
SetLastError
(
ERROR_INVALID_PARAMETER
);
RtlReleasePebLock
();
return
ret
;
}
/***********************************************************************
* FlsGetValue (kernelbase.@)
*/
PVOID
WINAPI
DECLSPEC_HOTPATCH
FlsGetValue
(
DWORD
index
)
{
if
(
!
index
||
index
>=
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
)
||
!
NtCurrentTeb
()
->
FlsSlots
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
SetLastError
(
ERROR_SUCCESS
);
return
NtCurrentTeb
()
->
FlsSlots
[
index
];
}
/***********************************************************************
* FlsSetValue (kernelbase.@)
*/
BOOL
WINAPI
DECLSPEC_HOTPATCH
FlsSetValue
(
DWORD
index
,
PVOID
data
)
{
if
(
!
index
||
index
>=
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
if
(
!
NtCurrentTeb
()
->
FlsSlots
&&
!
(
NtCurrentTeb
()
->
FlsSlots
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
8
*
sizeof
(
NtCurrentTeb
()
->
Peb
->
FlsBitmapBits
)
*
sizeof
(
void
*
)
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
NtCurrentTeb
()
->
FlsSlots
[
index
]
=
data
;
return
TRUE
;
}
/***********************************************************************
* Thread pool
***********************************************************************/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment