• 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     /* 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  */
Dalvik_java_lang_VMThread_currentThread(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_getStatus(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_holdsLock(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_interrupt(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_interrupted(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_isInterrupted(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_nameChanged(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_setPriority(const u4 * args,JValue * pResult)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  */
Dalvik_java_lang_VMThread_sleep(const u4 * args,JValue * pResult)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  */
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