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 */ 31 static 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 */ 44 static 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 */ 58 static 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 */ 81 static 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 dvmThrowNullPointerException("object == 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 */ 105 static 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 */ 123 static 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 */ 142 static 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 */ 165 static 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 //ALOGI("UPDATE: threadid=%d now '%s'", 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 */ 195 static 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 */ 215 static 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 */ 229 static 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 238 const 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