/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/

/************************************

	machine dependent
	task system

*************************************/

#ifndef ___TASK_H___
#define ___TASK_H___

/*
#define DEADLOCK_CHECK
*/

#define PRI_MAX		6


typedef struct htid {
	unsigned	valid:1;
// 0: invalid or error
// 1: valid or hard tid;
	unsigned int	tid;
} HTID;


#include	"machine/task.h"


typedef struct sem_org {
	D_SEM		d_sem;
	int		pri;
} SEM_ORG;
typedef struct ____sem {
	SEM_ORG *	so;		
} SEM;

extern SEM ____sem_null;
#define SEM_NULL	____sem_null

typedef struct rw_lock {
	SEM		lock;
	int		cnt;
} RW_LOCK;

typedef struct fifo_el {
	struct fifo_el *	next;
} FIFO_EL;

typedef struct fifo {
	SEM			lock;
	int			length;
	struct fifo_el *	head;
	struct fifo_el *	tail;
} FIFO;


void _sleep_task(unsigned int key,D_SEM s,char *file,int line);
void _wakeup_task(unsigned int key,char *file,int line);
void _i_sleep_task(unsigned int key,SEM s,char *file,int line);


#define sleep_task(k,s) _i_sleep_task(k,s,__FILE__,__LINE__)
#define wakeup_task(k) _wakeup_task(k,__FILE__,__LINE__)


void init_task(int);
void xx_close_lock(D_SEM s);
void close_lock(SEM s);


int lock_up_test(SEM);
D_SEM xx_new_lock(int level,char * file,int line);
SEM _i_new_lock(int level,char *,int);

#define new_lock(level)	_i_new_lock((level),__FILE__,__LINE__)
/*
SEM new_lock(int level);
*/
void _lock_task(D_SEM,char *,int);
void _unlock_task(D_SEM,char *,char *, int);
void _i_unlock_task(SEM,char *,char * ,int);
void _i_lock_task(SEM,char*,int);

#define lock_task(s)	_i_lock_task((s),__FILE__,__LINE__)
#define unlock_task(s,str)	_i_unlock_task((s),(str),__FILE__,__LINE__)

void rw_lock_init(RW_LOCK *,int);
void read_lock(RW_LOCK *);
void write_lock(RW_LOCK *);
void rwl_unlock(RW_LOCK *);
#ifndef sleep_task
void sleep_task(unsigned int,SEM);
#endif
#ifndef wakeup_task
void wakeup_task(unsigned int);
#endif

void change_pri(int,int);
/*
#ifndef create_task
int create_task(void (*func)(),int data,int pri);
#endif
*/
#ifndef xx_create_task
int xx_create_task(void (*func)(),int data,int pri,char*,int);
#endif
#define create_task(f,d,p)	xx_create_task(f,d,p,__FILE__,__LINE__)

void sleep_sec(int);
int get_tid();
HTID _get_tid();
int get_pri(int tid);
void change_pri(int tid,int pri);
int thread_exist(int tid);
int cmp_htid(HTID a,HTID b);
HTID invalid_htid();

extern int (*int_handler)();

void init_fifo(FIFO * f);
void insert_fifo(FIFO * f,FIFO_EL * e);
FIFO_EL * delete_fifo(FIFO * f);

extern void (*upper_layer_lock_tracer)(int *);
int debug_th_timeout_check(int time);

#endif

