java_lang_VMThread.cpp revision 60fc806b679a3655c228b4093058c59941a49cfe
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        dvmThrowNullPointerException(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'", 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