/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * java.lang.VMThread */ #include "Dalvik.h" #include "native/InternalNativePriv.h" /* * static void create(Thread t, long stacksize) * * This is eventually called as a result of Thread.start(). * * Throws an exception on failure. */ static void Dalvik_java_lang_VMThread_create(const u4* args, JValue* pResult) { Object* threadObj = (Object*) args[0]; s8 stackSize = GET_ARG_LONG(args, 1); /* copying collector will pin threadObj for us since it was an argument */ dvmCreateInterpThread(threadObj, (int) stackSize); RETURN_VOID(); } /* * static Thread currentThread() */ static void Dalvik_java_lang_VMThread_currentThread(const u4* args, JValue* pResult) { UNUSED_PARAMETER(args); RETURN_PTR(dvmThreadSelf()->threadObj); } /* * void getStatus() * * Gets the Thread status. Result is in VM terms, has to be mapped to * Thread.State by interpreted code. */ static void Dalvik_java_lang_VMThread_getStatus(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; Thread* thread; int result; dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); if (thread != NULL) result = thread->status; else result = THREAD_ZOMBIE; // assume it used to exist and is now gone dvmUnlockThreadList(); RETURN_INT(result); } /* * boolean holdsLock(Object object) * * Returns whether the current thread has a monitor lock on the specific * object. */ static void Dalvik_java_lang_VMThread_holdsLock(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; Object* object = (Object*) args[1]; Thread* thread; if (object == NULL) { dvmThrowNullPointerException("object == null"); RETURN_VOID(); } dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); int result = dvmHoldsLock(thread, object); dvmUnlockThreadList(); RETURN_BOOLEAN(result); } /* * void interrupt() * * Interrupt a thread that is waiting (or is about to wait) on a monitor. */ static void Dalvik_java_lang_VMThread_interrupt(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; Thread* thread; dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); if (thread != NULL) dvmThreadInterrupt(thread); dvmUnlockThreadList(); RETURN_VOID(); } /* * static boolean interrupted() * * Determine if the current thread has been interrupted. Clears the flag. */ static void Dalvik_java_lang_VMThread_interrupted(const u4* args, JValue* pResult) { Thread* self = dvmThreadSelf(); bool interrupted; UNUSED_PARAMETER(args); interrupted = self->interrupted; self->interrupted = false; RETURN_BOOLEAN(interrupted); } /* * boolean isInterrupted() * * Determine if the specified thread has been interrupted. Does not clear * the flag. */ static void Dalvik_java_lang_VMThread_isInterrupted(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; Thread* thread; bool interrupted; dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); if (thread != NULL) interrupted = thread->interrupted; else interrupted = false; dvmUnlockThreadList(); RETURN_BOOLEAN(interrupted); } /* * void nameChanged(String newName) * * The name of the target thread has changed. We may need to alert DDMS. */ static void Dalvik_java_lang_VMThread_nameChanged(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; StringObject* nameStr = (StringObject*) args[1]; Thread* thread; int threadId = -1; /* get the thread's ID */ dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); if (thread != NULL) threadId = thread->threadId; dvmUnlockThreadList(); dvmDdmSendThreadNameChange(threadId, nameStr); //char* str = dvmCreateCstrFromString(nameStr); //ALOGI("UPDATE: threadid=%d now '%s'", threadId, str); //free(str); RETURN_VOID(); } /* * void setPriority(int newPriority) * * Alter the priority of the specified thread. "newPriority" will range * from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY (1-10), with "normal" * threads at Thread.NORM_PRIORITY (5). */ static void Dalvik_java_lang_VMThread_setPriority(const u4* args, JValue* pResult) { Object* thisPtr = (Object*) args[0]; int newPriority = args[1]; Thread* thread; dvmLockThreadList(NULL); thread = dvmGetThreadFromThreadObject(thisPtr); if (thread != NULL) dvmChangeThreadPriority(thread, newPriority); //dvmDumpAllThreads(false); dvmUnlockThreadList(); RETURN_VOID(); } /* * static void sleep(long msec, int nsec) */ static void Dalvik_java_lang_VMThread_sleep(const u4* args, JValue* pResult) { dvmThreadSleep(GET_ARG_LONG(args,0), args[2]); RETURN_VOID(); } /* * public void yield() * * Causes the thread to temporarily pause and allow other threads to execute. * * The exact behavior is poorly defined. Some discussion here: * http://www.cs.umd.edu/~pugh/java/memoryModel/archive/0944.html */ static void Dalvik_java_lang_VMThread_yield(const u4* args, JValue* pResult) { UNUSED_PARAMETER(args); sched_yield(); RETURN_VOID(); } const DalvikNativeMethod dvm_java_lang_VMThread[] = { { "create", "(Ljava/lang/Thread;J)V", Dalvik_java_lang_VMThread_create }, { "currentThread", "()Ljava/lang/Thread;", Dalvik_java_lang_VMThread_currentThread }, { "getStatus", "()I", Dalvik_java_lang_VMThread_getStatus }, { "holdsLock", "(Ljava/lang/Object;)Z", Dalvik_java_lang_VMThread_holdsLock }, { "interrupt", "()V", Dalvik_java_lang_VMThread_interrupt }, { "interrupted", "()Z", Dalvik_java_lang_VMThread_interrupted }, { "isInterrupted", "()Z", Dalvik_java_lang_VMThread_isInterrupted }, { "nameChanged", "(Ljava/lang/String;)V", Dalvik_java_lang_VMThread_nameChanged }, { "setPriority", "(I)V", Dalvik_java_lang_VMThread_setPriority }, { "sleep", "(JI)V", Dalvik_java_lang_VMThread_sleep }, { "yield", "()V", Dalvik_java_lang_VMThread_yield }, { NULL, NULL, NULL }, };