#include "thread.h"
#include "kernel.h"
#include "target.h"

BaseThread::BaseThread(StackItem* Stack, Priority pr, void (*exec)())
    : _stackPointer(Stack)
    , _timeout(0)
    , _priority(pr)
{
    Kernel::RegisterThread(this, _priority);

    *(--_stackPointer)  = 0x01000000L;             // xPSR
    *(--_stackPointer)  = reinterpret_cast<uint32_t>(exec); // Entry Point
    _stackPointer -= 14;                           // emulate "push R14,R12,R3,R2,R1,R0,R11-R4"
}

bool BaseThread::IsSleeping() const
{
	CriticalSection cs;
	if(_timeout)
		return true;
	else
		return false;
}

bool BaseThread::IsBlocked(void) const
{
	CriticalSection cs;
#if 0
	if (Kernel.ReadyThreadMap & getPrioTag(_priority))
		return false;
	else
		return true;
#endif
	return false;
}

void BaseThread::Sleep(timeout_t ticks)
{
	CriticalSection cs;
	BaseThread* current = Kernel::Running();
	current->_timeout = ticks;
	Kernel::BlockThread(current->_priority);
	Kernel::Scheduler();
}

bool BaseThread::WakeUpThread(void)
{
	CriticalSection cs;
	if (_timeout > 0) {
		if (--_timeout == 0) {
			return true;
		}
	}
	return false;
}
