#ifndef __OS_THREAD_H
#define __OS_THREAD_H

#include <sys/types.h>
#include <cpp/Uncopyable.h>

namespace OS {

// Forward declaration of kernel level thread
namespace Kernel {
class Thread;
}

class Thread : private Uncopyable {
public:
	Thread(const char *name = "Thread");
	virtual ~Thread();

	virtual status_t Start(bool now = true);
	virtual void Exit();
	virtual void Yield();
	virtual int SetPriority(int priority);
	virtual void SetCustomStack(vaddr_t base, vaddr_t size);

	virtual int Run() = 0; /* override for your initial routine */

	/* static methods that apply to current Thread */
	static Thread *GetCurrent();
	static void YieldCurrent();
	static void ExitCurrent();
	static int SetCurrentPriority(int priority);

	bool IsCurrent() const { return GetCurrent() == this; }

	// default stack size
	static const int kDefaultThreadStackSize = 4096;

private:
	static void ThreadStartRoutine(unsigned long);
	
	Kernel::Thread *mKThread;
};

/* simple thread class if you want to just call a routine at start */
class GenericThread : public Thread {
public:
	GenericThread(int (*startRoutine)(), const char *name = "Generic Thread");
	virtual ~GenericThread();

	virtual int Run();
private:
	int (*mStartRoutine)();
};

} // namespace OS

#endif


