org.jikesrvm.scheduler
Class Monitor

java.lang.Object
  extended by org.jikesrvm.scheduler.Monitor
Direct Known Subclasses:
NoYieldpointsMonitor

public class Monitor
extends Object

Implementation of a heavy lock and condition variable implemented using the primitives available from the operating system. Currently we use a pthread_mutex_t and pthread_cond_it. When instantiated, the mutex and cond are allocated. There is currently no way to destroy either (thus, pool and reuse accordingly).

It is perfectly safe to use this throughout the VM for locking. It is meant to provide roughly the same functionality as Java monitors, except:


Field Summary
 int acquireCount
           
(package private)  int holderSlot
           
(package private)  Word monitor
           
(package private)  int recCount
           
 
Constructor Summary
Monitor()
          Allocate a heavy condition variable and lock.
 
Method Summary
 void broadcast()
          Send a broadcast, which should awaken anyone who is currently blocked in any of the wait methods.
 void lockedBroadcastNoHandshake()
          Send a broadcast after first acquiring the lock.
 void lockNoHandshake()
          Wait until it is possible to acquire the lock and then acquire it.
static boolean lockNoHandshake(Monitor l)
           
 void lockWithHandshake()
          Wait until it is possible to acquire the lock and then acquire it.
static void lockWithHandshake(Monitor m1, Word priority1, Monitor m2, Word priority2)
           
private  void lockWithHandshakeNoRec()
           
private  void lockWithHandshakeNoRecImpl()
           
 void relockNoHandshake(int recCount)
          Relock the mutex after using unlockCompletely.
 void relockWithHandshake(int recCount)
          Relock the mutex after using unlockCompletely, but do so "nicely".
private  void relockWithHandshakeImpl(int recCount)
           
 void timedWaitAbsoluteNoHandshake(long whenWakeupNanos)
          Wait until someone calls broadcast, or until the clock reaches the given time.
 void timedWaitAbsoluteWithHandshake(long whenWakeupNanos)
          Wait until someone calls broadcast, or until the clock reaches the given time.
private  void timedWaitAbsoluteWithHandshakeImpl(long whenWakeupNanos)
           
 void timedWaitRelativeNoHandshake(long delayNanos)
          Wait until someone calls broadcast, or until at least the given number of nanoseconds pass.
 void timedWaitRelativeWithHandshake(long delayNanos)
          Wait until someone calls broadcast, or until at least the given number of nanoseconds pass.
private  void timedWaitRelativeWithHandshakeImpl(long delayNanos)
           
 void unlock()
          Release the lock.
static void unlock(boolean b, Monitor l)
           
 int unlockCompletely()
          Completely release the lock, ignoring recursion.
 void waitNoHandshake()
          Wait until someone calls broadcast.
 void waitWithHandshake()
          Wait until someone calls broadcast.
private  void waitWithHandshakeImpl()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

monitor

Word monitor

holderSlot

int holderSlot

recCount

int recCount

acquireCount

public int acquireCount
Constructor Detail

Monitor

public Monitor()
Allocate a heavy condition variable and lock. This involves allocating stuff in C that never gets deallocated. Thus, don't instantiate too many of these.

Method Detail

lockNoHandshake

public void lockNoHandshake()
Wait until it is possible to acquire the lock and then acquire it. There is no bound on how long you might wait, if someone else is holding the lock and there is no bound on how long they will hold it. As well, even if there is a bound on how long a thread might hold a lock but there are multiple threads contending on its acquisition, there will not necessarily be a bound on how long any particular thread will wait until it gets its turn.

This blocking method method does not notify the threading subsystem that it is blocking. Thus, if someone (like, say, the GC) requests that the thread is blocked then their request will block until this method unblocks. If this sounds like it might be undesirable, call lockNicely instead.


relockNoHandshake

public void relockNoHandshake(int recCount)
Relock the mutex after using unlockCompletely.


lockWithHandshake

public void lockWithHandshake()
Wait until it is possible to acquire the lock and then acquire it. There is no bound on how long you might wait, if someone else is holding the lock and there is no bound on how long they will hold it. As well, even if there is a bound on how long a thread might hold a lock but there are multiple threads contending on its acquisition, there will not necessarily be a bound on how long any particular thread will wait until it gets its turn.

This blocking method method notifies the threading subsystem that it is blocking. Thus, it may be safer than calling lock. But, its reliance on threading subsystem accounting methods may mean that it cannot be used in certain contexts (say, the threading subsystem itself).

This method will ensure that if it blocks, it does so with the mutex not held. This is useful for cases where the subsystem that requested you to block needs to acquire the lock you were trying to acquire when the blocking request came.

