• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
Dalvik_java_lang_VMThread_create(const u4 * args,JValue * pResult)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     dvmCreateInterpThread(threadObj, (int) stackSize);
37     RETURN_VOID();
38 }
39 
40 /*
41  * static Thread currentThread()
42  */
Dalvik_java_lang_VMThread_currentThread(const u4 * args,JValue * pResult)43 static void Dalvik_java_lang_VMThread_currentThread(const u4* args,
44     JValue* pResult)
45 {
46     UNUSED_PARAMETER(args);
47 
48     RETURN_PTR(dvmThreadSelf()->threadObj);
49 }
50 
51 /*
52  * void getStatus()
53  *
54  * Gets the Thread status. Result is in VM terms, has to be mapped to
55  * Thread.State by interpreted code.
56  */
Dalvik_java_lang_VMThread_getStatus(const u4 * args,JValue * pResult)57 static void Dalvik_java_lang_VMThread_getStatus(const u4* args, JValue* pResult)
58 {
59     Object* thisPtr = (Object*) args[0];
60     Thread* thread;
61     int result;
62 
63     dvmLockThreadList(NULL);
64     thread = dvmGetThreadFromThreadObject(thisPtr);
65     if (thread != NULL)
66         result = thread->status;
67     else
68         result = THREAD_ZOMBIE;     // assume it used to exist and is now gone
69     dvmUnlockThreadList();
70 
71     RETURN_INT(result);
72 }
73 
74 /*
75  * boolean holdsLock(Object object)
76  *
77  * Returns whether the current thread has a monitor lock on the specific
78  * object.
79  */
Dalvik_java_lang_VMThread_holdsLock(const u4 * args,JValue * pResult)80 static void Dalvik_java_lang_VMThread_holdsLock(const u4* args, JValue* pResult)
81 {
82     Object* thisPtr = (Object*) args[0];
83     Object* object = (Object*) args[1];
84     Thread* thread;
85 
86     if (object == NULL) {
87         dvmThrowException("Ljava/lang/NullPointerException;", NULL);
88         RETURN_VOID();
89     }
90 
91     dvmLockThreadList(NULL);
92     thread = dvmGetThreadFromThreadObject(thisPtr);
93     int result = dvmHoldsLock(thread, object);
94     dvmUnlockThreadList();
95 
96     RETURN_BOOLEAN(result);
97 }
98 
99 /*
100  * void interrupt()
101  *
102  * Interrupt a thread that is waiting (or is about to wait) on a monitor.
103  */
Dalvik_java_lang_VMThread_interrupt(const u4 * args,JValue * pResult)104 static void Dalvik_java_lang_VMThread_interrupt(const u4* args, JValue* pResult)
105 {
106     Object* thisPtr = (Object*) args[0];
107     Thread* thread;
108 
109     dvmLockThreadList(NULL);
110     thread = dvmGetThreadFromThreadObject(thisPtr);
111     if (thread != NULL)
112         dvmThreadInterrupt(thread);
113     dvmUnlockThreadList();
114     RETURN_VOID();
115 }
116 
117 /*
118  * static boolean interrupted()
119  *
120  * Determine if the current thread has been interrupted.  Clears the flag.
121  */
Dalvik_java_lang_VMThread_interrupted(const u4 * args,JValue * pResult)122 static void Dalvik_java_lang_VMThread_interrupted(const u4* args,
123     JValue* pResult)
124 {
125     Thread* self = dvmThreadSelf();
126     bool interrupted;
127 
128     UNUSED_PARAMETER(args);
129 
130     interrupted = self->interrupted;
131     self->interrupted = false;
132     RETURN_BOOLEAN(interrupted);
133 }
134 
135 /*
136  * boolean isInterrupted()
137  *
138  * Determine if the specified thread has been interrupted.  Does not clear
139  * the flag.
140  */
Dalvik_java_lang_VMThread_isInterrupted(const u4 * args,JValue * pResult)141 static void Dalvik_java_lang_VMThread_isInterrupted(const u4* args,
142     JValue* pResult)
143 {
144     Object* thisPtr = (Object*) args[0];
145     Thread* thread;
146     bool interrupted;
147 
148     dvmLockThreadList(NULL);
149     thread = dvmGetThreadFromThreadObject(thisPtr);
150     if (thread != NULL)
151         interrupted = thread->interrupted;
152     else
153         interrupted = false;
154     dvmUnlockThreadList();
155 
156     RETURN_BOOLEAN(interrupted);
157 }
158 
159 /*
160  * void nameChanged(String newName)
161  *
162  * The name of the target thread has changed.  We may need to alert DDMS.
163  */
Dalvik_java_lang_VMThread_nameChanged(const u4 * args,JValue * pResult)164 static void Dalvik_java_lang_VMThread_nameChanged(const u4* args,
165     JValue* pResult)
166 {
167     Object* thisPtr = (Object*) args[0];
168     StringObject* nameStr = (StringObject*) args[1];
169     Thread* thread;
170     int threadId = -1;
171 
172     /* get the thread's ID */
173     dvmLockThreadList(NULL);
174     thread = dvmGetThreadFromThreadObject(thisPtr);
175     if (thread != NULL)
176         threadId = thread->threadId;
177     dvmUnlockThreadList();
178 
179     dvmDdmSendThreadNameChange(threadId, nameStr);
180     //char* str = dvmCreateCstrFromString(nameStr);
181     //LOGI("UPDATE: threadid=%d now '%s'\n", threadId, str);
182     //free(str);
183 
184     RETURN_VOID();
185 }
186 
187 /*
188  * void setPriority(int newPriority)
189  *
190  * Alter the priority of the specified thread.  "newPriority" will range
191  * from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY (1-10), with "normal"
192  * threads at Thread.NORM_PRIORITY (5).
193  */
Dalvik_java_lang_VMThread_setPriority(const u4 * args,JValue * pResult)194 static void Dalvik_java_lang_VMThread_setPriority(const u4* args,
195     JValue* pResult)
196 {
197     Object* thisPtr = (Object*) args[0];
198     int newPriority = args[1];
199     Thread* thread;
200 
201     dvmLockThreadList(NULL);
202     thread = dvmGetThreadFromThreadObject(thisPtr);
203     if (thread != NULL)
204         dvmChangeThreadPriority(thread, newPriority);
205     //dvmDumpAllThreads(false);
206     dvmUnlockThreadList();
207 
208     RETURN_VOID();
209 }
210 
211 /*
212  * static void sleep(long msec, int nsec)
213  */
Dalvik_java_lang_VMThread_sleep(const u4 * args,JValue * pResult)214 static void Dalvik_java_lang_VMThread_sleep(const u4* args, JValue* pResult)
215 {
216     Thread* self = dvmThreadSelf();
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  */
Dalvik_java_lang_VMThread_yield(const u4 * args,JValue * pResult)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 
264