blob: 520366e2328197d454162b9e09f05ccb4406d514 [file] [log] [blame]
/*
* 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
/*
* Monitor shape field. Used to distinguish immediate thin locks from
* indirecting fat locks.
*/
#define LW_SHAPE_THIN 0
#define LW_SHAPE_FAT 1
#define LW_SHAPE_MASK 0x1
#define LW_SHAPE(x) ((x) & LW_SHAPE_MASK)
/*
* Hash state field. Used to signify that an object has had its
* identity hash code exposed or relocated.
*/
#define LW_HASH_STATE_UNHASHED 0
#define LW_HASH_STATE_HASHED 1
#define LW_HASH_STATE_HASHED_AND_MOVED 3
#define LW_HASH_STATE_MASK 0x3
#define LW_HASH_STATE_SHIFT 1
#define LW_HASH_STATE(x) (((x) >> LW_HASH_STATE_SHIFT) & LW_HASH_STATE_MASK)
/*
* Monitor accessor. Extracts a monitor structure pointer from a fat
* lock. Performs no error checking.
*/
#define LW_MONITOR(x) \
((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | \
LW_SHAPE_MASK)))
/*
* Lock owner field. Contains the thread id of the thread currently
* holding the lock.
*/
#define LW_LOCK_OWNER_MASK 0xffff
#define LW_LOCK_OWNER_SHIFT 3
#define LW_LOCK_OWNER(x) (((x) >> LW_LOCK_OWNER_SHIFT) & LW_LOCK_OWNER_MASK)
/*
* Lock recursion count field. Contains a count of the numer of times
* a lock has been recursively acquired.
*/
#define LW_LOCK_COUNT_MASK 0x1fff
#define LW_LOCK_COUNT_SHIFT 19
#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK)
struct Object;
struct Monitor;
struct Thread;
typedef struct Monitor Monitor;
/*
* Initialize a Lock to the proper starting value.
* This is necessary for thin locking.
*/
#define DVM_LOCK_INITIAL_THIN_VALUE (0)
#define DVM_LOCK_INIT(lock) \
do { *(lock) = DVM_LOCK_INITIAL_THIN_VALUE; } while (0)
/*
* Returns true if the lock has been fattened.
*/
#define IS_LOCK_FAT(lock) (LW_SHAPE(*(lock)) == LW_SHAPE_FAT)
/*
* 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 System.identityHashCode().
*/
u4 dvmIdentityHashCode(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(struct Thread* thread);
/* create a new Monitor struct */
Monitor* dvmCreateMonitor(struct Object* obj);
/*
* Frees unmarked monitors from the monitor list. The given callback
* routine should return a non-zero value when passed a pointer to an
* unmarked object.
*/
void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*));
/* 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);
/*
* Get the thread that holds the lock on the specified object. The
* object may be unlocked, thin-locked, or fat-locked.
*
* The caller must lock the thread list before calling here.
*/
struct Thread* dvmGetObjectLockHolder(struct Object* obj);
/*
* Checks whether the object is held by the specified thread.
*/
bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
/*
* Relative timed wait on condition
*/
int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
s8 msec, s4 nsec);
#endif /*_DALVIK_SYNC*/