]> git.sur5r.net Git - freertos/commitdiff
Lowered the thread priorities used by the Win32 port, and added in a method to delete...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 22 Nov 2010 09:52:36 +0000 (09:52 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 22 Nov 2010 09:52:36 +0000 (09:52 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1159 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/MSVC-MingW/port.c
Source/portable/MSVC-MingW/portmacro.h

index 03345560df213f0dba8c3eb7cc5d401f3e189b2e..e3fde1e9b9e63ea8cd21f344f3e2541e0d428108 100644 (file)
@@ -153,8 +153,11 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
                SignalObjectAndWait( pvInterruptEventMutex, pvTickAcknowledgeEvent, INFINITE, FALSE );\r
        }\r
 \r
-       /* Should never reach here. */\r
-       return 0;\r
+       #ifdef __GNUC__\r
+               /* Should never reach here - MingW complains if you leave this line out,\r
+               MSVC complains if you put it in. */\r
+               return 0;\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -200,7 +203,6 @@ xThreadState *pxThreadState;
        /* Set the priority of this thread such that it is above the priority of \r
        the threads that run tasks.  This higher priority is required to ensure\r
        pseudo interrupts take priority over tasks. */\r
-       SetPriorityClass( GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS );\r
        pvHandle = GetCurrentThread();\r
        if( pvHandle == NULL )\r
        {\r
@@ -209,7 +211,7 @@ xThreadState *pxThreadState;
        \r
        if( lSuccess == pdPASS )\r
        {\r
-               if( SetThreadPriority( pvHandle, THREAD_PRIORITY_HIGHEST ) == 0 )\r
+               if( SetThreadPriority( pvHandle, THREAD_PRIORITY_BELOW_NORMAL ) == 0 )\r
                {\r
                        lSuccess = pdFAIL;\r
                }\r
@@ -224,7 +226,7 @@ xThreadState *pxThreadState;
                pvHandle = CreateThread( NULL, 0, prvSimulatedPeripheralTimer, NULL, 0, NULL );\r
                if( pvHandle != NULL )\r
                {\r
-                       SetThreadPriority( pvHandle, THREAD_PRIORITY_HIGHEST );\r
+                       SetThreadPriority( pvHandle, THREAD_PRIORITY_NORMAL );\r
                        SetThreadPriorityBoost( pvHandle, TRUE );\r
                        SetThreadAffinityMask( pvHandle, 0x01 );\r
                }\r
@@ -237,7 +239,6 @@ xThreadState *pxThreadState;
                /* Bump up the priority of the thread that is going to run, in the\r
                hope that this will asist in getting the Windows thread scheduler to\r
                behave as an embedded engineer might expect. */\r
-               SetThreadPriority( pxThreadState->pvThread, THREAD_PRIORITY_ABOVE_NORMAL );\r
                ResumeThread( pxThreadState->pvThread );\r
 \r
                /* Handle all pseudo interrupts - including yield requests and \r
@@ -253,7 +254,7 @@ xThreadState *pxThreadState;
 \r
 static void prvProcessPseudoInterrupts( void )\r
 {\r
-long lSwitchRequired;\r
+long lSwitchRequired, lCurrentTaskBeingDeleted;\r
 xThreadState *pxThreadState;\r
 void *pvObjectList[ 2 ];\r
 unsigned long i;\r
@@ -271,6 +272,7 @@ unsigned long i;
                /* Used to indicate whether the pseudo interrupt processing has\r
                necessitated a context switch to another task/thread. */\r
                lSwitchRequired = pdFALSE;\r
+               lCurrentTaskBeingDeleted = pdFALSE;\r
 \r
                /* For each interrupt we are interested in processing, each of which is\r
                represented by a bit in the 32bit ulPendingInterrupts variable. */\r
@@ -307,6 +309,14 @@ unsigned long i;
                                                SetEvent( pvTickAcknowledgeEvent );\r
                                                break;\r
 \r
+                                       case portINTERRUPT_DELETE_THREAD:\r
+\r
+                                               lCurrentTaskBeingDeleted = pdTRUE;\r
+\r
+                                               /* Clear the interrupt pending bit. */\r
+                                               ulPendingInterrupts &= ~( 1UL << portINTERRUPT_DELETE_THREAD );\r
+                                               break;\r
+\r
                                        default:\r
 \r
                                                /* Is a handler installed? */\r
@@ -329,7 +339,7 @@ unsigned long i;
                        }\r
                }\r
 \r
-               if( lSwitchRequired != pdFALSE )\r
+               if( ( lSwitchRequired != pdFALSE ) || ( lCurrentTaskBeingDeleted != pdFALSE ) )\r
                {\r
                        void *pvOldCurrentTCB;\r
 \r
@@ -344,32 +354,19 @@ unsigned long i;
                        {\r
                                /* Suspend the old thread. */\r
                                pxThreadState = ( xThreadState *) *( ( unsigned long * ) pvOldCurrentTCB );\r
-                               SetThreadPriority( pxThreadState->pvThread, THREAD_PRIORITY_IDLE );\r
-                               SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );\r
-                               SuspendThread( pxThreadState->pvThread );\r
-                                                       \r
-\r
-\r
-                               /* NOTE! - Here lies a problem when the preemptive scheduler is \r
-                               used.  It would seem Win32 threads do not stop as soon as a\r
-                               call to suspend them is made.  The co-operative scheduler gets\r
-                               around this by having the thread block on a semaphore \r
-                               immediately after yielding so it cannot execute any more task\r
-                               code until it is once again scheduled to run.  This cannot be\r
-                               done if the task is pre-empted though, and I have not found an\r
-                               equivalent work around for the preemptive situation. */\r
-                               \r
 \r
+                               if( lCurrentTaskBeingDeleted != pdFALSE )\r
+                               {\r
+                                       TerminateThread( pxThreadState->pvThread, 0 );\r
+                               }\r
+                               else\r
+                               {\r
+                                       SuspendThread( pxThreadState->pvThread );\r
+                               }                                                       \r
 \r
                                /* Obtain the state of the task now selected to enter the \r
                                Running state. */\r
                                pxThreadState = ( xThreadState * ) ( *( unsigned long *) pxCurrentTCB );\r
-\r
-                               /* Boost the priority of the thread selected to run a little \r
-                               in an attempt to get the Windows thread scheduler to act a \r
-                               little more like an embedded engineer might expect. */\r
-                               SetThreadPriority( pxThreadState->pvThread, THREAD_PRIORITY_ABOVE_NORMAL );\r
-                               SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );\r
                                ResumeThread( pxThreadState->pvThread );\r
                        }\r
                }\r
