Discussion:
std::chrono::high_resolution_clock::now throwing exception in Safari (when ASM.JS is run in webworker)
Gaurav Dewan
2016-07-25 10:24:48 UTC
Permalink
Based on quick read of C++ specs (although more thorough reading of C++
specs would be required),
(1) std::chrono::high_resolution_clock::now is declared to be
no-except(cannot throw exceptions).
(2) high_resolution_-clock may be a synonym for system_clock or steady_clock

When calling this function in Safari ASM.JS worker(Mac),
The test program is same as:
https://github.com/kripken/emscripten/issues/2980
It's just that this asm.js is loaded from javascript webworker.

Function *__ZNSt3__16chrono12steady_clock3nowE *calls *__ZNSt3__120__throw_system_errorEiPKc
(via *invoke_vii).
Shouldn't emscripten fallback to Date.now() if Performance.now() is not
implemented ?
--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alon Zakai
2016-07-25 17:56:16 UTC
Permalink
Yes, all I can see is code that checks if performance exists first, then
uses a fallback if not (on current incoming). Do you have a specific stack
trace showing where in the code it fails for you?
Post by Gaurav Dewan
Based on quick read of C++ specs (although more thorough reading of C++
specs would be required),
(1) std::chrono::high_resolution_clock::now is declared to be
no-except(cannot throw exceptions).
(2) high_resolution_-clock may be a synonym for system_clock or steady_clock
When calling this function in Safari ASM.JS worker(Mac),
https://github.com/kripken/emscripten/issues/2980
It's just that this asm.js is loaded from javascript webworker.
Function *__ZNSt3__16chrono12steady_clock3nowE *calls *__ZNSt3__120__throw_system_errorEiPKc
(via *invoke_vii).
Shouldn't emscripten fallback to Date.now() if Performance.now() is not
implemented ?
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Gaurav Dewan
2016-07-27 14:07:59 UTC
Permalink
To reproduce, on emscripten 1.36.5 (incoming branch)
(1) here is simple test case (c.cpp)
#include <chrono>
#include <iostream>


int
main()
{
std::cout << "before" << std::endl;
auto now = std::chrono::high_resolution_clock::now();
std::cout << "after" << std::endl;
return 0;
}

(2) Compile it using
em++ c.cpp -o c.html

(3) In generated c.js, add following line as first line (To simulate
Safari/IE/Edge webworker environment restriction on FF/Chrome)
performance={};

Output:
Only before is printed followed by exception (some implementations of
boost::chrono::steady_clock::now may throw exception; but here we are using
std::chrono )

Reason:

*__ZNSt3__26chrono12steady_clock3nowEv *(_std::__2::chrono::
*steady_clock::now(*)) calls (via invoke_ii) *_clock_gettime(*clk_id
=1,tp)
*_clock_gettime *calls*_emscripten_get_now_is_monotonic* which return false
*_clock_gettime* then sets error number and return -1.
*__ZNSt3__26chrono12steady_clock3nowEv *on seeing this error throws if
exceptions are enabled *or *continue (with unexpected time value) if
exceptions are disabled.
YES, _emscripten_get_now checks if performance exists and then uses a
fallback but it is not called due to monotonicity test failure


Other consideration:
As mentioned in comment, Date.now does not guarantee monotonicty and it may
be issue depending on some implementation. An answer here indicate how
Date.now can be forced to be monotonic:
http://stackoverflow.com/questions/7272395/monotonically-increasing-time-in-javascript
--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alon Zakai
2016-07-27 19:05:33 UTC
Permalink
Ok, I see - the issue isn't that we try to use the performance object when
it isn't there, but that when it isn't there, we don't have a monotonic
clock, and we report that correctly. That C++ STL functionality happens to
require a monotonic clock, so when it finds we don't have that, it throws a
C++ exception.

Not sure what we can do here. Forcing Date.now to be monotonic is tricky,
it could be very inaccurate and cause surprising behavior.
To reproduce, on emscripten 1.36.5 (incoming branch)
(1) here is simple test case (c.cpp)
#include <chrono>
#include <iostream>
int
main()
{
std::cout << "before" << std::endl;
auto now = std::chrono::high_resolution_clock::now();
std::cout << "after" << std::endl;
return 0;
}
(2) Compile it using
em++ c.cpp -o c.html
(3) In generated c.js, add following line as first line (To simulate
Safari/IE/Edge webworker environment restriction on FF/Chrome)
performance={};
Only before is printed followed by exception (some implementations of
boost::chrono::steady_clock::now may throw exception; but here we are using
std::chrono )
*steady_clock::now(*)) calls (via invoke_ii) *_clock_gettime(*clk_id
=1,tp)
*_clock_gettime *calls*_emscripten_get_now_is_monotonic* which return false
*_clock_gettime* then sets error number and return -1.
*__ZNSt3__26chrono12steady_clock3nowEv *on seeing this error throws if
exceptions are enabled *or *continue (with unexpected time value) if
exceptions are disabled.
YES, _emscripten_get_now checks if performance exists and then uses a
fallback but it is not called due to monotonicity test failure
As mentioned in comment, Date.now does not guarantee monotonicty and it
may be issue depending on some implementation. An answer here indicate how
http://stackoverflow.com/questions/7272395/monotonically-increasing-time-in-javascript
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alon Zakai
2016-07-27 19:06:53 UTC
Permalink
As a workaround, you can polyfill performance and its now() method (with
something that forces Date.now() to be monotonic). I'm worried about doing
that by default, but if it works for your app it's a simple solution.
Post by Alon Zakai
Ok, I see - the issue isn't that we try to use the performance object when
it isn't there, but that when it isn't there, we don't have a monotonic
clock, and we report that correctly. That C++ STL functionality happens to
require a monotonic clock, so when it finds we don't have that, it throws a
C++ exception.
Not sure what we can do here. Forcing Date.now to be monotonic is tricky,
it could be very inaccurate and cause surprising behavior.
To reproduce, on emscripten 1.36.5 (incoming branch)
(1) here is simple test case (c.cpp)
#include <chrono>
#include <iostream>
int
main()
{
std::cout << "before" << std::endl;
auto now = std::chrono::high_resolution_clock::now();
std::cout << "after" << std::endl;
return 0;
}
(2) Compile it using
em++ c.cpp -o c.html
(3) In generated c.js, add following line as first line (To simulate
Safari/IE/Edge webworker environment restriction on FF/Chrome)
performance={};
Only before is printed followed by exception (some implementations of
boost::chrono::steady_clock::now may throw exception; but here we are using
std::chrono )
*steady_clock::now(*)) calls (via invoke_ii) *_clock_gettime(*clk_id
=1,tp)
*_clock_gettime *calls*_emscripten_get_now_is_monotonic* which return false
*_clock_gettime* then sets error number and return -1.
*__ZNSt3__26chrono12steady_clock3nowEv *on seeing this error throws if
exceptions are enabled *or *continue (with unexpected time value) if
exceptions are disabled.
YES, _emscripten_get_now checks if performance exists and then uses a
fallback but it is not called due to monotonicity test failure
As mentioned in comment, Date.now does not guarantee monotonicty and it
may be issue depending on some implementation. An answer here indicate how
http://stackoverflow.com/questions/7272395/monotonically-increasing-time-in-javascript
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...