RE: ONE_SHOT_MODE vs. PERIODIC_MODE

"Vandenbroucke Sander" <[email protected]> Mon, 11 Apr 2005 10:00:20 +0200
Newsgroups gmane.science.robotics.orocos.user
Message-ID <[email protected]>
> Flexibility. In periodic mode, in order to get reasonable 
> jitter/latencies, 
> all threads must be 1) started at a time which is a multiple 
> of the PIC 
> (Programmable INterrupt Controller) period and 2) be a 
> multiple of the timer 
> period. Thus it needs carefull programming of start times and 
> periods of your 
> thread. In oneshot, the next runnable thread wakeup time is 
> programmed into 
> the PIC, and then the current thread is run. The 
> reprogramming can take 1000 
> to 2000 clock cycles, which is thus overhead, but you buy 
> flexibility for it.
> 
> With well crafted threads, periodic mode might be not that 
> bad. The Orocos 
> PeriodicThread does not take a 'start time' argument yet ( in 
> start() ), but 
> this may easily be added in the current implementation. Also, 
> the hardcoded
> oneshot mode might then be made configurable (even at startup-time).
> 
This would be a nice feature. But I thick it should be fixed in the OS dependend layer only.
The Application builder for example should not see any difference in both modes...

> You could also have used TimeService::ticks2nano( 
> ts->getTicks() ), but a 
> native getNSecs() is indeed more efficient, avoiding a 
> syscall, so I'll 
> possitively accept it ! :-)
> 
Here are some patches. You have to use them in
/orocos-vers/packages/corelib/timing/vers (TimeService.patch)
/orocos-vers/packages/os/lxrt/vers (fosi_lxrt.patch)
/orocos-vers/packages/os/gnulinux/vers (fosi_gnu.patch)

Sander.

_______________________________________________
Orocos mailing list
[email protected]
http://lists.mech.kuleuven.be/mailman/listinfo/orocos
fosi_lxrt.patch (application/octet-stream, 988 B)
--- include/fosi.h	2005-04-11 09:01:28.484576768 +0200
+++ include/fosi.new.h	2005-04-11 09:06:35.919839504 +0200
@@ -152,6 +152,8 @@
 
 inline TICK_TIME systemTimeGet(void) { return rt_get_time(); }
 
+inline TICK_TIME systemNSecsTimeGet(void) { return rt_get_cpu_time_ns(); }
+
 inline TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); }
 
 	inline TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); }
@@ -261,6 +263,8 @@
 
 TICK_TIME systemTimeGet(void);
 
+NANO_TIME systemNSecsTimeGet(void);
+
 TICK_TIME ticksPerSec(void);
 
 TICK_TIME nano2ticks(NANO_TIME t);
--- src/fosi.c	2005-04-11 09:02:32.475848616 +0200
+++ src/fosi.new.c	2005-04-11 09:02:04.358123160 +0200
@@ -88,6 +88,8 @@
 
 TICK_TIME systemTimeGet(void) { return rt_get_time(); }
 
+NANO_TIME systemNSecsTimeGet(void) { return rt_get_cpu_time_ns(); }
+
 TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); }
 
 TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); }
fosi_gnu.patch (application/octet-stream, 514 B)
--- include/fosi.h	2005-04-11 09:13:11.484704504 +0200
+++ include/fosi.new.h	2005-04-11 09:12:04.076952040 +0200
@@ -82,6 +82,15 @@
         return rtos_get_time_ns();
     }
 
+    /**
+     * This function should return ticks,
+     * but we use ticks == nsecs in userspace
+     */
+    inline NANO_TIME systemNSecsTimeGet()
+    {
+        return rtos_get_time_ns();
+    }
+
     inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp )
     {
         //    return usleep(rqtp->tv_nsec/1000L);
TimeService.patch (application/octet-stream, 1.4 KB)
--- include/TimeService.hpp	2005-04-11 08:50:56.364673600 +0200
+++ include/TimeService.new.hpp	2005-04-11 08:26:41.095908080 +0200
@@ -161,6 +161,21 @@
          * \a secondsChange.
          */
         void enableSystemClock( bool yes_no );
+	
+        /**
+         * Get current nsecs of the HeartBeat clock
+         * 
+         * @return current nsecs of the heartbeat clock
+         */
+        nsecs getNSecs() const;
+
+        /**
+         * Get nsecs passed since a certain moment
+         * 
+         * @return nsecs passed since <relativeTime> unless <relativeTime>
+         *         is zero, then sets <relativeTime> = timeGet() and returns zero
+         */
+        nsecs getNSecs( nsecs &relativeTime ) const;
 
         /**
          * Convert an amount of nano seconds to HeartBeat ticks
--- src/TimeService.cxx	2005-04-11 08:51:29.730601208 +0200
+++ src/TimeService.new.cxx	2005-04-11 08:26:10.667533896 +0200
@@ -137,5 +137,20 @@
         return nsecs_to_Seconds( ticks2nsecs( ticksSince( 0 ) ) ) ;
     }
 
+    TimeService::nsecs
+    TimeService::getNSecs() const
+    {
+        return systemNSecsTimeGet();
+    }
 
+    TimeService::nsecs
+    TimeService::getNSecs( TimeService::nsecs &relativeTime ) const
+    {
+        if ( relativeTime == 0 )
+        {
+            relativeTime = getNSecs();
+            return 0;
+        }
+        return ( getNSecs() - relativeTime );
+    }
 }