@@ -379,8 +376,34 @@ unsigned long i;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void vPortDeleteThread( void *pvTaskToDelete )\r
+{\r
+xThreadState *pxThreadState;\r
+\r
+       if( pvTaskToDelete == pxCurrentTCB )\r
+       {\r
+               /* The task is deleting itself, and so the thread that is running now\r
+               is also to be deleted.  This has to be deferred until this thread is\r
+               no longer running, so its done in the pseudo interrupt handler thread. */\r
+               vPortGeneratePseudoInterrupt( portINTERRUPT_DELETE_THREAD );\r
+       }\r
+       else\r
+       {\r
+               WaitForSingleObject( pvInterruptEventMutex, INFINITE );\r
+\r
+               /* Find the handle of the thread being deleted. */\r
+               pxThreadState = ( xThreadState * ) ( *( unsigned long *) pvTaskToDelete );\r
+               TerminateThread( pxThreadState->pvThread, 0 );\r
+\r
+               ReleaseMutex( pvInterruptEventMutex );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 void vPortEndScheduler( void )\r
 {\r
+       /* This function IS NOT TESTED! */\r
+       TerminateProcess( GetCurrentProcess(), 0 );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index 94cca44269ad829eeb6bc9b92f71141f03658eb8..7dfdf166f4ac8e4d492bfb7e50a57bd1aff93f9f 100644 (file)
@@ -55,7 +55,6 @@
 #define PORTMACRO_H\r
 \r
 #include <Windows.h>\r
-//#include <tchar.h>\r
 \r
 /******************************************************************************\r
        Defines\r
@@ -83,6 +82,9 @@
 #define portBYTE_ALIGNMENT                     4\r
 \r
 #define portYIELD()                                    vPortGeneratePseudoInterrupt( portINTERRUPT_YIELD )\r
+\r
+void vPortDeleteThread( void *pvThreadToDelete );\r
+#define traceTASK_DELETE( pxTCB )      vPortDeleteThread( pxTCB )\r
 #define portDISABLE_INTERRUPTS()\r
 #define portENABLE_INTERRUPTS()\r
 \r
@@ -100,6 +102,7 @@ void vPortExitCritical( void );
 \r
 #define portINTERRUPT_YIELD                            ( 0UL )\r
 #define portINTERRUPT_TICK                             ( 1UL )\r
+#define portINTERRUPT_DELETE_THREAD            ( 2UL )\r
 \r
 /* \r
  * Raise a simulated interrupt represented by the bit mask in ulInterruptMask.\r