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


#ifndef proc_h
#define proc_h


#include<types.h>
#include<segment.h>
#include<time.h>
#include<except_i386.h>
#include<share/wait.h>


#ifndef ASM_FILE


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

	/* プロセスの状態。 */
	TASK_RUNNING			= 1 << 0,
	TASK_WAIT				= 1 << 1,
	TASK_DEVICE_WAIT		= 1 << 2,	/* デバイス割り込み待ち。 */
	TASK_SIGNAL_WAIT		= 1 << 3,	/* シグナル待ち。 */
	TASK_SEND_SIGNAL_WAIT	= 1 << 4,	/* 配送されたシグナルによる待ち。 */
	TASK_TRACE				= 1 << 5,	/* トレース停止中。 */
	TASK_EXIT				= 1 << 6,	/* Exit. */
	TASK_CHILD_WAIT			= 1 << 7,	/* wait call待ち。 */
	
	// タスクスケジュールフラグ
	PROC_SCHEDULE_DEL = 0,	// 必ず０、常にタスクスケジュールから切り離す。
	PROC_SCHEDULE_NOT_DEL,	// タスクスケジュールから切り離さない。
};


typedef struct{
	
}USER_HANDL;

/* プロセス構造体 */
typedef struct PROC{
	struct PROC	*next;				// Schedule linkの次のプロセス
	struct PROC	*prev;				// Schedule linkの前のプロセス
	struct PROC	*wait_next;			// next link for wait
	struct PROC	*wait_prev;			// prev link for wait
	struct PROC	*proc_next;			// Process list link next.
	struct PROC	*proc_prev;			// Process list link prev.
	uint		 esp;				// セーブしたコンテキストのスタックトップesp
	struct PROC	*parent;			// Parent process.
	struct PROC	*brother;			// Brother process
	struct PROC	*child;				// Child process
	char		 nestCount;			// 割り込みネストカウント。
#define PROC_ZERO_TOP child			// 0初期化の始めの要素。
	uchar		 count_child;		// Number of child processes
	uchar		 exit_state;		// Exit state.
	uchar		 signum;			// Exit signal number.
	FPU_SAVE	 fpu;				// FPUセーブ構造体
	uint64		 cpu_time[2];		// CPU time,0:system 1:user.
	uint		 ctime[2];			// Children clock tick,0:system 1:user.
#define PROC_ZERO_END cpu			// 0初期化の最後の次の要素。
	uchar		 cpu;				// running cpu number 稼働してなければ-1以下の値
	uchar		 state;				// プロセスの状態。
	pid_t		 pid;				// process ID.
	pid_t		 pgid;				// process groupe ID.
	uid_t		 uid;				// user ID.
	gid_t		 gid;				// user groupe ID.
	pid_t		 sid;				// session ID.
	uint		 espBack;			// 保存したユーザーハンドラ実行時の元のカーネルESP値。
	TIMER		 timer[TIMER_MAX];	// タイマー構造体。
	ITIMER		 itimer[ITIMER_MAX];// itimer
	void		*ctlterm;			// ターミナル制御構造体。
	void		*signal_struct;		// シグナル操作構造体。
	void		*mm_struct;			// メモリー管理構造体アドレス。
	void		*file_struct;		// ファイル構造体アドレス。
	int			 gate;				// スピンロックゲート
}PROC;

/* プロセスリスト構造体。 */
typedef struct PROC_LIST{
	struct PROC_LIST *next;
	struct PROC_LIST *prev;
	int lockGate;
}PROC_LIST;

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


extern CPU cputask[];
extern PROC_LIST procHash[];


#define getProcAddr(address,member) (PROC*)((uint)address-(uint)&((PROC*)0)->member)


/*
 * 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*, int, int*);
extern void del_from_schedule(const int, int);
extern PROC *searchProcList(int);
extern void waitProc1();
extern void incrementNest();
extern void decrementNest();
extern int isNest();
extern int isSingleNest();
extern int forkKernelThread();
extern int initProc1();
extern int init_cputask(int);
extern int set_idle_proc(int);
extern void set_tss(int);
extern void start_tasking();
extern PROC *getNextProc(PROC*,int);
extern void sendSignalAllProc(int);
extern void exit(int,int);
extern int sys_fork();
extern int sys_exit();
extern int sys_exec();
extern int sys_wait();
extern int sys_getpid();
extern int sys_getgid();
extern int sys_getpgid();
extern int sys_getppid();
extern int sys_getuid();
extern int sys_getsid();
extern int sys_setgid();
extern int sys_setpgid();
extern int sys_setuid();
extern int sys_setsid();

extern int sys_times();


#endif


#endif
