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 struct Object; 23 struct Monitor; 24 struct Thread; 25 typedef struct Monitor Monitor; 26 27 #define QUIET_ZYGOTE_MONITOR 1 28 29 /* 30 * Synchronization lock, included in every object. 31 * 32 * We want this to be a 32-bit "thin lock", holding the lock level and 33 * the owner's threadId, that inflates to a Monitor pointer when there 34 * is contention or somebody waits on it. 35 */ 36 typedef union Lock { 37 u4 thin; 38 Monitor* mon; 39 } Lock; 40 41 /* 42 * Initialize a Lock to the proper starting value. 43 * This is necessary for thin locking. 44 */ 45 #define THIN_LOCKING 1 46 #if THIN_LOCKING 47 #define DVM_LOCK_INITIAL_THIN_VALUE (0x1) 48 #else 49 #define DVM_LOCK_INITIAL_THIN_VALUE (0) 50 #endif 51 #define DVM_LOCK_INIT(lock) \ 52 do { (lock)->thin = DVM_LOCK_INITIAL_THIN_VALUE; } while (0) 53 54 /* 55 * Returns true if the lock has been fattened. 56 */ 57 #define IS_LOCK_FAT(lock) (((lock)->thin & 1) == 0 && (lock)->mon != NULL) 58 59 /* 60 * Acquire the object's monitor. 61 */ 62 void dvmLockObject(struct Thread* self, struct Object* obj); 63 64 /* Returns true if the unlock succeeded. 65 * If the unlock failed, an exception will be pending. 66 */ 67 bool dvmUnlockObject(struct Thread* self, struct Object* obj); 68 69 /* 70 * Implementations of some java/lang/Object calls. 71 */ 72 void dvmObjectWait(struct Thread* self, struct Object* obj, 73 s8 timeout, s4 nanos, bool interruptShouldThrow); 74 void dvmObjectNotify(struct Thread* self, struct Object* obj); 75 void dvmObjectNotifyAll(struct Thread* self, struct Object* obj); 76 77 /* 78 * Implementation of Thread.sleep(). 79 */ 80 void dvmThreadSleep(u8 msec, u4 nsec); 81 82 /* 83 * Implementation of Thread.interrupt(). 84 * 85 * Interrupt a thread. If it's waiting on a monitor, wake it up. 86 */ 87 void dvmThreadInterrupt(volatile struct Thread* thread); 88 89 /* create a new Monitor struct */ 90 Monitor* dvmCreateMonitor(struct Object* obj); 91 92 /* free an object's monitor during GC */ 93 void dvmFreeObjectMonitor_internal(Lock* lock); 94 #define dvmFreeObjectMonitor(obj) \ 95 do { \ 96 Object *DFM_obj_ = (obj); \ 97 if (IS_LOCK_FAT(&DFM_obj_->lock)) { \ 98 dvmFreeObjectMonitor_internal(&DFM_obj_->lock); \ 99 } \ 100 } while (0) 101 102 /* free monitor list */ 103 void dvmFreeMonitorList(void); 104 105 /* 106 * Get the object a monitor is part of. 107 * 108 * Returns NULL if "mon" is NULL or the monitor is not part of an object 109 * (which should only happen for Thread.sleep() in the current implementation). 110 */ 111 struct Object* dvmGetMonitorObject(Monitor* mon); 112 113 /* 114 * Checks whether the object is held by the specified thread. 115 */ 116 bool dvmHoldsLock(struct Thread* thread, struct Object* obj); 117 118 /* 119 * Debug. 120 */ 121 void dvmDumpMonitorInfo(const char* msg); 122 123 #endif /*_DALVIK_SYNC*/ 124