mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-09 05:10:23 +00:00
clearer what they mean: - They all have VGCONF_ prefixes now, to indicate they come out of configure.in (and are clearly distinguished from the VGA_/VGO_/VGP_ #defines passed in to C files). - The ones that refer to the primary *or* secondary platform have _INCLUDES_ in them. - The ones that are in all-caps have a _CAPS suffix. So, for example, what was VGP_X86_LINUX is now VGCONF_PLATFORMS_INCLUDE_X86_LINUX, which is more verbose but also a lot clearer. The names of the #defines used in the C files (VGA_x86, VGO_linux, etc) are unchanged. cputest.c: changed to reflect the Valgrind installation's capabilities, rather than the machine's capabilities. In particular, if --enable-only32bit is used on a 64-bit machine, then this program will claim to only support 32-bits. Also use the VGA/VGO/VGP macros which are clearer than the __i386__ ones. (This is partially merged from the DARWIN branch.) configure.in: clean up the comments, distinguish different sections more clearly, and generally make it more readable. valgrind.pc.in: try to make this more accurate. I doubt anyone's using it. It doesn't appear to be set up to handle dual-architecture builds. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9031
88 lines
1.8 KiB
C
88 lines
1.8 KiB
C
/*
|
|
Check that a thread which yields with pause (rep;nop) makes less
|
|
progress against a pure spinner.
|
|
*/
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
static pthread_mutex_t m_go = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_cond_t c_go = PTHREAD_COND_INITIALIZER;
|
|
static pthread_cond_t c_running = PTHREAD_COND_INITIALIZER;
|
|
|
|
static volatile int alive, running;
|
|
|
|
static int spin;
|
|
static int rep_nop;
|
|
|
|
static void *spinner(void *v)
|
|
{
|
|
pthread_mutex_lock(&m_go);
|
|
while(!alive)
|
|
pthread_cond_wait(&c_go, &m_go);
|
|
running++;
|
|
pthread_cond_signal(&c_running);
|
|
pthread_mutex_unlock(&m_go);
|
|
|
|
while(alive)
|
|
spin++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void *rep_nopper(void *v)
|
|
{
|
|
pthread_mutex_lock(&m_go);
|
|
while(!alive)
|
|
pthread_cond_wait(&c_go, &m_go);
|
|
running++;
|
|
pthread_cond_signal(&c_running);
|
|
pthread_mutex_unlock(&m_go);
|
|
|
|
while(alive) {
|
|
rep_nop++;
|
|
// This gives a hint to a P4, telling it to pause
|
|
// (ie. we're in a spin-wait loop)
|
|
asm volatile ("rep; nop" : : : "memory");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
pthread_t a, b;
|
|
|
|
pthread_create(&a, NULL, spinner, NULL);
|
|
pthread_create(&b, NULL, rep_nopper, NULL);
|
|
|
|
/* make sure both threads start at the same time */
|
|
pthread_mutex_lock(&m_go);
|
|
alive = 1;
|
|
pthread_cond_broadcast(&c_go);
|
|
|
|
/* make sure they both get started */
|
|
while(running < 2)
|
|
pthread_cond_wait(&c_running, &m_go);
|
|
pthread_mutex_unlock(&m_go);
|
|
|
|
sleep(2);
|
|
|
|
alive = 0;
|
|
pthread_join(a, NULL);
|
|
pthread_join(b, NULL);
|
|
|
|
if (0)
|
|
printf("spin=%d rep_nop=%d rep_nop:spin ratio: %g\n",
|
|
spin, rep_nop, (float)rep_nop / spin);
|
|
|
|
if (spin > rep_nop)
|
|
printf("PASS\n");
|
|
else
|
|
printf("FAIL spin=%d rep_nop=%d rep_nop:spin ratio: %g\n",
|
|
spin, rep_nop, (float)rep_nop / spin);
|
|
|
|
return 0;
|
|
}
|