Sync.h revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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
22struct Object;
23struct Monitor;
24struct Thread;
25typedef 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 */
36typedef 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 */
62void 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 */
67bool dvmUnlockObject(struct Thread* self, struct Object* obj);
68
69/*
70 * Implementations of some java/lang/Object calls.
71 */
72void dvmObjectWait(struct Thread* self, struct Object* obj,
73    s8 timeout, s4 nanos, bool interruptShouldThrow);
74void dvmObjectNotify(struct Thread* self, struct Object* obj);
75void dvmObjectNotifyAll(struct Thread* self, struct Object* obj);
76
77/*
78 * Implementation of Thread.sleep().
79 */
80void dvmThreadSleep(u8 msec, u4 nsec);
81
82/* create a new Monitor struct */
83Monitor* dvmCreateMonitor(struct Object* obj);
84
85/* free an object's monitor during GC */
86void dvmFreeObjectMonitor_internal(Lock* lock);
87#define dvmFreeObjectMonitor(obj) \
88    do { \
89        Object *DFM_obj_ = (obj); \
90        if (IS_LOCK_FAT(&DFM_obj_->lock)) { \
91            dvmFreeObjectMonitor_internal(&DFM_obj_->lock); \
92        } \
93    } while (0)
94
95/* free monitor list */
96void dvmFreeMonitorList(void);
97
98/*
99 * Get the object a monitor is part of.
100 *
101 * Returns NULL if "mon" is NULL or the monitor is not part of an object
102 * (which should only happen for Thread.sleep() in the current implementation).
103 */
104struct Object* dvmGetMonitorObject(Monitor* mon);
105
106/*
107 * Checks whether the object is held by the specified thread.
108 */
109bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
110
111/*
112 * Debug.
113 */
114void dvmDumpMonitorInfo(const char* msg);
115
116#endif /*_DALVIK_SYNC*/
117