As requested by Dimitrie, this version of the patch has just one #ifdef block. Alberto Index: dlls/kernel/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/kernel/Makefile.in,v retrieving revision 1.52 diff -u -r1.52 Makefile.in --- dlls/kernel/Makefile.in 11 Dec 2002 01:34:52 -0000 1.52 +++ dlls/kernel/Makefile.in 17 Dec 2002 11:11:46 -0000 @@ -16,6 +16,7 @@ console.c \ debugger.c \ editline.c \ + fiber.c \ format_msg.c \ kernel_main.c \ locale.c \ Index: dlls/kernel/kernel32.spec =================================================================== RCS file: /home/wine/wine/dlls/kernel/kernel32.spec,v retrieving revision 1.85 diff -u -r1.85 kernel32.spec --- dlls/kernel/kernel32.spec 15 Dec 2002 01:22:41 -0000 1.85 +++ dlls/kernel/kernel32.spec 17 Dec 2002 11:11:47 -0000 @@ -182,7 +182,6 @@ @ stdcall ConnectNamedPipe(long ptr) ConnectNamedPipe @ stdcall ContinueDebugEvent(long long long) ContinueDebugEvent @ stdcall ConvertDefaultLocale (long) ConvertDefaultLocale -@ stub ConvertThreadToFiber @ stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle @ stdcall CopyFileA(str str long) CopyFileA @ stdcall CopyFileW(wstr wstr long) CopyFileW @@ -983,10 +982,11 @@ @ stdcall CancelWaitableTimer(long) CancelWaitableTimer @ stdcall CopyFileExA (str str ptr ptr ptr long) CopyFileExA @ stdcall CopyFileExW (wstr wstr ptr ptr ptr long) CopyFileExW -@ stub CreateFiber +@ stdcall ConvertThreadToFiber(ptr) ConvertThreadToFiber +@ stdcall CreateFiber(long ptr ptr) CreateFiber @ stdcall CreateWaitableTimerA(ptr long str) CreateWaitableTimerA @ stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW -@ stub DeleteFiber +@ stdcall DeleteFiber(ptr) DeleteFiber @ stub DuplicateConsoleHandle @ stdcall FindFirstFileExA(str long ptr long ptr long)FindFirstFileExA @ stdcall FindFirstFileExW(wstr long ptr long ptr long)FindFirstFileExW @@ -1018,7 +1018,7 @@ @ stdcall SetThreadPriorityBoost(long long) SetThreadPriorityBoost @ stdcall SetWaitableTimer(long ptr long ptr ptr long) SetWaitableTimer @ stub SignalObjectAndWait -@ stub SwitchToFiber +@ stdcall SwitchToFiber(ptr) SwitchToFiber @ stdcall SwitchToThread() SwitchToThread @ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection @ stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx Index: dlls/kernel/kernel_main.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/kernel_main.c,v retrieving revision 1.39 diff -u -r1.39 kernel_main.c --- dlls/kernel/kernel_main.c 15 Nov 2002 01:01:48 -0000 1.39 +++ dlls/kernel/kernel_main.c 17 Dec 2002 11:11:47 -0000 @@ -41,6 +41,8 @@ #include "wincon.h" #include "console_private.h" +extern DWORD fiber_tls_index; + extern void LOCALE_Init(void); extern BOOL RELAY_Init(void); extern void COMPUTERNAME_Init(void); @@ -137,8 +139,10 @@ switch(reason) { case DLL_PROCESS_ATTACH: + fiber_tls_index=TlsAlloc(); return process_attach(); case DLL_PROCESS_DETACH: + TlsFree(fiber_tls_index); WriteOutProfiles16(); break; } --- /dev/null 1970-01-01 01:00:00.000000000 +0100 +++ dlls/kernel/fiber.c 2002-12-17 12:22:20.000000000 +0100 @@ -0,0 +1,170 @@ +/* + * Fiber code + * + * Copyright 2002 Alberto Massari + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "wine/port.h" + +#include "wine/winbase16.h" +#include "winnt.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(fiber); + +DWORD fiber_tls_index=0; + +#ifdef HAVE_UCONTEXT_H + +#include <ucontext.h> + +typedef struct { + BOOL bDeleteStack; + ucontext_t context; +} HFIBER, *PHFIBER; + +/*********************************************************************** + * ConvertThreadToFiber (KERNEL32.@) + * + * Converts the current thread into a fiber (fibers are just like threads + * but the scheduling is done by the user) + * + */ +LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter) +{ + PHFIBER pFiber; + TRACE("(%p)\n",lpParameter); + pFiber=HeapAlloc( GetProcessHeap(), 0, sizeof(HFIBER) ); + pFiber->bDeleteStack=FALSE; + getcontext(&pFiber->context); + TlsSetValue(fiber_tls_index,pFiber); + return pFiber; +} + +/*********************************************************************** + * CreateFiber (KERNEL32.@) + * + * Creates a new fiber object + * + */ + +typedef void (*contextFn)(); + +LPVOID WINAPI CreateFiber(DWORD dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter) +{ + PHFIBER pFiber; + TRACE("(%ld,%p,%p)\n",dwStackSize,lpStartAddress,lpParameter); + if(dwStackSize==0) + dwStackSize=1024*1024; /* default value is 1Mb */ + pFiber=HeapAlloc( GetProcessHeap(), 0, sizeof(HFIBER) ); + pFiber->bDeleteStack=TRUE; + /* get the current context */ + getcontext(&pFiber->context); + // Modify the context to a new stack + pFiber->context.uc_link=0; + pFiber->context.uc_stack.ss_sp=HeapAlloc( GetProcessHeap(), 0, dwStackSize); + pFiber->context.uc_stack.ss_size=dwStackSize; + pFiber->context.uc_stack.ss_flags=0; + makecontext(&pFiber->context,(contextFn)lpStartAddress,1,lpParameter); + return pFiber; +} + +/*********************************************************************** + * SwitchToFiber (KERNEL32.@) + * + * Schedules a fiber for execution + * + */ +void WINAPI SwitchToFiber(LPVOID lpFiber) +{ + PHFIBER pFiber,pCurrentFiber; + pFiber=(PHFIBER)lpFiber; + pCurrentFiber=(PHFIBER)TlsGetValue(fiber_tls_index); + TRACE("Switching from %p to %p\n",pFiber,pCurrentFiber); + TlsSetValue(fiber_tls_index,pFiber); + swapcontext(&pCurrentFiber->context,&pFiber->context); +} + +/*********************************************************************** + * DeleteFiber (KERNEL32.@) + * + * Deletes a fiber object + * + */ +void WINAPI DeleteFiber(LPVOID lpFiber) +{ + PHFIBER pFiber; + TRACE("(%p)\n",lpFiber); + pFiber=(PHFIBER)lpFiber; + if(pFiber->bDeleteStack) + HeapFree(GetProcessHeap(), 0, pFiber->context.uc_stack.ss_sp); + HeapFree(GetProcessHeap(), 0, pFiber); +} + +#else + +/*********************************************************************** + * ConvertThreadToFiber (KERNEL32.@) + * + * Converts the current thread into a fiber (fibers are just like threads + * but the scheduling is done by the user) + * + */ +LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter) +{ + FIXME("(%p) stub\n",lpParameter); + return NULL; +} + +/*********************************************************************** + * CreateFiber (KERNEL32.@) + * + * Creates a new fiber object + * + */ +LPVOID WINAPI CreateFiber(DWORD dwStackSize, LPFIBER_START_ROUTINE lpStartAddress, LPVOID lpParameter) +{ + FIXME("(%ld, %p, %p) stub\n",dwStackSize,lpStartAddress,lpParameter); + return NULL; +} + +/*********************************************************************** + * SwitchToFiber (KERNEL32.@) + * + * Schedules a fiber for execution + * + */ +void WINAPI SwitchToFiber(LPVOID lpFiber) +{ + FIXME("(%p) stub\n",lpFiber); +} + +/*********************************************************************** + * DeleteFiber (KERNEL32.@) + * + * Deletes a fiber object + * + */ +void WINAPI DeleteFiber(LPVOID lpFiber) +{ + FIXME("(%p) stub\n",lpFiber); +} + +#endif /* #ifdef HAVE_UCONTEXT_H */ +