require '_h2ph_pre.ph';

no warnings qw(redefine misc);

unless(defined(&_SYS_LOCK_H_)) {
    eval 'sub _SYS_LOCK_H_ () {1;}' unless defined(&_SYS_LOCK_H_);
    require 'sys/stdint.ph';
    require 'sys/mutex.ph';
    require 'machine/lock.ph';
    if(defined(&_KERNEL)) {
	if(defined(&_KERNEL_OPT)) {
	    require './sys/opt_lockdebug.ph';
	}
	unless(defined(&SPINLOCK_SPIN_HOOK)) {
	    eval 'sub SPINLOCK_SPIN_HOOK () {1;}' unless defined(&SPINLOCK_SPIN_HOOK);
	}
	unless(defined(&SPINLOCK_BACKOFF_HOOK)) {
	    require 'sys/systm.ph';
	    eval 'sub SPINLOCK_BACKOFF_HOOK () { &nullop( &NULL);}' unless defined(&SPINLOCK_BACKOFF_HOOK);
	}
	unless(defined(&SPINLOCK_BACKOFF_MIN)) {
	    eval 'sub SPINLOCK_BACKOFF_MIN () {4;}' unless defined(&SPINLOCK_BACKOFF_MIN);
	}
	unless(defined(&SPINLOCK_BACKOFF_MAX)) {
	    eval 'sub SPINLOCK_BACKOFF_MAX () {128;}' unless defined(&SPINLOCK_BACKOFF_MAX);
	}
	eval 'sub SPINLOCK_BACKOFF {
	    my($count) = @_;
    	    eval q( &do { \'int\'  &__i;  &for ( &__i = ($count);  &__i != 0;  &__i--) {  &SPINLOCK_BACKOFF_HOOK; }  &if (($count) <  &SPINLOCK_BACKOFF_MAX) ($count) += ($count); }  &while ( 0););
	}' unless defined(&SPINLOCK_BACKOFF);
	if(defined(&LOCKDEBUG)) {
	    eval 'sub SPINLOCK_SPINOUT {
	        my($spins) = @_;
    		eval q((($spins)++ > 0xfffffff));
	    }' unless defined(&SPINLOCK_SPINOUT);
	} else {
	    eval 'sub SPINLOCK_SPINOUT {
	        my($spins) = @_;
    		eval q((( &void)($spins), 0));
	    }' unless defined(&SPINLOCK_SPINOUT);
	}
    }
}
1;
