• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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