Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 May 2002 17:58:54 -0700
From:      Jonathan Mini <mini@freebsd.org>
To:        John Baldwin <jhb@FreeBSD.ORG>
Cc:        current@FreeBSD.ORG
Subject:   Re: Please test PAUSE on non-Intel processors
Message-ID:  <20020524175854.C64383@stylus.haikugeek.com>
In-Reply-To: <XFMail.20020524102553.jhb@FreeBSD.org>; from jhb@FreeBSD.ORG on Fri, May 24, 2002 at 10:25:53AM -0400
References:  <XFMail.20020524102553.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

I get:
stylus:~$ cc pausetest.c
stylus:~$ ./a.out
Testing PAUSE instruction:
Register esp changed: 0xbfbff79c -> 0xbfbff760

.. I assume this is functional. =)

I have:

CPU: AMD Athlon(tm) MP 1900+ (1592.90-MHz 686-class CPU)
  Origin = "AuthenticAMD"  Id = 0x662  Stepping = 2
  Features=0x383fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CM
OV,PAT,PSE36,MMX,FXSR,SSE>
  AMD Features=0xc0480000<MP,AMIE,DSP,3DNow!>
Programming 24 pins in IOAPIC #0
IOAPIC #0 intpin 2 -> irq 0
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
 cpu0 (BSP): apic id:  1, version: 0x00040010, at 0xfee00000
 cpu1 (AP):  apic id:  0, version: 0x00040010, at 0xfee00000
 io0 (APIC): apic id:  2, version: 0x00170011, at 0xfec00000
Pentium Pro MTRR support enabled
Using $PIR table, 268435454 entries at 0xc00fdef0

John Baldwin [jhb@FreeBSD.ORG] wrote :

> Hey gang, although Intel's document seems to claim that they tested
> proper operation of pause I'd like people with non-Intel processors
> to verify that it actually works.  Please compile the attached test
> program and run it.  The output should look like this:
> 
> > ./pt
> Testing PAUSE instruction:
> Register esp changed: 0xbfbff9fc -> 0xbfbff9c0
> 
> If you get a signal or any of the other registers change their value,
> please let me know.  I've tested this on a Pentium III mobile, a K6-II,
> and an Athlon.  The program cmopiles ok on both stable and current.
> 
> -----FW: <200205212226.g4LMQaV68801@freefall.freebsd.org>-----
> 
> Date: Tue, 21 May 2002 15:26:36 -0700 (PDT)
> Sender: owner-cvs-committers@FreeBSD.org
> From: John Baldwin <jhb@FreeBSD.org>
> To: cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
> Subject: cvs commit: src/sys/kern kern_mutex.c
> 
> jhb         2002/05/21 15:26:36 PDT
> 
>   Modified files:
>     sys/kern             kern_mutex.c 
>   Log:
>   Add appropriate IA32 "pause" instructions to improve performanec on
>   Pentium 4's and newer IA32 processors.  The "pause" instruction has been
>   verified by Intel to be a NOP on all currently existing IA32 processors
>   prior to the Pentium 4.
>   
>   Revision  Changes    Path
>   1.95      +17 -1     src/sys/kern/kern_mutex.c
> 
> --------------End of forwarded message-------------------------
> 
> -- 
> 
> John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
> "Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

Content-Description: pausetest.c
> /*
>  * Simple program to see if the new IA32 PAUSE instruction works properly.
>  * We test two different things: 1) that we don't get an illegal instruction
>  * fault, and 2) that no registers change state.
>  */
> 
> #include <sys/types.h>
> #include <stdio.h>
> 
> #define	NUM_SEGREGS	6
> #define	NUM_REGS	15
> 
> #define	PUSH_REGS			\
> 	"	pushf ;\n"		\
> 	"	pusha ;\n"		\
> 	"	push %cs ;\n"		\
> 	"	push %ds ;\n"		\
> 	"	push %es ;\n"		\
> 	"	push %fs ;\n"		\
> 	"	push %gs ;\n"		\
> 	"	push %ss ;\n"
> 
> const char *register_names[NUM_REGS] = {
> 	"ss", "gs", "fs", "es", "ds", "cs",
> 	"edi", "esi", "ebp", "esp", "ebx", "edx", "ecx", "eax",
> 	"eflags"
> };
> 
> struct register_set {
> 	register_t	r_regs[NUM_REGS];
> /*
> 	register_t	r_ss;
> 	register_t	r_gs;
> 	register_t	r_fs;
> 	register_t	r_es;
> 	register_t	r_ds;
> 	register_t	r_cs;
> 	register_t	r_edi;
> 	register_t	r_esi;
> 	register_t	r_ebp;
> 	register_t	r_isp;
> 	register_t	r_ebx;
> 	register_t	r_edx;
> 	register_t	r_ecx;
> 	register_t	r_eax;
> 	register_t	r_eflags;
>  */
> };
> 
> void
> compare_registers(struct register_set after, struct register_set before)
> {
> 	int i;
> 
> 	for (i = 0; i < NUM_SEGREGS; i++) {
> 		before.r_regs[i] &= 0xffff;
> 		after.r_regs[i] &= 0xffff;
> 	}
> 	for (i = 0; i < NUM_REGS; i++)
> 		if (before.r_regs[i] != after.r_regs[i])
> 			printf("Register %s changed: %#x -> %#x\n",
> 			    register_names[i], before.r_regs[i],
> 			    after.r_regs[i]);
> }
> 
> void
> test_pause(void)
> {
> 	__asm __volatile(
> 	"	mov $10,%ecx ;\n"
> 	PUSH_REGS
> 	"	pause ;\n"
> 	PUSH_REGS
> 	"	call compare_registers ;\n"
> 	"	addl $0x78,%esp ;\n");
> }
> 
> int
> main(int ac, char **av)
> {
> 
> 	printf("Testing PAUSE instruction:\n");
> 	test_pause();
> 	return (0);
> }


-- 
Jonathan Mini <mini@freebsd.org>
http://www.haikugeek.com

"He who is not aware of his ignorance will be only misled by his knowledge."
                                                        -- Richard Whatley

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020524175854.C64383>