hrtimer going off sooner than what I programmed it - android

I am trying to set of a hrtimer to generate period function call backs at absolute intervals.
Initializing the timer as
hrtimer_init(&p->rt_track.rt_period_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
Function assignment is being done as
p->rt_track.rt_period_timer.function = new_period_actions;
Function prototype is
enum hrtimer_restart new_period_actions(struct hrtimer *timer);
Setting off timer as
hrtimer_start(&p->rt_track.rt_period_timer, ktime_set(t.tv_sec, t.tv_nsec), HRTIMER_MODE_REL);
Even though the timespec t is = (10 secs , 0 nsecs) (while I am testing) the timer keeps going of within a few milliseconds causes the kernel to crash by overwhelming the system I guess.
I want to control the timer callback duration by programming the timespec t.
Can someone please tell me what I might be doing wrong?

Solved it using timer forwarding
now = hrtimer_cb_get_time(timer);
hrtimer_forward(timer, now,ktime_set(rtt->T.tv_sec,rtt->T.tv_nsec) );

Related

High frequency UI update - Android

I want to make 8 squares change colors between red/black periodically.
I acomplish this using timer.schedule with period time in milliseconds and it work
BUT then I realized that I need to use small time between this transitions (example nanoseconds).
To accomplish that I wrote this code:
timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run(){
//CODE OF THE TASK.
}
});
}
};
//To make schedule this task in 5 nanoseconds I use this!
exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleAtFixedRate(timerTask, 0, 5, TimeUnit.NANOSECONDS);
But when I run this, the UI is not updating (seems to be stuck), but in logcat, all the logs are printing very fast. How can I achieve to make a task periodically x nanoseconds?
The entire Android UI runs at 60Hz- 60 updates per second. This means the minimum time between redraws is 16 ms. You cannot run it at a higher framerate. Nor are human eyes capable of seeing changes at a much higher frequency than that.
iOS and most video game consoles also work on a 60 Hz refresh rate. You'd find very few to no systems that go faster.
I'm not sure what exactly you're trying to accomplish, but I'm fairly certain you're trying to do it the wrong way.
ALSO: I notice your timer task posts to a handler. That means your timer task is going to tell the main thread to run something, and the timer task is running in nanoseconds. YOu're basically going to choke your main thread full of "run this task" messages, then eventually crash with an OOM error when the event queue becomes so massive it can't add any more (which may take several minutes), because there's no way you're processing them fast enough with the thread switching overhead.
After doing a lot of research, I realized that in order to get the view to refresh so quickly, I needed the use of SurfaceView and a Thread to make the UI redraw very fast, I really had no knowledge of this. Thanks for the help

Android NDK Sensor strange report interval to event queue

I try to access the accelerometer from the NDK. So far it works. But the way events are written to the eventqueue seems a little bit strange.
See the following code:
ASensorManager* AcquireASensorManagerInstance(void) {
typedef ASensorManager *(*PF_GETINSTANCEFORPACKAGE)(const char *name);
void* androidHandle = dlopen("libandroid.so", RTLD_NOW);
PF_GETINSTANCEFORPACKAGE getInstanceForPackageFunc = (PF_GETINSTANCEFORPACKAGE) dlsym(androidHandle, "ASensorManager_getInstanceForPackage");
if (getInstanceForPackageFunc) {
return getInstanceForPackageFunc(kPackageName);
}
typedef ASensorManager *(*PF_GETINSTANCE)();
PF_GETINSTANCE getInstanceFunc = (PF_GETINSTANCE) dlsym(androidHandle, "ASensorManager_getInstance");
return getInstanceFunc();
}
void init() {
sensorManager = AcquireASensorManagerInstance();
accelerometer = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
accelerometerEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID_USER, NULL, NULL);
auto status = ASensorEventQueue_enableSensor(accelerometerEventQueue,
accelerometer);
status = ASensorEventQueue_setEventRate(accelerometerEventQueue,
accelerometer,
SENSOR_REFRESH_PERIOD_US);
}
That's how I initialize everything. My SENSOR_REFRESH_PERIOD_US is 100.000 - so 10 refreshs per second. Now I have the following method to receive the events of the event queue.
vector<sensorEvent> update() {
ALooper_pollAll(0, NULL, NULL, NULL);
vector<sensorEvent> listEvents;
ASensorEvent event;
while (ASensorEventQueue_getEvents(accelerometerEventQueue, &event, 1) > 0) {
listEvents.push_back(sensorEvent{event.acceleration.x, event.acceleration.y, event.acceleration.z, (long long) event.timestamp});
}
return listEvents;
}
sensorEvent at this point is a custom struct which I use. This update method gets called via JNI from Android every 10 seconds from an IntentService (to make sure it runs even when the app itself is killed). Now I would expect to receive 100 values (10 per second * 10 seconds). In different tests I received around 130 which is also completly fine for me even it's a bit off. Then I read in the documentation of ASensorEventQueue_setEventRate that it's not forced to follow the given refresh period. So if I would get more than I wanted it would be totally fine.
But now the problem: Sometimes I receive like 13 values in 10 seconds and when I continue to call update 10 secods later I get the 130 values + the missing 117 of the run before. This happens completly random and sometimes it's not the next run but the fourth following or something like that.
I am completly fine with being off from the refresh period by having more values. But can anyone explain why it happens that there are so many values missing and they appear 10 seconds later in the next run? Or is there maybe a way to make sure I receive them in their desired run?
Your code is correct and as i see only one reason can be cause such behaviour. It is android system, for avoid drain battery, decreases frequency of accelerometer stream of events in some time after app go to background or device fall asleep.
You need to revise all axelerometer related logic and optimize according
Doze and App Standby
Also you can try to work with axelerometer in foreground service.

