#include <debug.h>
#include <err.h>
#include <os/Module.h>
#include <os/Thread.h>
#include <kernel/Dispatcher.h>
#include <kernel/Thread.h>

using namespace OS;

namespace OS {
namespace Test {

	static int testThreadRoutine()
	{
		int i;

		dprintf("testThread\n");
		Thread *t = Thread::GetCurrent();
		for(i = 0; i < 16; i++) {
			dprintf("current thread %p\n", t);
			Thread::YieldCurrent();
		}

		dprintf("exiting thread %p\n", t);
		return 0;
	}

	static void threadTests()
	{
		Thread *t = new GenericThread(&testThreadRoutine);
		t->Start(false);
		t = new GenericThread(&testThreadRoutine);
		t->Start(false);
	}

	static Kernel::Dispatcher *d;

	static int dispatcherThreadRoutine0()
	{
		dprintf("dispatcherThreadRoutine0\n");


		dprintf("0 %p: calling WaitOn\n", Thread::GetCurrent());
		d->WaitOn();
		dprintf("0 %p: after WaitOn\n", Thread::GetCurrent());

		return 0;
	}

	static int dispatcherThreadRoutine1()
	{
		dprintf("dispatcherThreadRoutine1\n");

		dprintf("1: calling Pulse()\n");
		d->Pulse();
		dprintf("1: after Pulse()\n");

		dprintf("1: calling Signal()\n");
		d->Signal();
		dprintf("1: after Signal()\n");

		return 0;
	}

	static void dispatcherTests()
	{
		d = new Kernel::Dispatcher();

		Thread *t;
		t = new GenericThread(&dispatcherThreadRoutine0); t->SetPriority(Kernel::Scheduler::kHighestPriority); t->Start(false);
		t = new GenericThread(&dispatcherThreadRoutine0); t->SetPriority(Kernel::Scheduler::kHighestPriority); t->Start(false);
		t = new GenericThread(&dispatcherThreadRoutine0); t->SetPriority(Kernel::Scheduler::kHighestPriority); t->Start(false);
		t = new GenericThread(&dispatcherThreadRoutine0); t->SetPriority(Kernel::Scheduler::kHighestPriority); t->Start(false);
		t = new GenericThread(&dispatcherThreadRoutine1); t->Start(false);
	}

	static status_t testInit(Module *)
	{
		TRACE_ENTRY;

//		threadTests();
//		dispatcherTests();

		return NO_ERROR;
	}

	Module threadTestModule("Thread Test", Module::LEVEL_THREAD, &testInit);
}} // namespace OS::Test

