Renderscript rs.finish(), allocation.syncAll(), copyTo() : wait till kernel execution finishes - android

I am writing android renderscript code which requires back to back kernel calls (sometimes output of one kernel become input of other). I also have some global pointers, binded to memory from Java layer. Each kernel updates those global pointers and outputs something. I hav e to make sure that execute of kernel1 is finished, before kernel2 starts execution.
I looked at android renderscript docs, but couldn't understand syncAll(Usage) and finish() well. Can anyone clarify how to achieve this behaviour?
Thanks
mScript.forEach_kernel1(mColorImageAllocation, tempAlloc);
// make sure kernel1 finishes, from android rs doc, copyTo should block
tempAlloc.copyTo(testOutputBitmap);
for (short i = 0; i < NUM_DIST; i++) {
mScript.set_gCurrentDistanceIndex(i);
mScript.forEach_kernel2(tempAlloc);
mRS.finish(); // wait till kernel2 finishes
}
In the above example, same kernel2 is called with different global parameters on kernel1's output.

For this code you don't need either. RS is a pipeline model so any work which could impact the result of a later command must be finished first by the driver.
syncAll() is used to sync memory spaces not execution. For example to propagate changes from script memory to graphics memory.

Related

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.

OpenSL ES Android: "Too many objects" SL_RESULT_MEMORY_FAILURE

I'm having a problem with OpenSL ES on Android. I'm using OpenSL to play sound effects. Currently I'm creating a new player each time I play a sound. (I know this isn't terribly efficient, but it's "good enough" for the time being.)
After a while of playback, I start to get these errors:
E/libOpenSLES(25131): Too many objects
W/libOpenSLES(25131): Leaving Engine::CreateAudioPlayer (SL_RESULT_MEMORY_FAILURE)
I'm tracking my create/destroy pattern and I never go above 4 outstanding objects at any given time, well below the system limit of 32. Of course, this is assuming that the Destroy is properly working.
My only guess right now is that I'm doing something incorrectly when I clean up the player objects. One possible issue is that the Destroy is often called in the context of the player callback (basically destroying the player after it's finished playing), although I can't find any reference suggesting this is a problem. Are there any other cleanup steps I should be taking besides "Destroy"-ing the player object? Do the Interfaces need to be cleaned up somehow as well?
-- Added --
After more testing, it happens consistently after the 30th player is created (there is an engine and a mix too, so that brings the total to 32 objects). So I must not be destroying the object properly. Here's the code--I'd love to know what's going wrong:
SLuint32 playerState = 0;
SLresult result = (*pPlayerObject)->GetState(pPlayerObject, &playerState);
return_if_fail(result);
if (playerState == SL_OBJECT_STATE_REALIZED)
{
(*pPlayerObject)->AbortAsyncOperation(pPlayerObject);
(*pPlayerObject)->Destroy(pPlayerObject);
}
else
{
__android_log_print(1, LOG_TAG, "Player object in unexpected state (%d)", playerState);
return 1002;
}
if (playerState == SL_OBJECT_STATE_REALIZED)
is not needed. Try to do it always.
AbortAsyncOperation is called in Destroy => not needed.
So try just (*pPlayerObject)->Destroy(pPlayerObject); it should be enough.
Edit:
I tested, and found solution.
You cannot call Destroy() from player callback. Should make "destroy" list and destroy it somewhere else, for example, in main thread.

how to deal with this case: andorid epoll_wait return -1 and errno=4 used ndk

I am writing network communication program with Android ndk, using epoll.
I found the method ‘epoll_wait’ woken not very accurate
while(1){
struct epoll_event events[3];
log_string("epoll_wait start");//here will print start time
events_len = epoll_wait(_epoll_fd, events, 3, 20 * 1000);// wait 20 second,for test,I use pipe instead of socket,monitor a pipe EPOLLIN event
if (events_len <= 0) {
log_string("epoll_wait end events_len=%d,errno=%d", events_len, errno);//Normally,the events_len always is 0,and errno is 0
}
}
The above code runs on the PC(like Ubuntun PC) is very normal,as expected.
If it runs on Android Phone(use Android Service , separate thread to run) is as expected at first.
After some time,epoll_wait becomes not very accurate,sometimes got -1 and errno=4,sometimes waited very long.
So I only know that phenomenon, but do not know why.
Can you tell why and tell me the best practices for use android epoll?
thx
4 is EINTR, which means your app got a signal. This isn't really an error, just restart epoll.
Regarding "waited very long", does your app hold at least a partial wakelock?

Accurate POSIX thread timing using NDK

