/*
 * proc.h
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 *
 * プロセス関係ヘッダファイル
 */


#ifndef proc_h
#define proc_h


#include"segment.h"
#include"fs.h"


#define FPUSAVE_SIZE 108		/* FPUセーブデータサイズ（バイト単位） */


#ifndef ASM_FILE


enum{
	MAX_CHILD=8,		/* Max number of child processes */
};

/* プロセス構造体 */
typedef struct PROC{
	struct PROC *wait_next;		/* next link for wait,WAIT_QUEUE・TIMERのnextと同じ位置 */
	struct PROC *wait_prev;		/* prev link for wait,WAIT_QUEUE・TIMERのnextと同じ位置 */
	int timer_count;			/* Counter for timer */
	int timer_type;				/* Timer type */
	struct PROC *next;			/* Schedule linkの次のプロセス */
	struct PROC *prev;			/* Schedule linkの前のプロセス */
	uint esp;					/* Save contextのトップesp */
	uint *pagedir;				/* Page directory address */
	int pagedir_gate;			/* Lock gate for page table handlling */
	int count_child;			/* Number of child processes */
	struct PROC *parent;		/* Parent process */
	struct PROC *child;			/* Child process */
	struct PROC *brother;		/* Link of brother process */
	int cpu;					/* running cpu number 稼働してなければ-1以下の値*/
	F_STRUCT fstruct;			/* ファイル情報構造体 */
}PROC;

/* プロセスウエイトキュー構造体 */
typedef struct{
	PROC *wait_next;		/* ウエイトリンクの次のプロセス,PROCのwait_nextと同じ位置 */
	PROC *wait_prev;		/* ウエイトリンクの前のプロセス,PROCのwait_prevと同じ位置 */
	int flag;				/* Wait flag */
	int gate;				/* Lock gate */
}WAIT_QUEUE;

/* タイマー割り込み待ち用構造体 */
typedef struct{
	PROC *proc;		/* 割り込み待ちプロセス */
	int flag;		/* タイムアウトフラグ */
}WAIT_INTR;

/* cpuごとのタスク情報構造体 */
typedef struct CPU{
	int cpu;				/* number of cpu */
	PROC *current_task;		/* 現在の稼働中のprocess */
	uint proc_num;			/* 稼動プロセス数 */
	struct CPU *next;
	struct CPU *prev;
	int gate;				/* Lock gate */
}CPU;


extern CPU cputask[];


/*
 * Get current cpu number
 * returns : current cpu number
 */
extern inline int get_current_cpu()
{
	int result;


	asm volatile(
		"xorl	%%eax,%%eax\n"\
		"str	%%ax\n"\
		"subl	%1,%%eax\n"\
		"shrl	$3,%%eax"
		:"=a"(result):"i"(TSS_DES)
	);

	return result;
}

/*
 * Get current task
 * return : Current process
 */
extern inline PROC *get_current_task()
{
	return cputask[get_current_cpu()].current_task;
}



extern void add_to_schedule(PROC*);
extern void del_from_schedule(PROC*);
extern void wait_proc(WAIT_QUEUE*);
extern void wake_proc(WAIT_QUEUE*);
extern int wait_intr(WAIT_INTR*,int);
extern int wake_intr(WAIT_INTR*);
extern int init_cputask(int);
extern int set_idle_proc(int,uint*);
extern void set_tss(int);
extern void start_tasking();
extern void set_tss(int);
extern int sys_fork();
extern int sys_exit();
extern int sys_exec();


#endif


#endif
