//
// 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 : Peter A. Buhr
// Last Modified On : Sat Jul 22 09:58:09 2017
// Update Count     : 2
//

#pragma once

#include "libhdr.h"

#include "kernel"
#include "thread"

#include "alarm.h"


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

extern "C" {
	void disable_interrupts();
	void enable_interrupts_noPoll();
	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);

//Block current thread and release/wake-up the following resources
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 event_kernel_t {
	alarm_list_t alarms;
	spinlock lock;
};

extern event_kernel_t * event_kernel;

extern thread_local coroutine_desc * volatile this_coroutine;
extern thread_local thread_desc *    volatile this_thread;
extern thread_local processor *      volatile this_processor;

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);

//-----------------------------------------------------------------------------
// Utils
#define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)]

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