//                              -*- Mode: CFA -*-
//
// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// kernel_private.h --
//
// Author           : Thierry Delisle
// Created On       : Mon Feb 13 12:27:26 2017
// Last Modified By : Thierry Delisle
// Last Modified On : --
// Update Count     : 0
//

#ifndef KERNEL_PRIVATE_H
#define KERNEL_PRIVATE_H

#include "libhdr.h"

#include "kernel"
#include "thread"

#include "alarm.h"


//-----------------------------------------------------------------------------
// Scheduler

extern "C" {
	void disable_interrupts();
	void enable_interrupts_noRF();
	void enable_interrupts( DEBUG_CTX_PARAM );
}

void ScheduleThread( thread_desc * );
static inline void WakeThread( thread_desc * thrd ) {
	if( !thrd ) return;

	disable_interrupts();
	ScheduleThread( thrd );
	enable_interrupts( DEBUG_CTX );
}
thread_desc * nextThread(cluster * this);

void BlockInternal(void);
void BlockInternal(spinlock * lock);
void BlockInternal(thread_desc * thrd);
void BlockInternal(spinlock * lock, thread_desc * thrd);
void BlockInternal(spinlock ** locks, unsigned short count);
void BlockInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
void LeaveThread(spinlock * lock, thread_desc * thrd);

//-----------------------------------------------------------------------------
// Processor
coroutine processorCtx_t {
	processor * proc;
};

void main(processorCtx_t *);
void start(processor * this);
void runThread(processor * this, thread_desc * dst);
void finishRunning(processor * this);
void spin(processor * this, unsigned int * spin_count);

struct system_proc_t {
	processor proc;

	alarm_list_t alarms;
	spinlock alarm_lock;

	bool pending_alarm;
};

extern cluster * systemCluster;
extern system_proc_t * systemProcessor;
extern volatile thread_local processor * this_processor;
extern volatile thread_local coroutine_desc * this_coroutine;
extern volatile thread_local thread_desc * this_thread;
extern volatile thread_local bool preemption_in_progress;
extern volatile thread_local unsigned short disable_preempt_count;

//-----------------------------------------------------------------------------
// Threads
extern "C" {
      forall(dtype T | is_thread(T))
      void CtxInvokeThread(T * this);
}

extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst);

#endif //KERNEL_PRIVATE_H

// Local Variables: //
// mode: c //
// tab-width: 4 //
// End: //
