Hi,

Hopefully the ascii graphics underneath renders correctly. Here's an example 
where timer API without cancel status (return value) is causing, not only 
potential implementation inefficiency, but an application failure.

An application has created multiple timers (t0, t1, ...). It sets t0 to expire 
in e.g. 10ms. The timer HW is set, t0 expires and the timeout is sent out. Core 
B receives the tmo, checks the status, status is fresh, it starts tmo 
processing. A bit later core A cancels t0 and reuses it for another timeout 
(e.g. again 10ms). Timer HW is set for t0 expiration. Core B continues 
processing and holds tmo for e.g. 100ms (a long time relative to the reused t0 
expiration time). HW timer expires, but tmo for t0 has not returned yet. 
Eventually core B returns tmo for t0 and the new timeout for t0 can be 
delivered.

Application used all timer API calls correctly and everything "succeeded", but 
the second tmo was delivered e.g. 90ms late!

If cancel would have returned status code ("too late"), application on core A 
would not have reused t0, but used the next "free timer" instead (e.g. t1). The 
tmo buffer for that would have been available and tmo delivered in time (e.g. 
received and processed by core C). From application point of view, a "free 
timer" is one that has been successfully cancelled or the pending tmo have been 
handled.

The problem is build from the combination of:
- timer_set_xxx cannot fail => timer cannot allocate a new tmo buffer when 
application holds previous one
- cancel cannot fail => application does not need to care about timer status 
when reusing a timer
- application may hold a tmo for long time (as it should be able to do)


The special nature of tmo buffer is also problematic. It's a buffer (of timer 
timeout type) but cannot be e.g. stored or forwarded to other queues (for 
arbitrary time) - otherwise the original timer is stuck until application 
returns the buffer.

Did I miss something in the API logic?


-Petri
  


timer_t t0, t1, ... 


Core A                          Core B                          Timer 
HW/implementation

timer_set_rel(t0, 10ms)                                                 set t0
                                
                                                                                
t0 expired
                                                                                
send timeout for t0
                                        tmo = sched()
                                        tmo_status(tmo) == FRESH
                                        start processing tmo
cancel(t0)                              
timer_set_rel(t0, 10ms)                                                 set t0

                                                                                
t0 expired
                                                                                
no tmo buffer for t0
                                                                                
no tmo buffer for t0 ...
                                        
                                        e.g. after 100ms
                                        finished processing tmo

                                        return_tmo(tmo)                 return 
tmo buffer for t0
                                                                                
send timeout for t0

                                        tmo = sched()
                                        tmo_status(tmo) == FRESH

                                        TMO RECEIVED 90ms LATE!                 
                          





_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to