//===------------- VMObject.cpp - VM object definition --------------------===//
//
//                                N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <vector>

#include "mvm/Threads/Locks.h"

#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"
#include "VirtualMachine.h"

using namespace n3;

void VMObject::initialise(VMCommonClass* cl) {
  this->classOf = cl;
  this->lockObj = 0;
}

VMCond* VMCond::allocate() {
  return gc_new(VMCond)();
}

void VMCond::notify() {
  for (std::vector<VMThread*>::iterator i = threads.begin(), 
            e = threads.end(); i!= e; ++i) {
    VMThread* cur = *i;
    cur->lock->lock();
    if (cur->interruptFlag != 0) {
      cur->lock->unlock();
      continue;
    } else if (cur->vmThread != 0) {
      cur->varcond->signal();
      cur->lock->unlock();
      threads.erase(i);
      break;
    } else { // dead thread
      threads.erase(i);
    }
  }
}

void VMCond::notifyAll() {
  for (std::vector<VMThread*>::iterator i = threads.begin(),
            e = threads.end(); i!= e; ++i) {
    VMThread* cur = *i;
    cur->lock->lock();
    cur->varcond->signal();
    cur->lock->unlock();
    threads.erase(i);
  }
}

void VMCond::wait(VMThread* th) {
  threads.push_back(th);
}

void VMCond::remove(VMThread* th) {
  for (std::vector<VMThread*>::iterator i = threads.begin(),
            e = threads.end(); i!= e; ++i) {
    if (*i == th) {
      threads.erase(i);
      break;
    }
  }
}

void LockObj::print(mvm::PrintBuffer* buf) const {
  buf->write("Lock<>");
}

LockObj* LockObj::allocate() {
  LockObj* res = gc_new(LockObj)();
  res->lock = mvm::Lock::allocRecursive();
  res->varcond = VMCond::allocate();
  return res;
}

void LockObj::aquire() {
  lock->lock();
}

void LockObj::release() {
  lock->unlock();
}

bool LockObj::owner() {
  return mvm::Lock::selfOwner(lock);
}

void VMObject::print(mvm::PrintBuffer* buf) const {
  buf->write("VMObject<");
  classOf->print(buf);
  buf->write(">");
}

VMObject* VMObject::allocate(VMCommonClass* cl) {
  VMObject* res = gc_new(VMObject)();
  res->classOf = cl;
  return res;
}

static LockObj* myLock(VMObject* obj) {
  verifyNull(obj);
  if (obj->lockObj == 0) {
    VMObject::globalLock->lock();
    if (obj->lockObj == 0) {
      obj->lockObj = LockObj::allocate();
    }
    VMObject::globalLock->unlock();
  }
  return obj->lockObj;
}

void VMObject::aquire() {
  myLock(this)->aquire();
}

void VMObject::unlock() {
  verifyNull(this);
  lockObj->release();
}

void VMObject::waitIntern(struct timeval* info, bool timed) {
  LockObj * l = myLock(this);
  bool owner = l->owner();

  if (owner) {
    VMThread* thread = VMThread::get();
    mvm::Lock* mutexThread = thread->lock;
    mvm::Cond* varcondThread = thread->varcond;

    mutexThread->lock();
    if (thread->interruptFlag != 0) {
      mutexThread->unlock();
      thread->interruptFlag = 0;
      thread->vm->interruptedException(this);
    } else {
      unsigned int recur = mvm::LockRecursive::recursion_count(l->lock);
      bool timeout = false;
      mvm::LockRecursive::my_unlock_all(l->lock);
      l->varcond->wait(thread);
      thread->state = VMThread::StateWaiting;

      if (timed) {
        timeout = varcondThread->timed_wait(mutexThread, info);
      } else {
        varcondThread->wait(mutexThread);
      }

      bool interrupted = (thread->interruptFlag != 0);
      mutexThread->unlock();
      mvm::LockRecursive::my_lock_all(l->lock, recur);

      if (interrupted || timeout) {
        l->varcond->remove(thread);
      }

      thread->state = VMThread::StateRunning;

      if (interrupted) {
        thread->interruptFlag = 0;
        thread->vm->interruptedException(this);
      }
    }
  } else {
    VMThread::get()->vm->illegalMonitorStateException(this);
  }
}

void VMObject::wait() {
  waitIntern(0, false);
}

void VMObject::timedWait(struct timeval& info) {
  waitIntern(&info, false);
}

void VMObject::notify() {
  LockObj* l = myLock(this);
  if (l->owner()) {
    l->varcond->notify();
  } else {
    VMThread::get()->vm->illegalMonitorStateException(this);
  }
}

void VMObject::notifyAll() {
  LockObj* l = myLock(this);
  if (l->owner()) {
    l->varcond->notifyAll();
  } else {
    VMThread::get()->vm->illegalMonitorStateException(this);
  } 
}

bool VMObject::instanceOf(VMCommonClass* cl) {
  if (!this) return false;
  else return this->classOf->isAssignableFrom(cl);
}
