[chrono] Thread clock compatibility problems on Android

Hello, has anybody experienced also compatibility problems of chrono library on Android? I found following (Android 2.2, NDK-r5b, chrono v0.71, rev #71693): 1) Sources with boost::chrono::thread_clock does not compile, since _POSIX_THREAD_CPUTIME is not defined on Android. My workaround is to hack chrono/config.hpp: # if 1 //defined(_POSIX_THREAD_CPUTIME) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif 2) ::clock_gettime() fails when called with clock ID got from pthread_getcpuclockid. My workaround is to call ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) in chrono/detail/inlined/posix/thread_clock.hpp. 3) Additionally there is precision problem on Linux platforms, stopwatch<process_cpu_clock> provides results with different units on Windows (nanoseconds) and Linux platforms (miliseconds). BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Hello, has anybody experienced also compatibility problems of chrono library on Android? I found following (Android 2.2, NDK-r5b, chrono v0.71, rev #71693):
1) Sources with boost::chrono::thread_clock does not compile, since _POSIX_THREAD_CPUTIME is not defined on Android. My workaround is to hack chrono/config.hpp: # if 1 //defined(_POSIX_THREAD_CPUTIME) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif
I don't know Android. Do you know which is the macros used by Boost to identify Android? Or some macro that is always defined when compiling on Android? It will be better to use this macro instead of commenting the condition.
2) ::clock_gettime() fails when called with clock ID got from pthread_getcpuclockid. My workaround is to call ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) in chrono/detail/inlined/posix/thread_clock.hpp.
Again I will need a specific macro to include this specific code.
3) Additionally there is precision problem on Linux platforms, stopwatch<process_cpu_clock> provides results with different units on Windows (nanoseconds) and Linux platforms (miliseconds).
I don't remember why there were different, but what is wrong on providing the best precession provided by the platform? Please, could you create a ticket on Trac, so we don't forget. Thanks for the report, I will try to correct it as soon I have a macro to make the difference. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hello Vicente, thanks for the fast answer and your great library! You can rely on #if defined ANDROID. Regarding process_cpu_clock, I have experienced that following code provided on Linux wrong text output, while on Windows was ok: { boost::stopwatches::stopclock<> timer; ... some work } I was not even able to convert units: { stopwatch<process_cpu_clock>::duration d = t.stop(); real_time = microseconds( d.count().real).count(); // needs to be multiplied by 1000 } I'm not sure if I'm using conversion right way, but at least the stopclock text output indicates some problem. BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Hello Vicente, thanks for the fast answer and your great library!
You can rely on #if defined ANDROID.
Thanks.
Regarding process_cpu_clock, I have experienced that following code provided on Linux wrong text output, while on Windows was ok: { boost::stopwatches::stopclock<> timer; ... some work }
Could you give me output on both cases?
I was not even able to convert units: { stopwatch<process_cpu_clock>::duration d = t.stop(); real_time = microseconds( d.count().real).count(); // needs to be multiplied by 1000 } I'm not sure if I'm using conversion right way, but at least the stopclock text output indicates some problem.
Note that you could use the process_real_cpu_clock directly. Using process_cpu_clock you need to get the associated process_real_cpu_clock::duration in order to make the conversion. I think that what you wanted should be real_time = microseconds( process_real_cpu_clock::duration(d.count().real)).count(); but maybe I have misunderstood your purpose. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet wrote:
Regarding process_cpu_clock, I have experienced that following code provided on Linux wrong text output, while on Windows was ok: { boost::stopwatches::stopclock<> timer; ... some work }
Could you give me output on both cases?
Consider following code snippet: { boost::stopwatches::stopclock<> boost_timer; for( int i = 0; i < 10000000; i++) sqrt( 123.456L); sleep( 1); // sleep 1s } Text output on windows is: real 1.031s, cpu 0.031s (3.0%), user 0.031s, system 0.000s while thread clock measures: wall=1031ms, cpu=31ms Text output on Android (on Linux was similar) is: real 0.001s, cpu 0.000s (23.2%), user 0.000s, system 0.000s while thread clock measures: wall=1377ms, cpu=312ms Test on Android was around 10x slower because I run it on Android emulator (can not test Linux right now). Behaviour on Linux I saw couple of days ago was same as on Android, i.e., stopclock provided wrong text output, just test was similar fast as on Windows. Hope this helps. BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Vicente Botet wrote:
Regarding process_cpu_clock, I have experienced that following code provided on Linux wrong text output, while on Windows was ok: { boost::stopwatches::stopclock<> timer; ... some work }
Could you give me output on both cases?
Consider following code snippet: { boost::stopwatches::stopclock<> boost_timer; for( int i = 0; i < 10000000; i++) sqrt( 123.456L); sleep( 1); // sleep 1s }
Text output on windows is: real 1.031s, cpu 0.031s (3.0%), user 0.031s, system 0.000s while thread clock measures: wall=1031ms, cpu=31ms
Text output on Android (on Linux was similar) is: real 0.001s, cpu 0.000s (23.2%), user 0.000s, system 0.000s while thread clock measures: wall=1377ms, cpu=312ms
Test on Android was around 10x slower because I run it on Android emulator (can not test Linux right now). Behaviour on Linux I saw couple of days ago was same as on Android, i.e., stopclock provided wrong text output, just test was similar fast as on Windows.
Hope this helps.
On which linux dis you tried? It seems that the posix process_cpu_clocks is not working on this platform. This clock uses tms tm; clock_t c = ::times( &tm ); Could you dump the values of c and tm.tms_stime + tm.tms_cstime, tm.tms_utime + tm.tms_cutime, before and after the sleep? Thanks, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet wrote:
Libor Bus wrote:
Vicente Botet wrote:
Regarding process_cpu_clock, I have experienced that following code provided on Linux wrong text output, while on Windows was ok: { boost::stopwatches::stopclock<> timer; ... some work }
Could you give me output on both cases?
Consider following code snippet: { boost::stopwatches::stopclock<> boost_timer; for( int i = 0; i < 10000000; i++) sqrt( 123.456L); sleep( 1); // sleep 1s }
Text output on windows is: real 1.031s, cpu 0.031s (3.0%), user 0.031s, system 0.000s while thread clock measures: wall=1031ms, cpu=31ms
Text output on Android (on Linux was similar) is: real 0.001s, cpu 0.000s (23.2%), user 0.000s, system 0.000s while thread clock measures: wall=1377ms, cpu=312ms
Test on Android was around 10x slower because I run it on Android emulator (can not test Linux right now). Behaviour on Linux I saw couple of days ago was same as on Android, i.e., stopclock provided wrong text output, just test was similar fast as on Windows.
Hope this helps.
On which linux dis you tried?
It seems that the posix process_cpu_clocks is not working on this platform. This clock uses
tms tm; clock_t c = ::times( &tm );
Could you dump the values of c and tm.tms_stime + tm.tms_cstime, tm.tms_utime + tm.tms_cutime, before and after the sleep?
Thanks, Vicente
Log outputs from Android emulator are: times()-begin: c1=13829 tm1.tms_stime + tm1.tms_cstime=18, tm1.tms_utime + tm1.tms_cutime=638 times()-end: c2=13966 tm2.tms_stime + tm2.tms_cstime=18, tm2.tms_utime + tm2.tms_cutime=670 real 0.001s, cpu 0.000s (23.9%), user 0.000s, system 0.000s thread_clock: wall=1376ms, cpu=318ms Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor,
Log outputs from Android emulator are: times()-begin: c1=13829 tm1.tms_stime + tm1.tms_cstime=18, tm1.tms_utime + tm1.tms_cutime=638 times()-end: c2=13966 tm2.tms_stime + tm2.tms_cstime=18, tm2.tms_utime + tm2.tms_cutime=670 real 0.001s, cpu 0.000s (23.9%), user 0.000s, system 0.000s thread_clock: wall=1376ms, cpu=318ms
Could the problem be with the Android emulator rather than Android itself? Google seems to find multiple reports of problems with the Android emulator related to time. --Beman

Beman Dawes wrote:
Libor,
Log outputs from Android emulator are: times()-begin: c1=13829 tm1.tms_stime + tm1.tms_cstime=18, tm1.tms_utime + tm1.tms_cutime=638 times()-end: c2=13966 tm2.tms_stime + tm2.tms_cstime=18, tm2.tms_utime + tm2.tms_cutime=670 real 0.001s, cpu 0.000s (23.9%), user 0.000s, system 0.000s thread_clock: wall=1376ms, cpu=318ms
Could the problem be with the Android emulator rather than Android itself?
Google seems to find multiple reports of problems with the Android emulator related to time.
--Beman
Hello Beman and Vicente, it does not seem that the problem in stopclock test is caused by Android emulator. I have similar results from Android HW (BeagleBoard xM) and Linux PC (Ubuntu 11.04). Here is summary of stopclock test outputs on all tested platforms: Windows Vista: stopwatches::stopclock<>: real 1.031s, cpu 0.031s (3.0%), user 0.031s, system 0.000s thread_clock: wall=1031ms, cpu=31ms Android emulator: stopwatches::stopclock<>: real 0.001s, cpu 0.000s (23.2%), user 0.000s, system 0.000s thread_clock: wall=1377ms, cpu=312ms Android on BeagleBoard: stopwatches::stopclock<>: real 0.001s, cpu 0.000s (12.3%), user 0.000s, system 0.000s thread_clock: wall=1140ms, cpu=139ms Linux Ubuntu 11.04 (x86): stopwatches::stopclock<>: real 0.001s, cpu 0.000s (3.9%), user 0.000s, system 0.000s thread_clock: wall=1035ms, cpu=34ms My impression is that text output of stopwatches::stopclock<> on Android/Linux is 1000x less than shall be, so the printed values are not seconds but milliseconds. BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Hello Vicente, thanks for the fast answer and your great library!
You can rely on #if defined ANDROID.
Is CLOCK_THREAD_CPUTIME_ID a macro on this platform? I would prefer to check if CLOCK_THREAD_CPUTIME_ID is defined and use it. Would it be the correct behavior? could you try this patch // chrono/config.hpp # if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif # if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif // posix/thread_clock.hpp ... #if defined CLOCK_THREAD_CPUTIME_ID if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) #else // get the current thread pthread_t pth=pthread_self(); // get the clock_id associated to the current thread clockid_t clock_id; pthread_getcpuclockid(pth, &clock_id); // get the timespec associated to the thread clock if ( ::clock_gettime( clock_id, &ts ) ) #endif Best, Vicente Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet wrote:
Is CLOCK_THREAD_CPUTIME_ID a macro on this platform? I would prefer to check if CLOCK_THREAD_CPUTIME_ID is defined and use it. Would it be the correct behavior?
Yes, is defined like: #define CLOCK_THREAD_CPUTIME_ID 3 in time.h. Vicente Botet wrote:
could you try this patch
// chrono/config.hpp
# if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif # if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif
This causes compilation error because BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC is undefined in chrono/thread_clock.hpp: BOOST_CHRONO_STATIC_CONSTEXPR bool is_monotonic = BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC; However following patch works for me: # if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif # if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif I'm not sure about BOOST_DISABLE_THREADS. Vicente Botet wrote:
// posix/thread_clock.hpp ... #if defined CLOCK_THREAD_CPUTIME_ID if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) #else // get the current thread pthread_t pth=pthread_self(); // get the clock_id associated to the current thread clockid_t clock_id; pthread_getcpuclockid(pth, &clock_id); // get the timespec associated to the thread clock if ( ::clock_gettime( clock_id, &ts ) ) #endif
On Android works fine for me. BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Vicente Botet wrote:
Is CLOCK_THREAD_CPUTIME_ID a macro on this platform? I would prefer to check if CLOCK_THREAD_CPUTIME_ID is defined and use it. Would it be the correct behavior?
Yes, is defined like: #define CLOCK_THREAD_CPUTIME_ID 3 in time.h.
Great. I will use this macro then, which seems to be more general.
Vicente Botet wrote:
could you try this patch
// chrono/config.hpp
# if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif # if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_STEADY true # endif
This causes compilation error because BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC is undefined in chrono/thread_clock.hpp: BOOST_CHRONO_STATIC_CONSTEXPR bool is_monotonic = BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC;
However following patch works for me: # if defined(_POSIX_THREAD_CPUTIME) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif # if defined(CLOCK_THREAD_CPUTIME_ID) && !defined(BOOST_DISABLE_THREADS) # define BOOST_CHRONO_HAS_THREAD_CLOCK # define BOOST_CHRONO_THREAD_CLOCK_IS_MONOTONIC true # endif I'm not sure about BOOST_DISABLE_THREADS.
Oh, I see. You are not using the lib in the trunk which has replaced monotonic clocks by steady clocks.
Vicente Botet wrote:
// posix/thread_clock.hpp ... #if defined CLOCK_THREAD_CPUTIME_ID if ( ::clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts ) ) #else // get the current thread pthread_t pth=pthread_self(); // get the clock_id associated to the current thread clockid_t clock_id; pthread_getcpuclockid(pth, &clock_id); // get the timespec associated to the thread clock if ( ::clock_gettime( clock_id, &ts ) ) #endif
On Android works fine for me.
I have committed it on trunk. I will see how this behaves on the regression compilers before moving it to the release branch. I would appreciate if you create a ticket on the Trac system. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet wrote:
I have committed it on trunk. I will see how this behaves on the regression compilers before moving it to the release branch. I would appreciate if you create a ticket on the Trac system.
Great. I created ticked #5543. I checked your changes on trunk, please copy the change also to thread_clock::time_point thread_clock::now( ). BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Vicente Botet wrote:
I have committed it on trunk. I will see how this behaves on the regression compilers before moving it to the release branch. I would appreciate if you create a ticket on the Trac system.
Great. I created ticked #5543. I checked your changes on trunk, please copy the change also to thread_clock::time_point thread_clock::now( ).
Please, could you be more specific? Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet wrote:
Libor Bus wrote:
Vicente Botet wrote:
I have committed it on trunk. I will see how this behaves on the regression compilers before moving it to the release branch. I would appreciate if you create a ticket on the Trac system.
Great. I created ticked #5543. I checked your changes on trunk, please copy the change also to thread_clock::time_point thread_clock::now( ).
Please, could you be more specific?
Best, Vicente
... you updated function: thread_clock::now( system::error_code & ec ) but the same change shall be done also in function: thread_clock::now( ) BR, Libor -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

Libor Bus wrote:
Vicente Botet wrote:
Libor Bus wrote:
Vicente Botet wrote:
I have committed it on trunk. I will see how this behaves on the regression compilers before moving it to the release branch. I would appreciate if you create a ticket on the Trac system.
Great. I created ticked #5543. I checked your changes on trunk, please copy the change also to thread_clock::time_point thread_clock::now( ).
Please, could you be more specific?
... you updated function: thread_clock::now( system::error_code & ec ) but the same change shall be done also in function: thread_clock::now( )
Sorry. Committed revision 71951. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/chrono-Thread-clock-compatibility-problem... Sent from the Boost - Dev mailing list archive at Nabble.com.

"Vicente Botet" <vicente.botet@wanadoo.fr>wrote:
... you updated function: thread_clock::now( system::error_code & ec ) but the same change shall be done also in function: thread_clock::now( )
Sorry. Committed revision 71951.
Time to get rid of the duplicated code in all the now()-functions in chrono by making one of the functions call the other? It's a code maintenance nightmare waiting to happen - except it already happened :)

Message du 17/05/11 00:19 De : "Niklas Angare"
A : boost@lists.boost.org Copie à : Objet : [boost] [chrono]Duplicated code in now() functions (was: Thread clock compatibility problems on Android)
"Vicente Botet" wrote:
... you updated function: thread_clock::now( system::error_code & ec ) but the same change shall be done also in function: thread_clock::now( )
Sorry. Committed revision 71951.
Time to get rid of the duplicated code in all the now()-functions in chrono by making one of the functions call the other? It's a code maintenance nightmare waiting to happen - except it already happened :)
Hi, I will consider your suggestion, but not before the release. You could add a Task ticket if you want this to be tracked. Thanks, Vicente
participants (5)
-
Beman Dawes
-
Libor Bus
-
Niklas Angare
-
Vicente Botet
-
Vicente BOTET