UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor pafbat
Visitor
1,827 Views
Registered: ‎10-09-2007

Bug found in timer.c lib of Xilkernel

Hi all. I have  found a bug in timer.c library of Xilkernel v3_00_a. I know there is a newer version of Xilkernel v4_00_a, however I can not work with it yet and I don't know if the bug is solved in that last version.

 

The problem is encountered when there are two or more processes waiting on a sleep state and the current executing process kills one of these "sleeping" processes. If the killed process called sleep function prior to any other "sleeping" process, then the void soft_tmr_handler() function which is in charge of awaking the "sleeping" processes never will awake the last process that called sleep() function. I will put an example to make myself clear:

Lets say we have process A, B and C. Process A starts executing and at some point calls sleep(2000), that will cause it to sleep for 2 sec.

Then process B starts executing and at some point calls sleep(3000), that will cause it to sleep for 3 sec.

Then process C starts executing and decides to kill process A. Then, no matter whatever you do in process C, that the scheduler will never awake process B.

Here is the code of the function which has the bug:

----------------------------

timer.c file:

----------------------------

void soft_tmr_handler ()
{
    int i;
    int* tmrshadow;
    int curactive = 0;

    tmrshadow = get_tmr_list_shadow(active_tmrs);                       // Get the list that can act as a shadow to the current list
    for (i=0; i < nactive; i++) {
        if (soft_tmrs[active_tmrs[i]].pid == -1)                        // This timer has been removed and is no longer active. Silently drop it
            continue;

    soft_tmrs[active_tmrs[i]].timeout--;
        if (soft_tmrs[active_tmrs[i]].timeout == 0) {                   // Timer expired. Unblock the process
        handle_timeout (soft_tmrs[active_tmrs[i]].pid);
        soft_tmrs[active_tmrs[i]].pid = -1;
    }
    else {
        tmrshadow[curactive] = active_tmrs[i];                      // Append timer id to newly formed list
        curactive++;
    }
    }
   
    active_tmrs = tmrshadow;
    nactive = curactive;
}

---------------------------

The problem is that continue statement allows i variable to increase while nactive variable stays equal.

Hereafter I show a possible solution for the bug. I have tried already and it works:

---------------------------

void soft_tmr_handler ()
{
   int not_count = 0;//@amo added
    int i;
    int* tmrshadow;
    int curactive = 0;

    tmrshadow = get_tmr_list_shadow(active_tmrs);                       // Get the list that can act as a shadow to the current list
    for (i=0; i < nactive + not_count; i++) {//@amo added before -> for (i=0; i < nactive; i++)
        if (soft_tmrs[active_tmrs[i]].pid == -1)                        // This timer has been removed and is no longer active. Silently drop it
    {   //@amo added
       not_count++; //@amo added
       continue;
    } //@amo added

    soft_tmrs[active_tmrs[i]].timeout--;
        if (soft_tmrs[active_tmrs[i]].timeout == 0) {                   // Timer expired. Unblock the process
        handle_timeout (soft_tmrs[active_tmrs[i]].pid);
        soft_tmrs[active_tmrs[i]].pid = -1;
    }
    else {
        tmrshadow[curactive] = active_tmrs[i];                      // Append timer id to newly formed list
        curactive++;
    }
    }
   
    active_tmrs = tmrshadow;
    nactive = curactive;

-------------------------------------

Please notice the changes in red color. I hope this may help to someone!

 

pafbat

0 Kudos