#ifndef __KERNEL_SPINLOCK_H
#define __KERNEL_SPINLOCK_H

#include <compiler.h>
#include <cpp/Uncopyable.h>

namespace OS {
namespace Kernel {

class Spinlock : private Uncopyable {
  public:
	Spinlock() : mLockVar(0) { }

	void Acquire() { mLockVar = 1; } 
	void Release() { mLockVar = 0; }

	bool LockHeld() const { return mLockVar != 0; }

  private:
	volatile int mLockVar;
};

class SpinlockRef : private Uncopyable {
  public:
	SpinlockRef(Spinlock &lock) : mLock(lock) { 
		mLock.Acquire(); 
		mHeld = true;
	}
	~SpinlockRef() { Release(); }

	void Release() {
		if (mHeld)
			mLock.Release();
		mHeld = false;
	}

  private:
	Spinlock &mLock;
	bool mHeld;
};

}} // namespace OS::Kernel

#endif
