# Problem in 4.3.1 task handling

**URL:** <https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229>\
**Category:** Kernel\
**Created:** [July 27, 2007, 2:01pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229 "2007-07-27T14:01:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 2:01pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/1 "2007-07-27T14:01:18Z")

</div>

**[dansear](https://sourceforge.net/u/dansear/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2):

I recently encountered a bug in the handling of tasks.  
A consequence of the bug causes ‘pxItemToRemove-\>pvContainer’  
to be NULL in vListRemove(). I can detect the problem by  
putting a test for ‘pxItemToRemove-\>pvContainer == NULL’  
in that function.

The source of the bug is subtle, but I will try to describe  
the situation. ARM platform. Several tasks exist, including  
an idle task. The tasks that cause the problem loop around  
doing some work and then call vTaskSuspend(NULL). An interrupt  
is used to get the task going again, via xTaskResumeFromISR().  
In my case, there are 2 tasks doing this, each has its own  
interrupt for resuming.

The ‘work’ that the tasks perform include using a semaphore  
to lock/unlock access to a resource.

So the task may be suspended two ways 1) at the vTaskSuspend(NULL),  
and 2) waiting for the semaphore. The first does not have an ‘Event’  
associated with it, but the second does (involving xPendingReadyList,  
and xEventListItem).

The problem appears to be generated if the task is suspended on  
the semaphore, with event, but the interrupt triggers a resume.  
In my case, the interrupt occurs frequently, so it may happen  
during the suspend for the semaphore lock. There is nothing in  
xTaskResumeFromISR() that checks if the task is suspended waiting  
on an event.

Since the task is suspended, waiting for an event, I believe  
the ISR resume should be ignored… the event has not occured.

The following is my solution to accomplish that. In xTaskResumeFromISR()  
change:

if( listIS\_CONTAINED\_WITHIN( &xPendingReadyList, &( pxTCB-\>xEventListItem ) ) != pdTRUE )

to:

if(( listIS\_CONTAINED\_WITHIN( &xPendingReadyList, &( pxTCB-\>xEventListItem ) ) != pdTRUE )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; && (pxTCB-\>xEventListItem.pvContainer == NULL) )

This has solved my current problem with the NULL pointer getting into  
vListRemove(), but I have to wonder if this is correct?

Dan Searles

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [July 27, 2007, 2:13pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/2 "2007-07-27T14:13:41Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/e6ea):

I think this is related to your previous post regarding the indefinite suspension mechanism (a new thing) - where the task is actually held in the suspended list rather than the event list should it be waiting indefinitely for an event.

There is a new release to be made in the next couple of days, so I will fix.

Thanks, and regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 3:54pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/3 "2007-07-27T15:54:50Z")

</div>

**[dspaude](https://sourceforge.net/u/dspaude/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/89d6):

I think I also have a similar problem as Dan. I have a task that is sending data to the UART and then pausing (waiting on a semaphore) until a character is received from the UART to resume printing. However, the when the semaphore is signaled (from the UART Rx task) the Tx task will not resume. I THINK I explained that correctly, but I haven’t dug into that issue yet since I’ve been resolving my printf()-related aborts.

Darrik

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 4:08pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/4 "2007-07-27T16:08:12Z")

</div>

