From 3e7497f20e3b8b483e56b0343f85a348fbee7e51 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 4 Apr 2001 00:19:55 +0000 Subject: [PATCH] Unified 16-bit and 32-bit scheduling a bit more. --- include/task.h | 3 +- loader/task.c | 313 ++++++++++++++---------------------------------------- windows/message.c | 81 ++------------ windows/queue.c | 70 +++--------- 4 files changed, 105 insertions(+), 362 deletions(-) diff --git a/include/task.h b/include/task.h index 55309476f42..46060ddd516 100644 --- a/include/task.h +++ b/include/task.h @@ -150,7 +150,8 @@ extern HTASK TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow, LPCSTR cmdline, BYTE len, HANDLE *hThread ); extern void TASK_ExitTask(void); extern HTASK16 TASK_GetNextTask( HTASK16 hTask ); -extern void TASK_Reschedule(void); +extern TDB *TASK_GetPtr( HTASK16 hTask ); +extern TDB *TASK_GetCurrent(void); extern void TASK_InstallTHHook( THHOOK *pNewThook ); extern void TASK_CallTaskSignalProc( UINT16 uCode, HANDLE16 hTaskOrModule ); diff --git a/loader/task.c b/loader/task.c index 52e1270b9c4..4077211e836 100644 --- a/loader/task.c +++ b/loader/task.c @@ -69,12 +69,31 @@ void TASK_InstallTHHook( THHOOK *pNewThhook ) */ HTASK16 TASK_GetNextTask( HTASK16 hTask ) { - TDB* pTask = (TDB*)GlobalLock16(hTask); + TDB* pTask = TASK_GetPtr( hTask ); if (pTask->hNext) return pTask->hNext; return (hFirstTask != hTask) ? hFirstTask : 0; } + +/*********************************************************************** + * TASK_GetPtr + */ +TDB *TASK_GetPtr( HTASK16 hTask ) +{ + return GlobalLock16( hTask ); +} + + +/*********************************************************************** + * TASK_GetCurrent + */ +TDB *TASK_GetCurrent(void) +{ + return TASK_GetPtr( GetCurrentTask() ); +} + + /*********************************************************************** * TASK_LinkTask */ @@ -83,11 +102,11 @@ static void TASK_LinkTask( HTASK16 hTask ) HTASK16 *prevTask; TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; + if (!(pTask = TASK_GetPtr( hTask ))) return; prevTask = &hFirstTask; while (*prevTask) { - TDB *prevTaskPtr = (TDB *)GlobalLock16( *prevTask ); + TDB *prevTaskPtr = TASK_GetPtr( *prevTask ); if (prevTaskPtr->priority >= pTask->priority) break; prevTask = &prevTaskPtr->hNext; } @@ -108,12 +127,12 @@ static void TASK_UnlinkTask( HTASK16 hTask ) prevTask = &hFirstTask; while (*prevTask && (*prevTask != hTask)) { - pTask = (TDB *)GlobalLock16( *prevTask ); + pTask = TASK_GetPtr( *prevTask ); prevTask = &pTask->hNext; } if (*prevTask) { - pTask = (TDB *)GlobalLock16( *prevTask ); + pTask = TASK_GetPtr( *prevTask ); *prevTask = pTask->hNext; pTask->hNext = 0; nTaskCount--; @@ -152,13 +171,13 @@ static void TASK_CreateThunks( HGLOBAL16 handle, WORD offset, WORD count ) * * Allocate a thunk for MakeProcInstance(). */ -static SEGPTR TASK_AllocThunk( HTASK16 hTask ) +static SEGPTR TASK_AllocThunk(void) { TDB *pTask; THUNKS *pThunk; WORD sel, base; - - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; + + if (!(pTask = TASK_GetCurrent())) return 0; sel = pTask->hCSAlias; pThunk = &pTask->thunks; base = (int)pThunk - (int)pTask; @@ -187,13 +206,13 @@ static SEGPTR TASK_AllocThunk( HTASK16 hTask ) * * Free a MakeProcInstance() thunk. */ -static BOOL TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk ) +static BOOL TASK_FreeThunk( SEGPTR thunk ) { TDB *pTask; THUNKS *pThunk; WORD sel, base; - - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; + + if (!(pTask = TASK_GetCurrent())) return 0; sel = pTask->hCSAlias; pThunk = &pTask->thunks; base = (int)pThunk - (int)pTask; @@ -228,7 +247,7 @@ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cm hTask = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB) ); if (!hTask) return NULL; - pTask = (TDB *)GlobalLock16( hTask ); + pTask = TASK_GetPtr( hTask ); FarSetOwner16( hTask, pModule->self ); /* Fill the task structure */ @@ -340,7 +359,7 @@ static void TASK_DeleteTask( HTASK16 hTask ) TDB *pTask; HGLOBAL16 hPDB; - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; + if (!(pTask = TASK_GetPtr( hTask ))) return; hPDB = pTask->hPDB; pTask->magic = 0xdead; /* invalidate signature */ @@ -439,7 +458,7 @@ void TASK_ExitTask(void) /* Enter the Win16Lock to protect global data structures */ _EnterWin16Lock(); - pTask = (TDB *)GlobalLock16( GetCurrentTask() ); + pTask = TASK_GetCurrent(); if ( !pTask ) { _LeaveWin16Lock(); @@ -466,11 +485,11 @@ void TASK_ExitTask(void) if( nTaskCount ) { - TDB* p = (TDB *)GlobalLock16( hFirstTask ); + TDB* p = TASK_GetPtr( hFirstTask ); while( p ) { if( p->hYieldTo == pTask->hSelf ) p->hYieldTo = 0; - p = (TDB *)GlobalLock16( p->hNext ); + p = TASK_GetPtr( p->hNext ); } } @@ -481,180 +500,10 @@ void TASK_ExitTask(void) TASK_DeleteTask( pTask->hSelf ); - /* ... schedule another one ... */ - TASK_Reschedule(); - /* ... and completely release the Win16Lock, just in case. */ ReleaseThunkLock( &lockCount ); } -/*********************************************************************** - * TASK_Reschedule - * - * This is where all the magic of task-switching happens! - * - * 16-bit Windows performs non-preemptive (cooperative) multitasking. - * This means that each 16-bit task runs until it voluntarily yields - * control, at which point the scheduler gets active and selects the - * next task to run. - * - * In Wine, all processes, even 16-bit ones, are scheduled preemptively - * by the standard scheduler of the underlying OS. As many 16-bit apps - * *rely* on the behaviour of the Windows scheduler, however, we have - * to simulate that behaviour. - * - * This is achieved as follows: every 16-bit task is at time (except - * during task creation and deletion) in one of two states: either it - * is the one currently running, then the global variable hCurrentTask - * contains its task handle, or it is not currently running, then it - * is blocked on a special scheduler event, a global handle which - * is stored in the task struct. - * - * When the current task yields control, this routine gets called. Its - * purpose is to determine the next task to be active, signal the - * scheduler event of that task, and then put the current task to sleep - * waiting for *its* scheduler event to get signalled again. - * - * This routine can get called in a few other special situations as well: - * - * - On creation of a 16-bit task, the Unix process executing the task - * calls TASK_Reschedule once it has completed its initialization. - * At this point, the task needs to be blocked until its scheduler - * event is signalled the first time (this will be done by the parent - * process to get the task up and running). - * - * - When the task currently running terminates itself, this routine gets - * called and has to schedule another task, *without* blocking the - * terminating task. - * - * - When a 32-bit thread posts an event for a 16-bit task, it might be - * the case that *no* 16-bit task is currently running. In this case - * the task that has now an event pending is to be scheduled. - * - */ -void TASK_Reschedule(void) -{ - TDB *pOldTask = NULL, *pNewTask = NULL; - HTASK16 hOldTask = 0, hNewTask = 0; - enum { MODE_YIELD, MODE_SLEEP, MODE_WAKEUP } mode; - DWORD lockCount; - - _EnterWin16Lock(); - - /* Check what we need to do */ - hOldTask = GetCurrentTask(); - pOldTask = (TDB *)GlobalLock16( hOldTask ); - TRACE( "entered with hCurrentTask %04x by hTask %04x (pid %ld)\n", - hCurrentTask, hOldTask, (long) getpid() ); - - if ( pOldTask && THREAD_IsWin16( NtCurrentTeb() ) ) - { - /* We are called by an active (non-deleted) 16-bit task */ - - /* If we don't even have a current task, or else the current - task has yielded, we'll need to schedule a new task and - (possibly) put the calling task to sleep. Otherwise, we - only block the caller. */ - - if ( !hCurrentTask || hCurrentTask == hOldTask ) - mode = MODE_YIELD; - else - mode = MODE_SLEEP; - } - else - { - /* We are called by a deleted 16-bit task or a 32-bit thread */ - - /* The only situation where we need to do something is if we - now do not have a current task. Then, we'll need to wake up - some task that has events pending. */ - - if ( !hCurrentTask || hCurrentTask == hOldTask ) - mode = MODE_WAKEUP; - else - { - /* nothing to do */ - _LeaveWin16Lock(); - return; - } - } - - /* Find a task to yield to: check for DirectedYield() */ - if ( mode == MODE_YIELD && pOldTask && pOldTask->hYieldTo ) - { - hNewTask = pOldTask->hYieldTo; - pNewTask = (TDB *)GlobalLock16( hNewTask ); - if( !pNewTask || !pNewTask->nEvents || !pNewTask->teb) hNewTask = 0; - pOldTask->hYieldTo = 0; - } - - /* Find a task to yield to: check for pending events */ - if ( (mode == MODE_YIELD || mode == MODE_WAKEUP) && !hNewTask ) - { - hNewTask = hFirstTask; - while (hNewTask) - { - pNewTask = (TDB *)GlobalLock16( hNewTask ); - - TRACE( "\ttask = %04x, events = %i\n", hNewTask, pNewTask->nEvents ); - - if (pNewTask->nEvents) break; - hNewTask = pNewTask->hNext; - } - if (hLockedTask && (hNewTask != hLockedTask)) hNewTask = 0; - } - - /* If we are still the task with highest priority, just return ... */ - if ( mode == MODE_YIELD && hNewTask && hNewTask == hCurrentTask ) - { - TRACE("returning to the current task (%04x)\n", hCurrentTask ); - _LeaveWin16Lock(); - - /* Allow Win32 threads to thunk down even while a Win16 task is - in a tight PeekMessage() or Yield() loop ... */ - ReleaseThunkLock( &lockCount ); - RestoreThunkLock( lockCount ); - return; - } - - /* If no task to yield to found, suspend 16-bit scheduler ... */ - if ( mode == MODE_YIELD && !hNewTask ) - { - TRACE("No currently active task\n"); - hCurrentTask = 0; - } - - /* If we found a task to wake up, do it ... */ - if ( (mode == MODE_YIELD || mode == MODE_WAKEUP) && hNewTask ) - { - TRACE("Switching to task %04x (%.8s)\n", - hNewTask, pNewTask->module_name ); - - pNewTask->priority++; - TASK_UnlinkTask( hNewTask ); - TASK_LinkTask( hNewTask ); - pNewTask->priority--; - - hCurrentTask = hNewTask; - NtSetEvent( pNewTask->hEvent, NULL ); - - /* This is set just in case some app reads it ... */ - pNewTask->ss_sp = pNewTask->teb->cur_stack; - } - - /* If we need to put the current task to sleep, do it ... */ - if ( (mode == MODE_YIELD || mode == MODE_SLEEP) && hOldTask != hCurrentTask ) - { - NtResetEvent( pOldTask->hEvent, NULL ); - - ReleaseThunkLock( &lockCount ); - SYSLEVEL_CheckNotLevel( 1 ); - WaitForSingleObject( pOldTask->hEvent, INFINITE ); - RestoreThunkLock( lockCount ); - } - - _LeaveWin16Lock(); -} /*********************************************************************** * InitTask (KERNEL.91) @@ -668,7 +517,7 @@ void WINAPI InitTask16( CONTEXT86 *context ) SEGPTR ptr; context->Eax = 0; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; + if (!(pTask = TASK_GetCurrent())) return; /* Note: we need to trust that BX/CX contain the stack/heap sizes, as some apps, notably Visual Basic apps, *modify* the heap/stack @@ -728,7 +577,7 @@ BOOL16 WINAPI WaitEvent16( HTASK16 hTask ) TDB *pTask; if (!hTask) hTask = GetCurrentTask(); - pTask = (TDB *)GlobalLock16( hTask ); + pTask = TASK_GetPtr( hTask ); if ( !THREAD_IsWin16( NtCurrentTeb() ) ) { @@ -741,11 +590,20 @@ BOOL16 WINAPI WaitEvent16( HTASK16 hTask ) pTask->nEvents--; return FALSE; } - TASK_Reschedule(); - /* When we get back here, we have an event */ + if (pTask->teb == NtCurrentTeb()) + { + DWORD lockCount; + + NtResetEvent( pTask->hEvent, NULL ); + ReleaseThunkLock( &lockCount ); + SYSLEVEL_CheckNotLevel( 1 ); + WaitForSingleObject( pTask->hEvent, INFINITE ); + RestoreThunkLock( lockCount ); + if (pTask->nEvents > 0) pTask->nEvents--; + } + else FIXME("for other task %04x cur=%04x\n",pTask->hSelf,GetCurrentTask()); - if (pTask->nEvents > 0) pTask->nEvents--; return TRUE; } @@ -758,7 +616,7 @@ void WINAPI PostEvent16( HTASK16 hTask ) TDB *pTask; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; + if (!(pTask = TASK_GetPtr( hTask ))) return; if ( !THREAD_IsWin16( pTask->teb ) ) { @@ -768,9 +626,7 @@ void WINAPI PostEvent16( HTASK16 hTask ) pTask->nEvents++; - /* If we are a 32-bit task, we might need to wake up the 16-bit scheduler */ - if ( !THREAD_IsWin16( NtCurrentTeb() ) ) - TASK_Reschedule(); + if (pTask->nEvents == 1) NtSetEvent( pTask->hEvent, NULL ); } @@ -783,14 +639,14 @@ void WINAPI SetPriority16( HTASK16 hTask, INT16 delta ) INT16 newpriority; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; + if (!(pTask = TASK_GetPtr( hTask ))) return; newpriority = pTask->priority + delta; if (newpriority < -32) newpriority = -32; else if (newpriority > 15) newpriority = 15; pTask->priority = newpriority + 1; - TASK_UnlinkTask( hTask ); - TASK_LinkTask( hTask ); + TASK_UnlinkTask( pTask->hSelf ); + TASK_LinkTask( pTask->hSelf ); pTask->priority--; } @@ -820,17 +676,10 @@ HTASK16 WINAPI IsTaskLocked16(void) */ void WINAPI OldYield16(void) { - TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); - - if ( !THREAD_IsWin16( NtCurrentTeb() ) ) - { - FIXME("called for Win32 thread (%04x)!\n", NtCurrentTeb()->teb_sel); - return; - } + DWORD count; - if (pCurTask) pCurTask->nEvents++; /* Make sure we get back here */ - TASK_Reschedule(); - if (pCurTask) pCurTask->nEvents--; + ReleaseThunkLock(&count); + RestoreThunkLock(count); } /*********************************************************************** @@ -849,7 +698,7 @@ void WINAPI WIN32_OldYield16(void) */ void WINAPI DirectedYield16( HTASK16 hTask ) { - TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); + TDB *pCurTask = TASK_GetCurrent(); if ( !THREAD_IsWin16( NtCurrentTeb() ) ) { @@ -870,7 +719,7 @@ void WINAPI DirectedYield16( HTASK16 hTask ) */ void WINAPI Yield16(void) { - TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() ); + TDB *pCurTask = TASK_GetCurrent(); if (pCurTask) pCurTask->hYieldTo = 0; if (pCurTask && pCurTask->hQueue && Callout.UserYield16) Callout.UserYield16(); @@ -938,7 +787,7 @@ FARPROC16 WINAPI MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance ) if (NE_GetPtr(FarGetOwner16(hInstance))->flags & NE_FFLAGS_LIBMODULE) return func; - thunkaddr = TASK_AllocThunk( GetCurrentTask() ); + thunkaddr = TASK_AllocThunk(); if (!thunkaddr) return (FARPROC16)0; thunk = MapSL( thunkaddr ); lfunc = MapSL( (SEGPTR)func ); @@ -967,7 +816,7 @@ FARPROC16 WINAPI MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance ) void WINAPI FreeProcInstance16( FARPROC16 func ) { TRACE("(%08lx)\n", (DWORD)func ); - TASK_FreeThunk( GetCurrentTask(), (SEGPTR)func ); + TASK_FreeThunk( (SEGPTR)func ); } /********************************************************************** @@ -1103,7 +952,7 @@ HQUEUE16 WINAPI SetTaskQueue16( HTASK16 hTask, HQUEUE16 hQueue ) TDB *pTask; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; + if (!(pTask = TASK_GetPtr( hTask ))) return 0; hPrev = pTask->hQueue; pTask->hQueue = hQueue; @@ -1120,7 +969,7 @@ HQUEUE16 WINAPI GetTaskQueue16( HTASK16 hTask ) TDB *pTask; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; + if (!(pTask = TASK_GetPtr( hTask ))) return 0; return pTask->hQueue; } @@ -1154,7 +1003,7 @@ HQUEUE16 WINAPI GetThreadQueue16( DWORD thread ) else if ( HIWORD(thread) ) teb = THREAD_IdToTEB( thread ); else if ( IsTask16( (HTASK16)thread ) ) - teb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->teb; + teb = (TASK_GetPtr( (HANDLE16)thread ))->teb; return (HQUEUE16)(teb? teb->queue : 0); } @@ -1170,7 +1019,7 @@ VOID WINAPI SetFastQueue16( DWORD thread, HANDLE hQueue ) else if ( HIWORD(thread) ) teb = THREAD_IdToTEB( thread ); else if ( IsTask16( (HTASK16)thread ) ) - teb = ((TDB *)GlobalLock16( (HANDLE16)thread ))->teb; + teb = (TASK_GetPtr( (HANDLE16)thread ))->teb; if ( teb ) teb->queue = (HQUEUE16) hQueue; } @@ -1213,7 +1062,7 @@ void WINAPI SwitchStackTo16( WORD seg, WORD ptr, WORD top ) INSTANCEDATA *pData; UINT16 copySize; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; + if (!(pTask = TASK_GetCurrent())) return; if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return; TRACE("old=%04x:%04x new=%04x:%04x\n", SELECTOROF( pTask->teb->cur_stack ), @@ -1333,7 +1182,7 @@ DWORD WINAPI GetCurrentPDB16(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; return MAKELONG(pTask->hPDB, 0); /* FIXME */ } @@ -1367,7 +1216,7 @@ WORD WINAPI GetExeVersion16(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; return pTask->version; } @@ -1378,7 +1227,7 @@ WORD WINAPI GetExeVersion16(void) UINT16 WINAPI SetErrorMode16( UINT16 mode ) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; pTask->error_mode = mode; return SetErrorMode( mode ); } @@ -1403,7 +1252,7 @@ HINSTANCE16 WINAPI GetTaskDS16(void) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; return GlobalHandleToSel16(pTask->hInstance); } @@ -1415,7 +1264,7 @@ WORD WINAPI GetDummyModuleHandleDS16(void) TDB *pTask; WORD selector; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; if (!(pTask->flags & TDBF_WIN32)) return 0; selector = GlobalHandleToSel16( pTask->hModule ); CURRENT_DS = selector; @@ -1430,7 +1279,7 @@ BOOL16 WINAPI IsTask16( HTASK16 hTask ) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return FALSE; + if (!(pTask = TASK_GetPtr( hTask ))) return FALSE; if (GlobalSize16( hTask ) < sizeof(TDB)) return FALSE; return (pTask->magic == TDB_MAGIC); } @@ -1454,7 +1303,7 @@ FARPROC16 WINAPI SetTaskSignalProc( HTASK16 hTask, FARPROC16 proc ) FARPROC16 oldProc; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL; + if (!(pTask = TASK_GetPtr( hTask ))) return NULL; oldProc = pTask->userhandler; pTask->userhandler = proc; return oldProc; @@ -1468,7 +1317,7 @@ extern WORD CALLBACK TASK_CallTo16_word_wwwww(FARPROC16,WORD,WORD,WORD,WORD,WORD /* ### stop build ### */ void TASK_CallTaskSignalProc( UINT16 uCode, HANDLE16 hTaskOrModule ) { - TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); + TDB *pTask = TASK_GetCurrent(); if ( !pTask || !pTask->userhandler ) return; TASK_CallTo16_word_wwwww( pTask->userhandler, @@ -1491,7 +1340,7 @@ WORD WINAPI SetSigHandler16( FARPROC16 newhandler, FARPROC16* oldhandler, { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return 0; + if (!(pTask = TASK_GetCurrent())) return 0; if (oldmode) *oldmode = pTask->signal_flags; pTask->signal_flags = newmode; if (oldhandler) *oldhandler = pTask->sighandler; @@ -1511,7 +1360,7 @@ VOID WINAPI GlobalNotify16( FARPROC16 proc ) { TDB *pTask; - if (!(pTask = (TDB *)GlobalLock16( GetCurrentTask() ))) return; + if (!(pTask = TASK_GetCurrent())) return; pTask->discardhandler = proc; } @@ -1534,7 +1383,7 @@ static inline HMODULE16 GetExePtrHelper( HANDLE16 handle, HTASK16 *hTask ) *hTask = hFirstTask; while (*hTask) { - TDB *pTask = (TDB *)GlobalLock16( *hTask ); + TDB *pTask = TASK_GetPtr( *hTask ); if ((*hTask == handle) || (pTask->hInstance == handle) || (pTask->hQueue == handle) || @@ -1553,7 +1402,7 @@ static inline HMODULE16 GetExePtrHelper( HANDLE16 handle, HTASK16 *hTask ) *hTask = hFirstTask; while (*hTask) { - TDB *pTask = (TDB *)GlobalLock16( *hTask ); + TDB *pTask = TASK_GetPtr( *hTask ); if ((*hTask == owner) || (pTask->hInstance == owner) || (pTask->hQueue == owner) || @@ -1608,7 +1457,7 @@ BOOL16 WINAPI TaskNext16( TASKENTRY *lpte ) /* make sure that task and hInstance are valid (skip initial Wine task !) */ while (1) { - pTask = (TDB *)GlobalLock16( lpte->hNext ); + pTask = TASK_GetPtr( lpte->hNext ); if (!pTask || pTask->magic != TDB_MAGIC) return FALSE; if (pTask->hInstance) break; @@ -1650,7 +1499,7 @@ typedef INT (WINAPI *MessageBoxA_funcptr)(HWND hWnd, LPCSTR text, LPCSTR title, */ void WINAPI FatalAppExit16( UINT16 action, LPCSTR str ) { - TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() ); + TDB *pTask = TASK_GetCurrent(); if (!pTask || !(pTask->error_mode & SEM_NOGPFAULTERRORBOX)) { @@ -1721,7 +1570,7 @@ DWORD WINAPI GetAppCompatFlags( HTASK hTask ) TDB *pTask; if (!hTask) hTask = GetCurrentTask(); - if (!(pTask=(TDB *)GlobalLock16( (HTASK16)hTask ))) return 0; + if (!(pTask=TASK_GetPtr( (HTASK16)hTask ))) return 0; if (GlobalSize16(hTask) < sizeof(TDB)) return 0; return pTask->compat_flags; } diff --git a/windows/message.c b/windows/message.c index 7c36e5125b9..a10ebf9e8d2 100644 --- a/windows/message.c +++ b/windows/message.c @@ -839,13 +839,7 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue, iWndsLocks = WIN_SuspendWndsLock(); - /* force destination task to run next, if 16 bit threads */ - if ( THREAD_IsWin16(NtCurrentTeb()) && THREAD_IsWin16(destQ->teb) ) - DirectedYield16( destQ->teb->htask16 ); - - /* wait for the result, note that 16-bit apps almost always get out of - * DirectedYield() with SMSG_HAVE_RESULT flag already set */ - + /* wait for the result */ while ( TRUE ) { /* @@ -964,10 +958,6 @@ BOOL WINAPI ReplyMessage( LRESULT result ) /* tell the sending task that its reply is ready */ QUEUE_SetWakeBit( senderQ, QS_SMRESULT ); - /* switch directly to sending task (16 bit thread only) */ - if ( THREAD_IsWin16( NtCurrentTeb() ) && THREAD_IsWin16( senderQ->teb ) ) - DirectedYield16( senderQ->teb->htask16 ); - ret = TRUE; } @@ -1134,9 +1124,6 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, if (IsTaskLocked16()) flags |= PM_NOYIELD; - /* Never yield on Win32 threads */ - if (!THREAD_IsWin16(NtCurrentTeb())) flags |= PM_NOYIELD; - iWndsLocks = WIN_SuspendWndsLock(); while(1) @@ -1258,12 +1245,14 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, /* Check for timer messages, but yield first */ +#if 0 /* FIXME */ if (!(flags & PM_NOYIELD)) { UserYield16(); while ( QUEUE_ReceiveMessage( msgQueue ) ) ; } +#endif if (QUEUE_TestWakeBit(msgQueue, mask & QS_TIMER)) { @@ -1272,8 +1261,9 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, if (peek) { +#if 0 /* FIXME */ if (!(flags & PM_NOYIELD)) UserYield16(); - +#endif QUEUE_Unlock( msgQueue ); WIN_RestoreWndsLock(iWndsLocks); return FALSE; @@ -2083,64 +2073,11 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles, msgQueue->wakeMask = dwWakeMask; LeaveCriticalSection( &msgQueue->cSection ); - if (THREAD_IsWin16(NtCurrentTeb())) - { - /* - * This is a temporary solution to a big problem. - * You see, the main thread of all Win32 programs is created as a 16 bit - * task. This means that if you wait on an event using Win32 synchronization - * methods, the 16 bit scheduler is stopped and things might just stop happening. - * This implements a semi-busy loop that checks the handles to wait on and - * also the message queue. When either one is ready, the wait function returns. - * - * This will all go away when the real Win32 threads are implemented for all - * the threads of an applications. Including the main thread. - */ - DWORD curTime = GetCurrentTime(); - - do - { - /* - * Check the handles in the list. - */ - ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 5L); - - /* - * If the handles have been triggered, return. - */ - if (ret != WAIT_TIMEOUT) - break; - - /* - * Then, let the 16 bit scheduler do it's thing. - */ - K32WOWYield16(); - - /* - * If a message matching the wait mask has arrived, return. - */ - EnterCriticalSection( &msgQueue->cSection ); - if (msgQueue->changeBits & dwWakeMask) - { - LeaveCriticalSection( &msgQueue->cSection ); - ret = nCount; - break; - } - LeaveCriticalSection( &msgQueue->cSection ); - - /* - * And continue doing this until we hit the timeout. - */ - } while ((dwMilliseconds == INFINITE) || (GetCurrentTime()-curTime < dwMilliseconds) ); - } - else - { /* Add the thread event to the handle list */ - for (i = 0; i < nCount; i++) - handles[i] = pHandles[i]; - handles[nCount] = msgQueue->server_queue; - ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds ); - } + for (i = 0; i < nCount; i++) handles[i] = pHandles[i]; + handles[nCount] = msgQueue->server_queue; + ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds ); + QUEUE_Unlock( msgQueue ); return ret; } diff --git a/windows/queue.c b/windows/queue.c index 050983f8e0e..602cc2dd576 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -645,22 +645,13 @@ static BOOL QUEUE_TrySetWakeBit( MESSAGEQUEUE *queue, WORD bit, BOOL always ) if ( wake ) { /* Wake up thread waiting for message */ - if ( THREAD_IsWin16( queue->teb ) ) + SERVER_START_REQ( wake_queue ) { - int iWndsLock = WIN_SuspendWndsLock(); - PostEvent16( queue->teb->htask16 ); - WIN_RestoreWndsLock( iWndsLock ); - } - else - { - SERVER_START_REQ( wake_queue ) - { - req->handle = queue->server_queue; - req->bits = bit; - SERVER_CALL(); - } - SERVER_END_REQ; + req->handle = queue->server_queue; + req->bits = bit; + SERVER_CALL(); } + SERVER_END_REQ; } return wake; @@ -707,19 +698,17 @@ WORD QUEUE_TestWakeBit( MESSAGEQUEUE *queue, WORD bit ) int QUEUE_WaitBits( WORD bits, DWORD timeout ) { MESSAGEQUEUE *queue; - DWORD curTime = 0; HQUEUE16 hQueue; TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits); - if ( THREAD_IsWin16( NtCurrentTeb() ) && (timeout != INFINITE) ) - curTime = GetTickCount(); - hQueue = GetFastQueue16(); if (!(queue = QUEUE_Lock( hQueue ))) return 0; for (;;) { + DWORD dwlc; + EnterCriticalSection( &queue->cSection ); if (queue->changeBits & bits) @@ -745,40 +734,10 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout ) TRACE_(msg)("%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask); LeaveCriticalSection( &queue->cSection ); - if ( !THREAD_IsWin16( NtCurrentTeb() ) ) - { - BOOL bHasWin16Lock; - DWORD dwlc; - - if ( (bHasWin16Lock = _ConfirmWin16Lock()) ) - { - TRACE_(msg)("bHasWin16Lock=TRUE\n"); - ReleaseThunkLock( &dwlc ); - } - - WaitForSingleObject( queue->server_queue, timeout ); - - if ( bHasWin16Lock ) - { - RestoreThunkLock( dwlc ); - } - } - else - { - if ( timeout == INFINITE ) - WaitEvent16( 0 ); /* win 16 thread, use WaitEvent */ - else - { - /* check for timeout, then give control to other tasks */ - if (GetTickCount() - curTime > timeout) - { - - QUEUE_Unlock( queue ); - return 0; /* exit with timeout */ - } - K32WOWYield16(); - } - } + ReleaseThunkLock( &dwlc ); + if (dwlc) TRACE_(msg)("had win16 lock\n"); + WaitForSingleObject( queue->server_queue, timeout ); + if (dwlc) RestoreThunkLock( dwlc ); } } @@ -1630,12 +1589,9 @@ void WINAPI UserYield16(void) ; QUEUE_Unlock( queue ); - + /* Yield */ - if ( THREAD_IsWin16( NtCurrentTeb() ) ) - OldYield16(); - else - WIN32_OldYield16(); + OldYield16(); /* Handle sent messages again */ queue = QUEUE_Lock( GetFastQueue16() ); -- 2.11.4.GIT