I'm writing a simple NDK OpenSL ES audio app that records the users touches on a virtual piano keyboard and then plays them back forever over a set loop. After much experimenting and reading, I've settled on using a separate POSIX loop to achieve this. As you can see in the code it subtracts any processing time taken from the sleep time in order to make the interval of each loop as close to the desired sleep interval as possible (in this case it's 5000000 nanoseconds.
void init_timing_loop() {
pthread_t fade_in;
pthread_create(&fade_in, NULL, timing_loop, (void*)NULL);
}
void* timing_loop(void* args) {
while (1) {
clock_gettime(CLOCK_MONOTONIC, &timing.start_time_s);
tic_counter(); // simple logic gates that cycle the current tic
play_all_parts(); // for-loops through all parts and plays any notes (From an OpenSL buffer) that fall on the current tic
clock_gettime(CLOCK_MONOTONIC, &timing.finish_time_s);
timing.diff_time_s.tv_nsec = (5000000 - (timing.finish_time_s.tv_nsec - timing.start_time_s.tv_nsec));
nanosleep(&timing.diff_time_s, NULL);
}
return NULL;
}
The problem is that even using this the results are better, but quite inconsistent. sometimes notes will delay for perhaps even 50ms at a time, which makes for very wonky playback.
Is there a better way of approaching this? To debug I ran the following code:
gettimeofday(&timing.curr_time, &timing.tzp);
__android_log_print(ANDROID_LOG_DEBUG, "timing_loop", "gettimeofday: %d %d",
timing.curr_time.tv_sec, timing.curr_time.tv_usec);
Which gives a fairly consistent readout - that doesn't reflect the playback inaccuracies whatsoever. Are there other forces at work with Android preventing accurate timing? Or is OpenSL ES a potential issue? All the buffer data is loaded into memory - could there be bottlenecks there?
Happy to post more OpenSL code if needed... but at this stage I'm trying figure out if this thread loop is accurate or if there's a better way to do it.
You should consider seconds when using clock_gettime as well, you may get greater timing.start_time_s.tv_nsec than timing.finish_time_s.tv_nsec. tv_nsec starts from zero when tv_sec is increased.
timing.diff_time_s.tv_nsec =
(5000000 - (timing.finish_time_s.tv_nsec - timing.start_time_s.tv_nsec));
try something like
#define NS_IN_SEC 1000000000
(timing.finish_time_s.tv_sec * NS_IN_SEC + timing.finish_time_s.tv_nsec) -
(timing.start_time_s.tv_nsec * NS_IN_SEC + timing.start_time_s.tv_nsec)

android NDK mutex locking

I've been porting a cross platform C++ engine to Android, and noticed that it will inexplicably (and inconsistently) block when calling pthread_mutex_lock. This engine has already been working for many years on several platforms, and the problematic code hasn't changed in years, so I doubt it's a deadlock or otherwise buggy code. It must be my port to Android..
So far there are several places in the code that block on pthread_mutex_lock. It isn't entirely reproducible either. When it hangs, there's no suspicious output in LogCat.
I modified the mutex code like this (edited for brevity... real code checks all return values):
void MutexCreate( Mutex* m )
{
#ifdef WINDOWS
InitializeCriticalSection( m );
#else ANDROID
pthread_mutex_init( m, NULL );
#endif
}
void MutexDestroy( Mutex* m )
{
#ifdef WINDOWS
DeleteCriticalSection( m );
#else ANDROID
pthread_mutex_destroy( m, NULL );
#endif
}
void MutexLock( Mutex* m )
{
#ifdef WINDOWS
EnterCriticalSection( m );
#else ANDROID
pthread_mutex_lock( m );
#endif
}
void MutexUnlock( Mutex* m )
{
#ifdef WINDOWS
LeaveCriticalSection( m );
#else ANDROID
pthread_mutex_unlock( m );
#endif
}
I tried modifying MutexCreate to make error-checking and recursive mutexes, but it didn't matter. I wasn't even getting errors or log output either, so either that means my mutex code is just fine, or the errors/logs weren't being shown. How exactly does the OS notify you of bad mutex usage?
The engine makes heavy use of static variables, including mutexes. I can't see how, but is that a problem? I doubt it because I modified lots of mutexes to be allocated on the heap instead, and the same behavior occurred. But that may be because I missed some static mutexes. I'm probably grasping at straws here.
I read several references including:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_mutex_init.html
http://www.embedded-linux.co.uk/tutorial/mutex_mutandis
http://linux.die.net/man/3/pthread_mutex_init
Android NDK Mutex
Android NDK problem pthread_mutex_unlock issue
The "errorcheck" mutexes will check a couple of things (like attempts to use a non-recursive mutex recursively) but nothing spectacular.
You said "real code checks all return values", so presumably your code explodes if any pthread call returns a nonzero value. (Not sure why your pthread_mutex_destroy takes two args; assuming copy & paste error.)
The pthread code is widely used within Android and has no known hangups, so the issue is not likely in the pthread implementation itself.
The current implementation of mutexes fits in 32 bits, so if you print *(pthread_mutex_t* mut) as an integer you should be able to figure out what state it's in (technically, what state it was in at some point in the past). The definition in bionic/libc/bionic/pthread.c is:
/* a mutex is implemented as a 32-bit integer holding the following fields
*
* bits: name description
* 31-16 tid owner thread's kernel id (recursive and errorcheck only)
* 15-14 type mutex type
* 13 shared process-shared flag
* 12-2 counter counter of recursive mutexes
* 1-0 state lock state (0, 1 or 2)
*/
"Fast" mutexes have a type of 0, and don't set the tid field. In fact, a generic mutex will have a value of 0 (not held), 1 (held), or 2 (held, with contention). If you ever see a fast mutex whose value is not one of those, chances are something came along and stomped on it.
It also means that, if you configure your program to use recursive mutexes, you can see which thread holds the mutex by pulling the bits out (either by printing the mutex value when trylock indicates you're about to stall, or dumping state with gdb on a hung process). That, plus the output of ps -t, will let you know if the thread that locked the mutex still exists.

Categories

Resources