//===----------- ObjectLocks.h - Object based locks -----------------------===//
//
//                      The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef VMKIT_OBJECT_LOCKS_H
#define VMKIT_OBJECT_LOCKS_H

#include "vmkit/Allocator.h"
#include "vmkit/GC.h"
#include "vmkit/Cond.h"
#include "vmkit/Locks.h"
#include "vmkit/Thread.h"

namespace vmkit {

class FatLock;
class LockSystem;

class LockingThread {
public:
  /// varcond - Condition variable when the thread needs to be awaken from
  /// a wait.
  ///
  vmkit::Cond varcond;

  /// interruptFlag - Has this thread been interrupted?
  ///
  uint32 interruptFlag;

  /// nextWaiting - Next thread waiting on the same monitor.
  ///
  LockingThread* nextWaiting;
  
  /// prevWaiting - Previous thread waiting on the same monitor.
  ///
  LockingThread* prevWaiting;

  /// waitsOn - The lock on which the thread is waiting on.
  ///
  FatLock* waitsOn;


  /* Java thread states **************************************************************/

  static const unsigned int StateNew = 0;
  static const unsigned int StateRunning = 1;
  static const unsigned int StateBlocked = 2;
  static const unsigned int StateWaiting = 3;
  static const unsigned int StateTimeWaiting = 4;
  static const unsigned int StateTerminated = 5;
  static const unsigned int StateParked = 6;
  static const unsigned int StateTimeParked = 7;
  static const unsigned int StateInterrupted = 40;

  /// state - The current state of this thread: Running, Waiting or Interrupted.
  uint32 state;

  LockingThread() {
    interruptFlag = 0;
    nextWaiting = NULL;
    prevWaiting = NULL;
    waitsOn = NULL;
    state = StateRunning;
  }

  bool wait(gc* object, LockSystem& table, struct timeval* info, bool timed);
  void notify(gc* object, LockSystem& table, vmkit::Thread* ownerThread = NULL);
  void notifyAll(gc* object, LockSystem& table, vmkit::Thread* ownerThread = NULL);
};


class FatLock : public vmkit::PermanentObject {
private:
  vmkit::LockRecursive internalLock;
  vmkit::SpinLock spinLock;
  uint32_t waitingThreads;
  uint32_t lockingThreads;
  LockingThread* firstThread;
  gc* associatedObject;
  uint32_t index;
  FatLock* nextFreeLock;
  bool associatedObjectDead;

public:
  FatLock(uint32_t index, gc* object);
  word_t getID();
  int tryAcquire() { return internalLock.tryLock(); }
  bool acquire(gc* object, LockSystem& table);
  void acquireAll(gc* object, word_t count);
  void release(gc* object, LockSystem& table, vmkit::Thread* ownerThread = NULL);
  vmkit::Thread* getOwner();
  bool owner();
  void setAssociatedObject(gc* obj);
  gc* getAssociatedObject() { return associatedObject; }
  gc** getAssociatedObjectPtr() { return &associatedObject; }
  bool associatedObjectIsDead() const {return associatedObjectDead;}
  void markAssociatedObjectAsDead() {associatedObjectDead = true;}

  friend class LockSystem;
  friend class LockingThread;
  friend class ThinLock;
};


/// LockSystem - This class manages all Java locks used by the applications.
/// Each JVM must own an instance of this class and allocate Java locks
/// with it.
///
class LockSystem {
  friend class FatLock;
public:
  
  // Fixed values. With these values, an index is on 18 bits.
  static const uint32_t GlobalSize = 128;
  static const uint32_t BitIndex = 11;
  static const uint32_t IndexSize = 1 << BitIndex;
  static const uint32_t BitMask = IndexSize - 1;
  static const uint32_t MaxLocks = GlobalSize * IndexSize;

  vmkit::BumpPtrAllocator& allocator;

  /// LockTable - The global table that will hold the locks. The table is
  /// a two-dimensional array, and only one entry is created, so that
  /// the lock system does not eat up all memory on startup.
  ///  
  FatLock* ** LockTable;
  
  /// currentIndex - The current index in the tables. Always incremented,
  /// never decremented.
  ///
  uint32_t currentIndex;
 
  /// freeLock - The list of locks that are allocated and available.
  ///
  FatLock* freeLock;
 
  /// threadLock - Spin lock to protect the currentIndex field.
  ///
  vmkit::SpinLock threadLock;
  
  /// allocate - Allocate a FatLock.
  ///
  FatLock* allocate(gc* obj); 
 
  /// deallocate - Put a lock in the free list lock.
  ///
  void deallocate(FatLock* lock);

  /// LockSystem - Default constructor. Initialize the table.
  ///
  LockSystem(vmkit::BumpPtrAllocator& allocator);

  /// getLock - Get a lock from an index in the table.
  ///
  FatLock* getLock(uint32_t index) {
    return LockTable[index >> BitIndex][index & BitMask];
  }

  FatLock* getFatLockFromID(word_t ID);
};

class ThinLock {
public:
  
  // The header of an object that has a thin lock implementation is like the
  // following:
  //
  //    x      xxx xxxx xxxx        xxxx xxxx xxxx        xxxx xxxx
  //    ^      ^^^ ^^^^ ^^^^        ^^^^ ^^^^ ^^^^        ^^^^ ^^^^
  //    1           11                    12                  8
  // fat lock    thread id       thin lock count + hash     GC bits

  static const uint64_t FatMask = 1LL << (kThreadStart > 0xFFFFFFFFLL ? 61LL : 31LL);

  static const uint64_t NonLockBits = HashBits + GCBits;
  static const uint64_t NonLockBitsMask = ((1LL << NonLockBits) - 1LL);

  static const uint64_t ThinCountMask = 0xFFFFFFFFLL & ~(FatMask | kThreadIDMask | NonLockBitsMask);
  static const uint64_t ThinCountShift = NonLockBits;
  static const uint64_t ThinCountAdd = 1LL << NonLockBits;

  /// initialise - Initialise the value of the lock.
  ///
  static void removeFatLock(FatLock* fatLock, LockSystem& table);

  /// overflowThinlock - Change the lock of this object to a fat lock because
  /// we have reached the maximum number of locks.
  static void overflowThinLock(gc* object, LockSystem& table);
 
  /// changeToFatlock - Change the lock of this object to a fat lock. The lock
  /// may be in a thin lock or fat lock state.
  static FatLock* changeToFatlock(gc* object, LockSystem& table);

  /// acquire - Acquire the lock.
  static void acquire(gc* object, LockSystem& table);

  /// release - Release the lock.
  static void release(gc* object, LockSystem& table, vmkit::Thread* ownerThread = NULL);

  /// owner - Returns true if the current thread is the owner of this object's
  /// lock.
  static bool owner(gc* object, LockSystem& table);

  static vmkit::Thread* getOwner(gc* object, LockSystem& table);

  /// getFatLock - Get the fat lock is the lock is a fat lock, 0 otherwise.
  static FatLock* getFatLock(gc* object, LockSystem& table);
};

} // end namespace vmkit

#endif // VMKIT_OBJECT_LOCKS_H
