java_lang_VMThread.c revision 7365493ad8d360c1dcf9cd8b6eee62747af01cae
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* 18 * java.lang.VMThread 19 */ 20#include "Dalvik.h" 21#include "native/InternalNativePriv.h" 22 23 24/* 25 * static void create(Thread t, long stacksize) 26 * 27 * This is eventually called as a result of Thread.start(). 28 * 29 * Throws an exception on failure. 30 */ 31static void Dalvik_java_lang_VMThread_create(const u4* args, JValue* pResult) 32{ 33 Object* threadObj = (Object*) args[0]; 34 s8 stackSize = GET_ARG_LONG(args, 1); 35 36 /* copying collector will pin threadObj for us since it was an argument */ 37 dvmCreateInterpThread(threadObj, (int) stackSize); 38 RETURN_VOID(); 39} 40 41/* 42 * static Thread currentThread() 43 */ 44static void Dalvik_java_lang_VMThread_currentThread(const u4* args, 45 JValue* pResult) 46{ 47 UNUSED_PARAMETER(args); 48 49 RETURN_PTR(dvmThreadSelf()->threadObj); 50} 51 52/* 53 * void getStatus() 54 * 55 * Gets the Thread status. Result is in VM terms, has to be mapped to 56 * Thread.State by interpreted code. 57 */ 58static void Dalvik_java_lang_VMThread_getStatus(const u4* args, JValue* pResult) 59{ 60 Object* thisPtr = (Object*) args[0]; 61 Thread* thread; 62 int result; 63 64 dvmLockThreadList(NULL); 65 thread = dvmGetThreadFromThreadObject(thisPtr); 66 if (thread != NULL) 67 result = thread->status; 68 else 69 result = THREAD_ZOMBIE; // assume it used to exist and is now gone 70 dvmUnlockThreadList(); 71 72 RETURN_INT(result); 73} 74 75/* 76 * boolean holdsLock(Object object) 77 * 78 * Returns whether the current thread has a monitor lock on the specific 79 * object. 80 */ 81static void Dalvik_java_lang_VMThread_holdsLock(const u4* args, JValue* pResult) 82{ 83 Object* thisPtr = (Object*) args[0]; 84 Object* object = (Object*) args[1]; 85 Thread* thread; 86 87 if (object == NULL) { 88 dvmThrowException("Ljava/lang/NullPointerException;", NULL); 89 RETURN_VOID(); 90 } 91 92 dvmLockThreadList(NULL); 93 thread = dvmGetThreadFromThreadObject(thisPtr); 94 int result = dvmHoldsLock(thread, object); 95 dvmUnlockThreadList(); 96 97 RETURN_BOOLEAN(result); 98} 99 100/* 101 * void interrupt() 102 * 103 * Interrupt a thread that is waiting (or is about to wait) on a monitor. 104 */ 105static void Dalvik_java_lang_VMThread_interrupt(const u4* args, JValue* pResult) 106{ 107 Object* thisPtr = (Object*) args[0]; 108 Thread* thread; 109 110 dvmLockThreadList(NULL); 111 thread = dvmGetThreadFromThreadObject(thisPtr); 112 if (thread != NULL) 113 dvmThreadInterrupt(thread); 114 dvmUnlockThreadList(); 115 RETURN_VOID(); 116} 117 118/* 119 * static boolean interrupted() 120 * 121 * Determine if the current thread has been interrupted. Clears the flag. 122 */ 123static void Dalvik_java_lang_VMThread_interrupted(const u4* args, 124 JValue* pResult) 125{ 126 Thread* self = dvmThreadSelf(); 127 bool interrupted; 128 129 UNUSED_PARAMETER(args); 130 131 interrupted = self->interrupted; 132 self->interrupted = false; 133 RETURN_BOOLEAN(interrupted); 134} 135 136/* 137 * boolean isInterrupted() 138 * 139 * Determine if the specified thread has been interrupted. Does not clear 140 * the flag. 141 */ 142static void Dalvik_java_lang_VMThread_isInterrupted(const u4* args, 143 JValue* pResult) 144{ 145 Object* thisPtr = (Object*) args[0]; 146 Thread* thread; 147 bool interrupted; 148 149 dvmLockThreadList(NULL); 150 thread = dvmGetThreadFromThreadObject(thisPtr); 151 if (thread != NULL) 152 interrupted = thread->interrupted; 153 else 154 interrupted = false; 155 dvmUnlockThreadList(); 156 157 RETURN_BOOLEAN(interrupted); 158} 159 160/* 161 * void nameChanged(String newName) 162 * 163 * The name of the target thread has changed. We may need to alert DDMS. 164 */ 165static void Dalvik_java_lang_VMThread_nameChanged(const u4* args, 166 JValue* pResult) 167{ 168 Object* thisPtr = (Object*) args[0]; 169 StringObject* nameStr = (StringObject*) args[1]; 170 Thread* thread; 171 int threadId = -1; 172 173 /* get the thread's ID */ 174 dvmLockThreadList(NULL); 175 thread = dvmGetThreadFromThreadObject(thisPtr); 176 if (thread != NULL) 177 threadId = thread->threadId; 178 dvmUnlockThreadList(); 179 180 dvmDdmSendThreadNameChange(threadId, nameStr); 181 //char* str = dvmCreateCstrFromString(nameStr); 182 //LOGI("UPDATE: threadid=%d now '%s'\n", threadId, str); 183 //free(str); 184 185 RETURN_VOID(); 186} 187 188/* 189 * void setPriority(int newPriority) 190 * 191 * Alter the priority of the specified thread. "newPriority" will range 192 * from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY (1-10), with "normal" 193 * threads at Thread.NORM_PRIORITY (5). 194 */ 195static void Dalvik_java_lang_VMThread_setPriority(const u4* args, 196 JValue* pResult) 197{ 198 Object* thisPtr = (Object*) args[0]; 199 int newPriority = args[1]; 200 Thread* thread; 201 202 dvmLockThreadList(NULL); 203 thread = dvmGetThreadFromThreadObject(thisPtr); 204 if (thread != NULL) 205 dvmChangeThreadPriority(thread, newPriority); 206 //dvmDumpAllThreads(false); 207 dvmUnlockThreadList(); 208 209 RETURN_VOID(); 210} 211 212/* 213 * static void sleep(long msec, int nsec) 214 */ 215static void Dalvik_java_lang_VMThread_sleep(const u4* args, JValue* pResult) 216{ 217 dvmThreadSleep(GET_ARG_LONG(args,0), args[2]); 218 RETURN_VOID(); 219} 220 221/* 222 * public void yield() 223 * 224 * Causes the thread to temporarily pause and allow other threads to execute. 225 * 226 * The exact behavior is poorly defined. Some discussion here: 227 * http://www.cs.umd.edu/~pugh/java/memoryModel/archive/0944.html 228 */ 229static void Dalvik_java_lang_VMThread_yield(const u4* args, JValue* pResult) 230{ 231 UNUSED_PARAMETER(args); 232 233 sched_yield(); 234 235 RETURN_VOID(); 236} 237 238const DalvikNativeMethod dvm_java_lang_VMThread[] = { 239 { "create", "(Ljava/lang/Thread;J)V", 240 Dalvik_java_lang_VMThread_create }, 241 { "currentThread", "()Ljava/lang/Thread;", 242 Dalvik_java_lang_VMThread_currentThread }, 243 { "getStatus", "()I", 244 Dalvik_java_lang_VMThread_getStatus }, 245 { "holdsLock", "(Ljava/lang/Object;)Z", 246 Dalvik_java_lang_VMThread_holdsLock }, 247 { "interrupt", "()V", 248 Dalvik_java_lang_VMThread_interrupt }, 249 { "interrupted", "()Z", 250 Dalvik_java_lang_VMThread_interrupted }, 251 { "isInterrupted", "()Z", 252 Dalvik_java_lang_VMThread_isInterrupted }, 253 { "nameChanged", "(Ljava/lang/String;)V", 254 Dalvik_java_lang_VMThread_nameChanged }, 255 { "setPriority", "(I)V", 256 Dalvik_java_lang_VMThread_setPriority }, 257 { "sleep", "(JI)V", 258 Dalvik_java_lang_VMThread_sleep }, 259 { "yield", "()V", 260 Dalvik_java_lang_VMThread_yield }, 261 { NULL, NULL, NULL }, 262}; 263