Commit 3e7497f2 authored by Alexandre Julliard's avatar Alexandre Julliard

Unified 16-bit and 32-bit scheduling a bit more.

parent 1af1c67d
...@@ -150,7 +150,8 @@ extern HTASK TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow, ...@@ -150,7 +150,8 @@ extern HTASK TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow,
LPCSTR cmdline, BYTE len, HANDLE *hThread ); LPCSTR cmdline, BYTE len, HANDLE *hThread );
extern void TASK_ExitTask(void); extern void TASK_ExitTask(void);
extern HTASK16 TASK_GetNextTask( HTASK16 hTask ); 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_InstallTHHook( THHOOK *pNewThook );
extern void TASK_CallTaskSignalProc( UINT16 uCode, HANDLE16 hTaskOrModule ); extern void TASK_CallTaskSignalProc( UINT16 uCode, HANDLE16 hTaskOrModule );
......
...@@ -839,13 +839,7 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue, ...@@ -839,13 +839,7 @@ static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue,
iWndsLocks = WIN_SuspendWndsLock(); iWndsLocks = WIN_SuspendWndsLock();
/* force destination task to run next, if 16 bit threads */ /* wait for the result */
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 */
while ( TRUE ) while ( TRUE )
{ {
/* /*
...@@ -964,10 +958,6 @@ BOOL WINAPI ReplyMessage( LRESULT result ) ...@@ -964,10 +958,6 @@ BOOL WINAPI ReplyMessage( LRESULT result )
/* tell the sending task that its reply is ready */ /* tell the sending task that its reply is ready */
QUEUE_SetWakeBit( senderQ, QS_SMRESULT ); 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; ret = TRUE;
} }
...@@ -1134,9 +1124,6 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, ...@@ -1134,9 +1124,6 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd,
if (IsTaskLocked16()) flags |= PM_NOYIELD; if (IsTaskLocked16()) flags |= PM_NOYIELD;
/* Never yield on Win32 threads */
if (!THREAD_IsWin16(NtCurrentTeb())) flags |= PM_NOYIELD;
iWndsLocks = WIN_SuspendWndsLock(); iWndsLocks = WIN_SuspendWndsLock();
while(1) while(1)
...@@ -1258,12 +1245,14 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, ...@@ -1258,12 +1245,14 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd,
/* Check for timer messages, but yield first */ /* Check for timer messages, but yield first */
#if 0 /* FIXME */
if (!(flags & PM_NOYIELD)) if (!(flags & PM_NOYIELD))
{ {
UserYield16(); UserYield16();
while ( QUEUE_ReceiveMessage( msgQueue ) ) while ( QUEUE_ReceiveMessage( msgQueue ) )
; ;
} }
#endif
if (QUEUE_TestWakeBit(msgQueue, mask & QS_TIMER)) if (QUEUE_TestWakeBit(msgQueue, mask & QS_TIMER))
{ {
...@@ -1272,8 +1261,9 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd, ...@@ -1272,8 +1261,9 @@ static BOOL MSG_PeekMessage( int type, LPMSG msg_out, HWND hwnd,
if (peek) if (peek)
{ {
#if 0 /* FIXME */
if (!(flags & PM_NOYIELD)) UserYield16(); if (!(flags & PM_NOYIELD)) UserYield16();
#endif
QUEUE_Unlock( msgQueue ); QUEUE_Unlock( msgQueue );
WIN_RestoreWndsLock(iWndsLocks); WIN_RestoreWndsLock(iWndsLocks);
return FALSE; return FALSE;
...@@ -2083,64 +2073,11 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles, ...@@ -2083,64 +2073,11 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
msgQueue->wakeMask = dwWakeMask; msgQueue->wakeMask = dwWakeMask;
LeaveCriticalSection( &msgQueue->cSection ); 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 */ /* Add the thread event to the handle list */
for (i = 0; i < nCount; i++) for (i = 0; i < nCount; i++) handles[i] = pHandles[i];
handles[i] = pHandles[i]; handles[nCount] = msgQueue->server_queue;
handles[nCount] = msgQueue->server_queue; ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
}
QUEUE_Unlock( msgQueue ); QUEUE_Unlock( msgQueue );
return ret; return ret;
} }
......
...@@ -645,22 +645,13 @@ static BOOL QUEUE_TrySetWakeBit( MESSAGEQUEUE *queue, WORD bit, BOOL always ) ...@@ -645,22 +645,13 @@ static BOOL QUEUE_TrySetWakeBit( MESSAGEQUEUE *queue, WORD bit, BOOL always )
if ( wake ) if ( wake )
{ {
/* Wake up thread waiting for message */ /* Wake up thread waiting for message */
if ( THREAD_IsWin16( queue->teb ) ) SERVER_START_REQ( wake_queue )
{ {
int iWndsLock = WIN_SuspendWndsLock(); req->handle = queue->server_queue;
PostEvent16( queue->teb->htask16 ); req->bits = bit;
WIN_RestoreWndsLock( iWndsLock ); SERVER_CALL();
}
else
{
SERVER_START_REQ( wake_queue )
{
req->handle = queue->server_queue;
req->bits = bit;
SERVER_CALL();
}
SERVER_END_REQ;
} }
SERVER_END_REQ;
} }
return wake; return wake;
...@@ -707,19 +698,17 @@ WORD QUEUE_TestWakeBit( MESSAGEQUEUE *queue, WORD bit ) ...@@ -707,19 +698,17 @@ WORD QUEUE_TestWakeBit( MESSAGEQUEUE *queue, WORD bit )
int QUEUE_WaitBits( WORD bits, DWORD timeout ) int QUEUE_WaitBits( WORD bits, DWORD timeout )
{ {
MESSAGEQUEUE *queue; MESSAGEQUEUE *queue;
DWORD curTime = 0;
HQUEUE16 hQueue; HQUEUE16 hQueue;
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits); TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
if ( THREAD_IsWin16( NtCurrentTeb() ) && (timeout != INFINITE) )
curTime = GetTickCount();
hQueue = GetFastQueue16(); hQueue = GetFastQueue16();
if (!(queue = QUEUE_Lock( hQueue ))) return 0; if (!(queue = QUEUE_Lock( hQueue ))) return 0;
for (;;) for (;;)
{ {
DWORD dwlc;
EnterCriticalSection( &queue->cSection ); EnterCriticalSection( &queue->cSection );
if (queue->changeBits & bits) if (queue->changeBits & bits)
...@@ -745,40 +734,10 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout ) ...@@ -745,40 +734,10 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
TRACE_(msg)("%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask); TRACE_(msg)("%04x) wakeMask is %04x, waiting\n", queue->self, queue->wakeMask);
LeaveCriticalSection( &queue->cSection ); LeaveCriticalSection( &queue->cSection );
if ( !THREAD_IsWin16( NtCurrentTeb() ) ) ReleaseThunkLock( &dwlc );
{ if (dwlc) TRACE_(msg)("had win16 lock\n");
BOOL bHasWin16Lock; WaitForSingleObject( queue->server_queue, timeout );
DWORD dwlc; if (dwlc) RestoreThunkLock( 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();
}
}
} }
} }
...@@ -1630,12 +1589,9 @@ void WINAPI UserYield16(void) ...@@ -1630,12 +1589,9 @@ void WINAPI UserYield16(void)
; ;
QUEUE_Unlock( queue ); QUEUE_Unlock( queue );
/* Yield */ /* Yield */
if ( THREAD_IsWin16( NtCurrentTeb() ) ) OldYield16();
OldYield16();
else
WIN32_OldYield16();
/* Handle sent messages again */ /* Handle sent messages again */
queue = QUEUE_Lock( GetFastQueue16() ); queue = QUEUE_Lock( GetFastQueue16() );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment