//                              -*- 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.
//
// threads --
//
// Author           : Thierry Delisle
// Created On       : Mon Nov 28 12:27:26 2016
// Last Modified By : Thierry Delisle
// Last Modified On : Mon Nov 28 12:27:26 2016
// Update Count     : 0
//

#ifndef __THREADS_H__
#define __THREADS_H__

#include <stdbool.h>

extern "C" {
      struct coVtable {
            void (*main)(void*);
            struct coroutine* (*this_coroutine)(void*);
      };

      struct coStack_t {
            unsigned int size;		// size of stack
            void *storage;			// pointer to stack
            void *limit;			// stack grows towards stack limit
            void *base;				// base of stack
            void *context;			// address of cfa_context_t
            void *top;				// address of top of storage
            bool userStack;	
      };


      enum coroutine_state { Start, Inactive, Active, Halt };

      struct coroutine {
            coStack_t stack;
            const char *name;			// textual name for coroutine/task, initialized by uC++ generated code
            int errno_;				// copy of global UNIX variable errno
            coroutine_state state;	      // current execution status for coroutine
            bool notHalted;			// indicate if execuation state is not halted

            coroutine *starter;		// first coroutine to resume this one
            coroutine *last;			// last coroutine to resume this one
      };
}

void ?{}(coStack_t* this);

void ?{}(coroutine* this);

trait coroutine_t(dtype T) {
      coroutine* this_coroutine(T* this);
      void co_main(T* this);
      coVtable* vtable(T* this);
};

forall(dtype T | coroutine_t(T))
void start(T* cor);

void suspend(void);

forall(dtype T | coroutine_t(T))
void resume(T* cor);

#endif //__THREADS_H__

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