Revision: 29976
http://sourceforge.net/p/opalvoip/code/29976
Author: rjongbloed
Date: 2013-06-18 01:20:17 +0000 (Tue, 18 Jun 2013)
Log Message:
-----------
Hacks to be able to set thread priorities in Android. Can't use standard pthread functions as have to be root, but there is a Java interface, so if we are loaded using JNI, which is always the case, we use that API.
Modified Paths:
--------------
ptlib/trunk/src/ptlib/unix/tlibthrd.cxx
Modified: ptlib/trunk/src/ptlib/unix/tlibthrd.cxx
===================================================================
--- ptlib/trunk/src/ptlib/unix/tlibthrd.cxx 2013-06-18 01:12:56 UTC (rev 29975)
+++ ptlib/trunk/src/ptlib/unix/tlibthrd.cxx 2013-06-18 01:20:17 UTC (rev 29976)
@@ -54,6 +54,7 @@
#include <sys/syscall.h>
#elif defined(P_ANDROID)
#include <asm/page.h>
+#include <jni.h>
#endif
#ifdef P_HAS_SEMAPHORES_XPG6
@@ -61,7 +62,14 @@
#endif
#ifndef P_ANDROID
-#define P_USE_THREAD_CANCEL 1
+ #define P_USE_THREAD_CANCEL 1
+#else
+ static JavaVM * AndroidJavaVM;
+ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
+ {
+ AndroidJavaVM = vm;
+ return JNI_VERSION_1_6;
+ }
#endif
@@ -365,6 +373,9 @@
#endif
PProcess::Current().OnThreadStart(*this);
+
+ if (PX_priority != NormalPriority)
+ SetPriority(PX_priority);
}
@@ -458,13 +469,6 @@
process.InternalThreadStarted(this);
pthread_attr_destroy(&threadAttr);
-
-#ifdef P_MACOSX
- if (PX_priority == HighestPriority) {
- PTRACE(1, "set thread to have the highest priority (MACOSX)");
- SetPriority(HighestPriority);
- }
-#endif
}
@@ -605,6 +609,7 @@
void PThread::SetPriority(Priority priorityLevel)
{
+ PTRACE(4, "PTLib", "Setting thread priority to " << priorityLevel);
PX_priority = priorityLevel;
if (IsTerminated())
@@ -614,6 +619,57 @@
struct sched_param params;
PAssertPTHREAD(pthread_setschedparam, (m_threadId, GetSchedParam(priorityLevel, params), ¶ms));
+#elif defined(P_ANDROID)
+ if (Current() != this) {
+ PTRACE(2, "JNI", "Can only set priority for current thread.");
+ return;
+ }
+
+ if (AndroidJavaVM == NULL) {
+ PTRACE(2, "JNI", "JavaVM not set.");
+ return;
+ }
+
+ JNIEnv *jni = NULL;
+ bool detach = false;
+
+ jint err = AndroidJavaVM->GetEnv((void **)&jni, JNI_VERSION_1_6);
+ switch (err) {
+ case JNI_EDETACHED :
+ if ((err = AndroidJavaVM->AttachCurrentThread(&jni, NULL)) != JNI_OK) {
+ PTRACE(2, "JNI", "Could not attach JNI environment, error=" << err);
+ return;
+ }
+ detach = true;
+
+ case JNI_OK :
+ break;
+
+ default :
+ PTRACE(2, "JNI", "Could not get JNI environment, error=" << err);
+ return;
+ }
+
+ //Get pointer to the java class
+ jclass androidOsProcess = (jclass)jni->NewGlobalRef(jni->FindClass("android/os/Process"));
+ if (androidOsProcess != NULL) {
+ jmethodID setThreadPriority = jni->GetStaticMethodID(androidOsProcess, "setThreadPriority", "(I)V");
+ if (setThreadPriority != NULL) {
+ static const int Priorities[NumPriorities] = { 19, 10, 0, -10, -19 };
+ jni->CallStaticIntMethod(androidOsProcess, setThreadPriority, Priorities[priorityLevel]);
+ PTRACE(5, "JNI", "setThreadPriority " << Priorities[priorityLevel]);
+ }
+ else {
+ PTRACE(2, "JNI", "Could not find setThreadPriority");
+ }
+ }
+ else {
+ PTRACE(2, "JNI", "Could not find android.os.Process");
+ }
+
+ if (detach)
+ AndroidJavaVM->DetachCurrentThread();
+
#elif defined(P_MACOSX)
if (priorityLevel == HighestPriority) {
/* get fixed priority */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|