/*
 * 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"


#ifndef ASM_FILE


/*
 * 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 enter_spinlock(int *gate)
{
	int rest;


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


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


/*
 * 割り込みロック
 * 割り込みフラグを保存して割り込み不可を設定する
 * 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
