/*
 * lock.h
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 */


#ifndef lock_h
#define lock_h


#include<proc.h>
#include<lib.h>
#include<console.h>
#include<limits.h>


#ifndef ASM_FILE


// 更新ロック用構造体
typedef struct{
	int volatile gate;		// カウント更新用スピンロックゲート
	int volatile count;		// カウント
}MODIFY_LOCK;


// スピンロックに入る
extern inline void enter_spinlock(int volatile *gate)
{
	int rest;

	for(;;){
		while (*gate == 1){;
		}
		asm volatile(
			"movl	$1,%%eax\n"
			"xchgl	%%eax,(%%edx)"
			:"=a"(rest):"d"(gate)
		);
		if (rest == 0){
			break;
		}
	}
}


// スピンロックから出る
extern inline void exit_spinlock(int volatile *gate)
{
	*gate=0;
}


extern inline void cli()
{
	asm volatile("cli");
}


extern inline void sti()
{
	asm volatile("sti");
}

extern void enterCli(int*);
extern void exitCli(int*);
extern void lockModify(MODIFY_LOCK *modifyLock);
extern void unlockModify(MODIFY_LOCK *modifyLock);
extern void countUpModify(MODIFY_LOCK *modifyLock);
extern void countDownModify(MODIFY_LOCK *modifyLock);


/*
 * Atomic set 1
 * parameters : Gate
 * returns : not set 0,already set 1
 */
/*extern inline int atomic_set(int *gate)
{
	int rest;

	asm volatile(
		"movl	$1,%%eax\n"
		"xchgl	%%eax,(%%edx)"
		:"=a"(rest):"d"(gate)
	);

	return rest;
}
*/

/*
 * 書込み用排他ロック。
 * parameters : 共有ロック構造体アドレス（static値で最初に0初期化されている必要がある。),最小読み込み中カウント
 */
/*extern inline void enterWriteLock(SHARE_LOCK volatile *share,int count)
{
	int rest;


	for(;;)
	{
		for(;;)
		{
			while(share->gate==1);
			asm volatile(
				"movl	$1,%%eax\n"
				"xchgl	%%eax,(%%edx)"
				:"=a"(rest):"d"(&share->gate)
			);
			if(rest==0)break;
		}

		if(share->count<=count)break;

		share->gate=0;
	}
}
*/

/*
 * 読込み用共有ロック。
 * parameters : 共有ロック構造体アドレス（static値で最初に0初期化されている必要がある。）
 */
/*extern inline void enterReadLock(SHARE_LOCK volatile *share)
{
	int rest;


	for(;;)
	{
		while(share->gate==1);
		asm volatile(
			"movl	$1,%%eax\n"
			"xchgl	%%eax,(%%edx)"
			:"=a"(rest):"d"(&share->gate)
		);
		if(rest==0)break;
	}

	++share->count;
	share->gate=0;
}
*/

/*
 * 書込み用排他ロックから出る
 * parameters : 共有ロック構造体アドレス（static値で最初に0初期化されている必要がある。）
 */
/*extern inline void exitWriteLock(SHARE_LOCK volatile *share)
{
	share->gate=0;
}
*/

/*
 * 読込み用共有ロックから出る
 * parameters : 共有ロック構造体アドレス（static値で最初に0初期化されている必要がある。）
 */
/*extern inline void exitReadLock(SHARE_LOCK volatile *share)
{
	--share->count;
}
*/

/*
 * 割り込みロック
 * 割り込みフラグを保存して割り込み不可を設定する
 * parameters : 割り込み可フラグ保存バッファ
 */
/*extern inline void enter_intrlock(int *iflag)
{
	asm volatile(
		"pushfl\n"
		"popl	%%eax\n"
		"cli"
		:"=a"(*iflag):
	);
	*iflag&=0x200;
}*/


/*
 * 割り込みロック解除
 * 保存されている割り込みフラグを復帰させる
 * parameters : 割り込み可フラグ保存バッファ
 */
/*extern inline void exit_intrlock(int *iflag)
{
	asm volatile(
		"pushfl\n"
		"popl	%%edx\n"
		"orl	%%eax,%%edx\n"
		"pushl	%%edx\n"
		"popfl"
		::"a"(*iflag)
	);
}*/


#endif


#endif
