Subject: Re: Test and set (was Re: postgreSQL)
To: Chris G. Demetriou <cgd@netbsd.org>
From: Simon Burge <simonb@netbsd.org>
List: tech-kern
Date: 05/26/1999 23:01:04
Chris G. Demetriou wrote:

> Simon Burge <simonb@netbsd.org> writes:
> > NetBSD doesn't have anything like this - would it be a waste of a system
> > call (or a possibly system-call backed library routine) to add some sort
> > of MI atomic test and set operation?
> 
> Yes, it would be a waste of a syscall.
> 
> This is best implemented without kernel interaction if possible,
> because of the cost of of a syscall.  that's possible on several
> architectures.
> 
> On architectures where it has to be implemented as a sycall, the right
> syscall already exists (sysarch()).
> 
> A standard API would be fine, good actually.

As far as I can tell, this is a DEC API, not a MIPS API.  But it is most
useful on MIPS, so I guess the "right" thing to do is implement it as an
architecture-specific call and not a machine specific call.  Would we
need to add the same API for VAX/Ultrix and Alpha/OSF1 compatibility as
well?  And would it go in libc or libcompat?

> > The R4000 and later MIPS processors (actually MIPS II CPUs and later)
> > have the LL (Load Linked) and SC (Store Conditional) instructions, but
> > this really doesn't help everyone :-(  Are there any other archs other
> > than MIPS that don't have a test and set available to user code?
> 
> really, on the mips, what you probably want is a library
> routine/function pointer which on first run checks the cpu type and
> replaces the function pointer either with one that invokes a the LL/SC
> instructions or invokes the syscall.

This is what I meant by "or a possibly system-call backed library
routine".  From what I can tell, on the MIPS you can't tell which CPU
type you have from userland so we'd need a sysctl to give us the CPU
architecture.  It looks as though we don't have the machinery in place
(on MIPS at least) to support arch-dependant vs. cpu-dependant sysctl's
at the moment - I'll look into that.

So we'd end up with something like for MIPS:

	atomic_op(foo, bar, ...)
	{
		static int cpu_arch = 0;

		if (cpu_arch == 0)
			sysarch(GET_CPU_ARCH, &cpu_arch);

		if (cpu_arch == 1)
			/* No LL/SC on MIPS I */
			sysarch(TEST_AND_SET, ...);
		else
			load_linked, store_conditional
	}

Sound good?

Simon.