How do I work with the system clock / time in xamarin forms?

for a school project i'm making an app. The app is supposed to keep track of the time that you spend working on something specific. For example when i'm going to start my work shift, I would press a (start)button so the timer starts off and counts how much I've worked until i press a stop button.
I've got the xaml ready with all the buttons and labels.
My main problem is the timer. I would like to have a stopwatch underneath my start button, that shows the elapsed time. I've been looking for many many hours on github, stackoverflow, google and youtube and haven't found a solution.
If it isn't easy/possible to implement a stopwatch, i would at least need the app to check for the system time when the start and stop buttons are clicked, to calculate the difference in time.
So far I haven't been able to get any of those functions working.
Thanks in advance! - MagSky
.NET has a built in Stopwatch class you can use
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
// do some work here
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
to display a Timer in the UI, use System.Timers.Timer instead
int secs = 0;
// fire an event every 1000 ms
Timer timer = new Timer(1000);
// when event fires, update Label
timer.Elapsed += (sender, e) => { secs++; myLabel.Text = $"{secs} seconds"; };
// start the timer
timer.Start();

C++11 std::chrono::steady_clock issue on Android

I have been using std::chrono::steady_clock for interval calculation in an application i am making for Android platform.
Code:
// On application start
auto timeSinceEpoch = std::chrono::steady_clock::now().time_since_epoch();
auto timeInSec = std::chrono::duration_cast<seconds>(timeSinceEpoch).count();
log("On Enter Start Time Point - %lld", timeInSec);
Output:
On Enter Start Time Point - 521
Now i switch off the phone and restart the phone. I run my application and this time Output is:
On Enter Start Time Point - 114
As per definition at cppreference.com
"Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward."
How is the output when i restart the phone giving lesser value?
If anyone has faced this issue please help me out here. Thanks!!
The formal requirement for a steady clock is that the result of a call to now() that happens before another call to now() is always less than or equal to the result of the second call. The happens before relationship only applies to actions within a program run. A steady clock is not required to be steady across different invocations of a program.
On Android, AFAICT steady_clock is the same as (from Java) System.Clock.elapsedRealtime, which resets to zero on boot -- https://developer.android.com/reference/android/os/SystemClock.html
I'm totally failing to dig up the source code for clock_gettime, though. https://android.googlesource.com/platform/ndk.git/+/43255f3d58b03cd931d29d1ee4e5144e86e875ce/sources/cxx-stl/llvm-libc++/libcxx/src/chrono.cpp#124 shows it calling clock_gettime(CLOCK_MONOTONIC), but I'm not sure how to penetrate the veil from there.

Precision of delay

I have a problem with this code used for Android (Java)
handler.postDelayed(new Runnable(){
public void run(){
// Your code goes here...
}
}, 500);
If the delay is about 500ms then the program seems to repeat the task at 0.5s, but if I change to less than 100ms or even less it does not follow any more. I test the brightness change and for a while it can repeat the change of brightness at that rate, but then slow down and come back to normal flash rate again. It seems unstable. Do you have any code that give exact delay regardless of the load of the phone's CPU.
Many thanks
Not from Java, no; stock Java isn't a real-time system.
Timing precision is subject to the whims of the JVM and the OS's scheduler. You may be able to get incrementally more precise, but there's no guarantee of the kind of precision you're looking for.
You might be able to do something more precise if you use a CountDownTimer which has a periodic tick. Essentially you set it to count down for a period which can be hours if need be, and there are two methods one method is called on each tick, and the other at the end of the timer at which point you could start another one. Anyway you could set the tick to be very fast, and then only kick off the code at the delay point by check the actual time difference in the click. I think thats about the best you could do. Essentially inside the tick you would issue a signal if the right amout of time had actually passed. That signal would either kick off the thread or release something the already running thread was waiting on. What is the value of the CountDownTimer, I guess its just that you can do a very frequent polling, and elapsed time check. Although its not guaranteed, the time between the ticks you can set it to a high frequency and check/poll very frequently. This could lead to a smooth performance not unlike a realtime system. Its more likely to be accurate because its just issuing a signal and not taking up the resources of threading just to issue the signal. You might also try an IntentService to perform the tasks and just call startService(intentToIntentService) each call. See if the threading works better inside a service like IntentService which does queue them up I believe.
Date startDate = new Date();
long startTime = startDate.getTime();
// Tick called every 10th of a second. OnFinish called at Signal.
CountDownTimer ctDownTimer = new CountDownTimer(30000, 100) {
long startIntervalTime=startTime;
public void onTick(long millisUntilFinished) {
Date now = new Date();
long nowTime = now.getTime();
if ((startIntervalTime - nowTime) > 100)
{
issueSignal();
intervalStartTime=nowTime;
}
now=null;
}
public void onFinish() {
Log.d("MyClass", "Done") // Maybe start out.
}
}.start();

Categories

Resources