Home | History | Annotate | Download | only in vm
      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