- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have found what I think is an error in the malloc_lock-routine protecting the heap in the NIOS port of the µC/OS-II system.
If you are using the technique of priority inheritance, implemented in the µC/OS-II the system could go into a deadlocked state due to an error in the malloc_lock: The system has several threads, and they use a shared mutex with priority to access a shared resource. The different threads have different (low) priority, and the mutex is created with a unique (high) priority as well: Thread A Priority 62 Thread B Priority 61 G_mutex = OSMutexCreate( 2, g_err ) When the thread with the lowest priority (A) owns the g_mutex, and another thread _B_ with a higher priority tries to get access to the mutex, the priority of the first thread is “boosted” to the priority of the in order to finish the work. Now thread A runs with priority 2. The error occurs if Thread A have accessed the malloc-function before getting the priority boosted, and then access the malloc-function again (recursively), i.e. through the realloc(). Thread A will now go trough the following code (from the nios-port: alt_malloc_lock.c): /* use our priority as a task id */ err = OSTaskQuery( OS_PRIO_SELF, &tcb ); if (err != OS_NO_ERR) return; id = tcb.OSTCBPrio; /* see if we own the heap already */ OSSemQuery( alt_heapsem, &semdata ); if( !semdata.OSCnt && id == lockid ) // id == 2, lockid == 62 { /* we do; just count the recursion */ locks++; } else { /* wait on the other task to yield the heap, then claim ownership of it */ OSSemPend( alt_heapsem, 0, &err ); locks = 1; lockid = id; } The if statement checks whether the thread already has the heap, but this check fails, since Thread A had priority 62 when it originally claimed the heap, and has now been boosted to priority 2. This results in a deadlock in the system, since thread A is waiting to gain access to a semaphore that can only be released by thread A. And thread B waits to gain access to g_mutex that can only be released by thread A witch is waiting…. I know that release 5.1 of the NIOS IDE fixed a previous problem with the realloc mechanism, but it seems there is still a problem. A possible fix could be to check on the task-id, and set the variable lockid=taskID instead of using the task priority as ID. (The Task-ID is set by using the OSTaskCreateExt(), NOTE id MUST be uinique)Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Each time a description of the change, there is always plenty to talk about around the world. They are not exempt. A statement usually is: "i have to change almost immediately versions, so do not expect me to date continue to attack ...
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page