It is usually not necessary to call this method instead of lock(), since most VM locks are held for short periods of time.


lockWithHandshakeNoRec

private void lockWithHandshakeNoRec()

lockWithHandshakeNoRecImpl

private void lockWithHandshakeNoRecImpl()

relockWithHandshake

public void relockWithHandshake(int recCount)
Relock the mutex after using unlockCompletely, but do so "nicely".


relockWithHandshakeImpl

private void relockWithHandshakeImpl(int recCount)

unlock

public void unlock()
Release the lock. This method should (in principle) be non-blocking, and, as such, it does not notify the threading subsystem that it is blocking.


unlockCompletely

public int unlockCompletely()
Completely release the lock, ignoring recursion. Returns the recursion count.


waitNoHandshake

public void waitNoHandshake()
Wait until someone calls broadcast.

This blocking method method does not notify the threading subsystem that it is blocking. Thus, if someone (like, say, the GC) requests that the thread is blocked then their request will block until this method unblocks. If this sounds like it might be undesirable, call waitNicely instead.


timedWaitAbsoluteNoHandshake

public void timedWaitAbsoluteNoHandshake(long whenWakeupNanos)
Wait until someone calls broadcast, or until the clock reaches the given time.

This blocking method method does not notify the threading subsystem that it is blocking. Thus, if someone (like, say, the GC) requests that the thread is blocked then their request will block until this method unblocks. If this sounds like it might be undesirable, call timedWaitAbsoluteNicely instead.


timedWaitRelativeNoHandshake

public void timedWaitRelativeNoHandshake(long delayNanos)
Wait until someone calls broadcast, or until at least the given number of nanoseconds pass.

This blocking method method does not notify the threading subsystem that it is blocking. Thus, if someone (like, say, the GC) requests that the thread is blocked then their request will block until this method unblocks. If this sounds like it might be undesirable, call timedWaitRelativeNicely instead.


waitWithHandshake

public void waitWithHandshake()
Wait until someone calls broadcast.

This blocking method notifies the threading subsystem that it is blocking. Thus, it is generally safer than calling wait. But, its reliance on threading subsystem accounting methods may mean that it cannot be used in certain contexts (say, the threading subsystem itself).

This method will ensure that if it blocks, it does so with the mutex not held. This is useful for cases where the subsystem that requested you to block needs to acquire the lock you were trying to acquire when the blocking request came.


waitWithHandshakeImpl

private void waitWithHandshakeImpl()

timedWaitAbsoluteWithHandshake

public void timedWaitAbsoluteWithHandshake(long whenWakeupNanos)
Wait until someone calls broadcast, or until the clock reaches the given time.

This blocking method method notifies the threading subsystem that it is blocking. Thus, it is generally safer than calling timedWaitAbsolute. But, its reliance on threading subsystem accounting methods may mean that it cannot be used in certain contexts (say, the threading subsystem itself).

This method will ensure that if it blocks, it does so with the mutex not held. This is useful for cases where the subsystem that requested you to block needs to acquire the lock you were trying to acquire when the blocking request came.


timedWaitAbsoluteWithHandshakeImpl

private void timedWaitAbsoluteWithHandshakeImpl(long whenWakeupNanos)

timedWaitRelativeWithHandshake

public void timedWaitRelativeWithHandshake(long delayNanos)
Wait until someone calls broadcast, or until at least the given number of nanoseconds pass.

This blocking method method notifies the threading subsystem that it is blocking. Thus, it is generally safer than calling timedWaitRelative. But, its reliance on threading subsystem accounting methods may mean that it cannot be used in certain contexts (say, the threading subsystem itself).

This method will ensure that if it blocks, it does so with the mutex not held. This is useful for cases where the subsystem that requested you to block needs to acquire the lock you were trying to acquire when the blocking request came.


timedWaitRelativeWithHandshakeImpl

private void timedWaitRelativeWithHandshakeImpl(long delayNanos)

broadcast

public void broadcast()
Send a broadcast, which should awaken anyone who is currently blocked in any of the wait methods. This method should (in principle) be non-blocking, and, as such, it does not notify the threading subsystem that it is blocking.


lockedBroadcastNoHandshake

public void lockedBroadcastNoHandshake()
Send a broadcast after first acquiring the lock. Release the lock after sending the broadcast. In most cases where you want to send a broadcast but you don't need to acquire the lock to set the condition that the other thread(s) are waiting on, you want to call this method instead of broadcast.


lockNoHandshake

public static boolean lockNoHandshake(Monitor l)

unlock

public static void unlock(boolean b,
                          Monitor l)

lockWithHandshake

public static void lockWithHandshake(Monitor m1,
                                     Word priority1,
                                     Monitor m2,
                                     Word priority2)