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 * Object synchronization functions. 18 */ 19 #ifndef _DALVIK_SYNC 20 #define _DALVIK_SYNC 21 22 /* 23 * Monitor shape field. Used to distinguish immediate thin locks from 24 * indirecting fat locks. 25 */ 26 #define LW_SHAPE_THIN 0 27 #define LW_SHAPE_FAT 1 28 #define LW_SHAPE_MASK 0x1 29 #define LW_SHAPE(x) ((x) & LW_SHAPE_MASK) 30 31 /* 32 * Hash state field. Used to signify that an object has had its 33 * identity hash code exposed or relocated. 34 */ 35 #define LW_HASH_STATE_UNHASHED 0 36 #define LW_HASH_STATE_HASHED 1 37 #define LW_HASH_STATE_HASHED_AND_MOVED 3 38 #define LW_HASH_STATE_MASK 0x3 39 #define LW_HASH_STATE_SHIFT 1 40 #define LW_HASH_STATE(x) (((x) >> LW_HASH_STATE_SHIFT) & LW_HASH_STATE_MASK) 41 42 /* 43 * Monitor accessor. Extracts a monitor structure pointer from a fat 44 * lock. Performs no error checking. 45 */ 46 #define LW_MONITOR(x) \ 47 ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | \ 48 LW_SHAPE_MASK))) 49 50 /* 51 * Lock owner field. Contains the thread id of the thread currently 52 * holding the lock. 53 */ 54 #define LW_LOCK_OWNER_MASK 0xffff 55 #define LW_LOCK_OWNER_SHIFT 3 56 #define LW_LOCK_OWNER(x) (((x) >> LW_LOCK_OWNER_SHIFT) & LW_LOCK_OWNER_MASK) 57 58 /* 59 * Lock recursion count field. Contains a count of the numer of times 60 * a lock has been recursively acquired. 61 */ 62 #define LW_LOCK_COUNT_MASK 0x1fff 63 #define LW_LOCK_COUNT_SHIFT 19 64 #define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK) 65 66 struct Object; 67 struct Monitor; 68 struct Thread; 69 typedef struct Monitor Monitor; 70 71 #define QUIET_ZYGOTE_MONITOR 1 72 73 /* 74 * Initialize a Lock to the proper starting value. 75 * This is necessary for thin locking. 76 */ 77 #define DVM_LOCK_INITIAL_THIN_VALUE (0) 78 79 #define DVM_LOCK_INIT(lock) \ 80 do { *(lock) = DVM_LOCK_INITIAL_THIN_VALUE; } while (0) 81 82 /* 83 * Returns true if the lock has been fattened. 84 */ 85 #define IS_LOCK_FAT(lock) (LW_SHAPE(*(lock)) == LW_SHAPE_FAT) 86 87 /* 88 * Acquire the object's monitor. 89 */ 90 void dvmLockObject(struct Thread* self, struct Object* obj); 91 92 /* Returns true if the unlock succeeded. 93 * If the unlock failed, an exception will be pending. 94 */ 95 bool dvmUnlockObject(struct Thread* self, struct Object* obj); 96 97 /* 98 * Implementations of some java/lang/Object calls. 99 */ 100 void dvmObjectWait(struct Thread* self, struct Object* obj, 101 s8 timeout, s4 nanos, bool interruptShouldThrow); 102 void dvmObjectNotify(struct Thread* self, struct Object* obj); 103 void dvmObjectNotifyAll(struct Thread* self, struct Object* obj); 104 105 /* 106 * Implementation of System.identityHashCode(). 107 */ 108 u4 dvmIdentityHashCode(struct Object* obj); 109 110 /* 111 * Implementation of Thread.sleep(). 112 */ 113 void dvmThreadSleep(u8 msec, u4 nsec); 114 115 /* 116 * Implementation of Thread.interrupt(). 117 * 118 * Interrupt a thread. If it's waiting on a monitor, wake it up. 119 */ 120 void dvmThreadInterrupt(struct Thread* thread); 121 122 /* create a new Monitor struct */ 123 Monitor* dvmCreateMonitor(struct Object* obj); 124 125 /* 126 * Frees unmarked monitors from the monitor list. The given callback 127 * routine should return a non-zero value when passed a pointer to an 128 * unmarked object. 129 */ 130 void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*)); 131 132 /* free monitor list */ 133 void dvmFreeMonitorList(void); 134 135 /* 136 * Get the object a monitor is part of. 137 * 138 * Returns NULL if "mon" is NULL or the monitor is not part of an object 139 * (which should only happen for Thread.sleep() in the current implementation). 140 */ 141 struct Object* dvmGetMonitorObject(Monitor* mon); 142 143 /* 144 * Get the thread that holds the lock on the specified object. The 145 * object may be unlocked, thin-locked, or fat-locked. 146 * 147 * The caller must lock the thread list before calling here. 148 */ 149 struct Thread* dvmGetObjectLockHolder(struct Object* obj); 150 151 /* 152 * Checks whether the object is held by the specified thread. 153 */ 154 bool dvmHoldsLock(struct Thread* thread, struct Object* obj); 155 156 /* 157 * Relative timed wait on condition 158 */ 159 int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex, 160 s8 msec, s4 nsec); 161 162 /* 163 * Debug. 164 */ 165 void dvmDumpMonitorInfo(const char* msg); 166 167 #endif /*_DALVIK_SYNC*/ 168