static jint detachThread(Env* env, jboolean ignoreAttachCount) { env->attachCount--; if (!ignoreAttachCount && env->attachCount > 0) { return JNI_OK; } if (env->gatewayFrames) { rvmAbort("Cannot detach thread when there are non native frames on the call stack"); } // TODO: Release all monitors still held by this thread (should only be monitors acquired from JNI code) Thread* thread = env->currentThread; if (rvmExceptionOccurred(env)) { threadExitUncaughtException(env, thread); } if (thread->threadObj->group) { rvmCallVoidInstanceMethod(env, thread->threadObj->group, removeThreadMethod, thread->threadObj); rvmExceptionClear(env); } // Set threadPtr to null rvmAtomicStoreLong(&thread->threadObj->threadPtr, 0); // Notify anyone waiting on this thread (using Thread.join()) rvmLockObject(env, thread->threadObj->lock); rvmObjectNotifyAll(env, thread->threadObj->lock); rvmUnlockObject(env, thread->threadObj->lock); rvmLockThreadsList(); thread->status = THREAD_ZOMBIE; DL_DELETE(threads, thread); pthread_cond_broadcast(&threadsChangedCond); rvmTearDownSignals(env); env->currentThread = NULL; pthread_setspecific(tlsEnvKey, NULL); rvmUnlockThreadsList(); return JNI_OK; }
void Java_sun_misc_Unsafe_putLongVolatile(Env* env, Object* unsafe, Object* obj, jlong offset, jlong newValue) { if (!checkNull(env, obj)) return; jlong* address = (jlong*) getFieldAddress(obj, offset); rvmAtomicStoreLong(address, newValue); }