**[dansear](https://sourceforge.net/u/dansear/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/dd92):

I think it may be different as I had that fix in while tracking down  
the NULL pointer problem. So my tasks should have been staying in  
the suspended list.

A task suspended indefinitely and a task suspended on an event both  
have their GenericItem in the suspended list. Only the task waiting  
for the event has an EventItem in the PendingReady list. I’m not even  
sure what would happen if the GenericItem were in one of the Delayed lists.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [July 27, 2007, 4:33pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/5 "2007-07-27T16:33:30Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/89d6/5803):

I think Dans problems relate to the ‘wait indefinitely’ functionality, which was put in quite recently (not quite correctly it seems) following a request from a user.&nbsp; The problem is probably not related unless you are wanting to wait indefinitely while also using the xTaskResumeFromISR() feature (which incidentally is also a new function following a user request).

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 6:08pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/6 "2007-07-27T18:08:23Z")

</div>

**[dansear](https://sourceforge.net/u/dansear/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/2f76):

I think I see what you mean. The new part (delay indefinitely) is putting the GenericItem  
on the suspended list, where as before, it would have gone on a Delayed list. If it were on  
a delayed list, xTaskResumeFromISR() would not have seen it and wouldn’t resume it. So  
a proper fix may be a little tricker than what I did. A few more questions are starting  
to pop up, like should you be able to xTaskResumeFromISR() a task that has a definite  
wait time?

Dan

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [July 27, 2007, 8:26pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/7 "2007-07-27T20:26:47Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/2f76/6450):

The intention is that ResumeFromISR() is only used to unsuspend a task that was suspended using vTaskSuspend(), and never a task that was blocked with a timeout on a queue/semphore.&nbsp; Tasks that are blocked on a queue or semaphore should be woken (within an interrupt) using QueueSendFromISR() or SemaphoreGiveFromISR().

The problem has arisen by placing a task that is blocked on a queue/semaphore into the suspended list (where until recently they would never have been), without updating the ResumeFromISR() function to check that the task is indeed in the Suspended state (as a result of a call to TaskSuspend()), and not in the Blocked state (as a result of a call to a queue or semaphore function with infinite block time).

This is definitely an error, but in most cases people have got away from it because their tasks enter either the Suspended or Blocked states, not both.&nbsp; The scenario you described in the first message of this post is not one I have personally encountered.

I think the solution you suggested works, but I need more time to consider it, as per:

portBASE\_TYPE xTaskResumeFromISR( xTaskHandle pxTaskToResume )  
{  
portBASE\_TYPE xYieldRequired = pdFALSE;  
tskTCB \*pxTCB;

\_\_pxTCB = ( tskTCB \* ) pxTaskToResume;

\_\_/\* Is the task we are attempting to resume actually suspended? \*/  
\_\_if( listIS\_CONTAINED\_WITHIN( &xSuspendedTaskList, &( pxTCB-\>xGenericListItem ) ) != pdFALSE )  
\_\_{  
\_\_\_\_/\* Has the task already been resumed from within an ISR? \*/  
\_\_\_\_if( listIS\_CONTAINED\_WITHIN( &xPendingReadyList, &( pxTCB-\>xEventListItem ) ) != pdTRUE )  
\_\_\_\_{  
\_\_\_\_\_\_/\* Is the task really in the Suspended state, or blocking  
\_\_\_\_\_\_indefinitely on an event? \*/  
\_\_\_\_\_\_if( pxTCB-\>xEventListItem.pvContainer == NULL )  
\_\_\_\_\_\_{  
\_\_\_\_\_\_\_\_if( uxSchedulerSuspended == ( unsigned portBASE\_TYPE ) pdFALSE )  
\_\_\_\_\_\_\_\_{  
\_\_\_\_\_\_\_\_\_\_xYieldRequired = ( pxTCB-\>uxPriority \>= pxCurrentTCB-\>uxPriority );  
\_\_\_\_\_\_\_\_\_\_vListRemove(&nbsp; &( pxTCB-\>xGenericListItem ) );  
\_\_\_\_\_\_\_\_\_\_prvAddTaskToReadyQueue( pxTCB );  
\_\_\_\_\_\_\_\_}  
\_\_\_\_\_\_\_\_else  
\_\_\_\_\_\_\_\_{  
\_\_\_\_\_\_\_\_\_\_/\* We cannot access the delayed or ready lists, so will hold this  
\_\_\_\_\_\_\_\_\_\_task pending until the scheduler is resumed, at which point a  
\_\_\_\_\_\_\_\_\_\_yield will be preformed if necessary. \*/  
\_\_\_\_\_\_\_\_\_\_vListInsertEnd( ( xList \* ) &( xPendingReadyList ), &( pxTCB-\>xEventListItem ) );  
\_\_\_\_\_\_\_\_}  
\_\_\_\_\_\_\_}  
\_\_\_\_}  
\_\_}

\_\_return xYieldRequired;  
}

The same change is probably required in the TaskResume() function too.

With respect to the other issue you raised I was thinking along the lines of:

portBASE\_TYPE xTaskCheckForTimeOut( xTimeOutType \*pxTimeOut, portTickType \*pxTicksToWait )  
{  
portBASE\_TYPE xReturn;

\_\_#if INCLUDE\_vTaskSuspend == 1  
\_\_\_\_/\* The task is waiting indefinitely so had not timed out. \*/  
\_\_\_\_if( \*pxTicksToWait == portMAX\_DELAY )  
\_\_\_\_{  
\_\_\_\_\_\_xReturn = pdFALSE;  
\_\_\_\_}  
\_\_\_\_else  
\_\_#endif

\_\_if( ( xNumOfOverflows != pxTimeOut-\>xOverflowCount ) && ( xTickCount \>= pxTimeOut-\>xTimeOnEntering ) )  
\_\_{  
\_\_\_\_/\* The tick count is greater than the time at which vTaskSetTimeout()  
\_\_\_\_was called, but has also overflowed since vTaskSetTimeOut() was called.  
\_\_\_\_It must have wrapped all the way around and gone past us again. This  
\_\_\_\_passed since vTaskSetTimeout() was called. \*/  
\_\_\_\_xReturn = pdTRUE;  
\_\_}  
\_\_else if( ( xTickCount - pxTimeOut-\>xTimeOnEntering ) \< \*pxTicksToWait )  
\_\_{  
\_\_\_\_/\* Not a genuine timeout. Adjust parameters for time remaining. \*/  
\_\_\_\_\*pxTicksToWait -= ( xTickCount - pxTimeOut-\>xTimeOnEntering );  
\_\_\_\_vTaskSetTimeOutState( pxTimeOut );  
\_\_\_\_xReturn = pdFALSE;  
\_\_}  
\_\_else  
\_\_{  
\_\_\_\_xReturn = pdTRUE;  
\_\_}

\_\_return xReturn;  
}

Although I don’t like using the preprocessor in that way.

Thoughts?

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 9:28pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/8 "2007-07-27T21:28:43Z")

</div>

**[dansear](https://sourceforge.net/u/dansear/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/a78a):

I see that my solution was wrong… It misses the ERRONEOUS\_UNBLOCK case.

I currently don’t see another way that doesn’t add a couple more  
preprocessor tests, making it less clear.

Dan

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 9:35pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/9 "2007-07-27T21:35:40Z")

</div>

**[dansear](https://sourceforge.net/u/dansear/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/8735):

Consider moving the "if( xTicksToWait \> 0 ) "

test inside xTaskCheckForTimeOut().

Currently it is outside both calls.

Dan

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [July 27, 2007, 10:25pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/10 "2007-07-27T22:25:04Z")

</div>

**[dspaude](https://sourceforge.net/u/dspaude/)** wrote on [Friday, July 27, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/8c7c):

I use portMAX\_DELAY when I call xSemaphoreTake() from a task to wait for a character from the UART.

I looked at my sequence and here is what happens:  
1) TASK1 becomes active and sends data to UART  
2) TASK1 pauses by waiting on a semaphore (xSemaphoreTake())  
3) Rx IRQ on UART received  
4) UART ISR actually sends the data to TASK1 via xQueueSendFromISR()  
5) TASK1 never wakes up (I assume it won’t because it is waiting for the semaphore before it resumes)

So, my problem is that I am using the same task. I’ll have to see what to do about that.

Darrik

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [July 28, 2007, 4:38pm UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/11 "2007-07-28T16:38:40Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Saturday, July 28, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/5e33):

Files under SVN have been updated, but not yet fully tested (which will be done prior to release).

Regards.

---

<div class="post-metadata">

**Author:** ![jwestmoreland](https://avatars.discourse-cdn.com/v4/letter/j/d6d6ee/32.png) [@jwestmoreland](https://forums.freertos.org/u/jwestmoreland)\
**Post date:** [July 29, 2007, 1:00am UTC](https://forums.freertos.org/t/problem-in-4-3-1-task-handling/5229/12 "2007-07-29T01:00:55Z")

</div>

**[jwestmoreland](https://sourceforge.net/u/jwestmoreland/)** wrote on [Sunday, July 29, 2007](https://sourceforge.net/p/freertos/discussion/382005/thread/e70e8a93/#eae2/b7c1):

Richard,

I’ve added them in the work that I’m doing - of course I need to get the port working - but I’ll let you know if I see anything  
else otherwise.

Regards,  
John W.
