/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Object synchronization functions.
*/
#ifndef _DALVIK_SYNC
#define _DALVIK_SYNC
struct Object;
struct Monitor;
struct Thread;
typedef struct Monitor Monitor;
#define QUIET_ZYGOTE_MONITOR 1
/*
* Synchronization lock, included in every object.
*
* We want this to be a 32-bit "thin lock", holding the lock level and
* the owner's threadId, that inflates to a Monitor pointer when there
* is contention or somebody waits on it.
*/
typedef union Lock {
u4 thin;
Monitor* mon;
} Lock;
/*
* Initialize a Lock to the proper starting value.
* This is necessary for thin locking.
*/
#define THIN_LOCKING 1
#if THIN_LOCKING
#define DVM_LOCK_INITIAL_THIN_VALUE (0x1)
#else
#define DVM_LOCK_INITIAL_THIN_VALUE (0)
#endif
#define DVM_LOCK_INIT(lock) \
do { (lock)->thin = DVM_LOCK_INITIAL_THIN_VALUE; } while (0)
/*
* Returns true if the lock has been fattened.
*/
#define IS_LOCK_FAT(lock) (((lock)->thin & 1) == 0 && (lock)->mon != NULL)
/*
* Acquire the object's monitor.
*/
void dvmLockObject(struct Thread* self, struct Object* obj);
/* Returns true if the unlock succeeded.
* If the unlock failed, an exception will be pending.
*/
bool dvmUnlockObject(struct Thread* self, struct Object* obj);
/*
* Implementations of some java/lang/Object calls.
*/
void dvmObjectWait(struct Thread* self, struct Object* obj,
s8 timeout, s4 nanos, bool interruptShouldThrow);
void dvmObjectNotify(struct Thread* self, struct Object* obj);
void dvmObjectNotifyAll(struct Thread* self, struct Object* obj);
/*
* Implementation of Thread.sleep().
*/
void dvmThreadSleep(u8 msec, u4 nsec);
/*
* Implementation of Thread.interrupt().
*
* Interrupt a thread. If it's waiting on a monitor, wake it up.
*/
void dvmThreadInterrupt(volatile struct Thread* thread);
/* create a new Monitor struct */
Monitor* dvmCreateMonitor(struct Object* obj);
/* free an object's monitor during GC */
void dvmFreeObjectMonitor_internal(Lock* lock);
#define dvmFreeObjectMonitor(obj) \
do { \
Object *DFM_obj_ = (obj); \
if (IS_LOCK_FAT(&DFM_obj_->lock)) { \
dvmFreeObjectMonitor_internal(&DFM_obj_->lock); \
} \
} while (0)
/* free monitor list */
void dvmFreeMonitorList(void);
/*
* Get the object a monitor is part of.
*
* Returns NULL if "mon" is NULL or the monitor is not part of an object
* (which should only happen for Thread.sleep() in the current implementation).
*/
struct Object* dvmGetMonitorObject(Monitor* mon);
/*
* Checks whether the object is held by the specified thread.
*/
bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
/*
* Debug.
*/
void dvmDumpMonitorInfo(const char* msg);
#endif /*_DALVIK_SYNC*/