mwait.c revision 10528
110528Smorr@cs.wisc.edu// author: Marc Orr 210528Smorr@cs.wisc.edu 310528Smorr@cs.wisc.edu#include <pthread.h> 410528Smorr@cs.wisc.edu#include <stdio.h> 510528Smorr@cs.wisc.edu#include <stdlib.h> 610528Smorr@cs.wisc.edu 710528Smorr@cs.wisc.edu#define NUM_TRIES 1000 810528Smorr@cs.wisc.edu 910528Smorr@cs.wisc.edu// Make sure that flags and wait sit in different cache lines 1010528Smorr@cs.wisc.eduvolatile int flags[10]; 1110528Smorr@cs.wisc.eduvolatile int wait[10]; 1210528Smorr@cs.wisc.edu 1310528Smorr@cs.wisc.edupthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 1410528Smorr@cs.wisc.edu 1510528Smorr@cs.wisc.eduvoid *DoWork1(void *threadid) 1610528Smorr@cs.wisc.edu{ 1710528Smorr@cs.wisc.edu flags[0] = flags[0] + 1; 1810528Smorr@cs.wisc.edu wait[0] = 0; 1910528Smorr@cs.wisc.edu pthread_exit(0); 2010528Smorr@cs.wisc.edu} 2110528Smorr@cs.wisc.edu 2210528Smorr@cs.wisc.eduvoid *DoWork2(void *threadid) 2310528Smorr@cs.wisc.edu{ 2410528Smorr@cs.wisc.edu pthread_mutex_lock (&mutex); 2510528Smorr@cs.wisc.edu flags[0] = flags[0] + 1; 2610528Smorr@cs.wisc.edu pthread_mutex_unlock (&mutex); 2710528Smorr@cs.wisc.edu pthread_exit(0); 2810528Smorr@cs.wisc.edu} 2910528Smorr@cs.wisc.edu 3010528Smorr@cs.wisc.edu//////////////////////////////////////////////////////////////////////////////// 3110528Smorr@cs.wisc.edu// Program main 3210528Smorr@cs.wisc.edu//////////////////////////////////////////////////////////////////////////////// 3310528Smorr@cs.wisc.eduint main( int argc, char** argv) 3410528Smorr@cs.wisc.edu{ 3510528Smorr@cs.wisc.edu // stuff for thread 3610528Smorr@cs.wisc.edu pthread_t threads[1]; 3710528Smorr@cs.wisc.edu 3810528Smorr@cs.wisc.edu // initialize global variables 3910528Smorr@cs.wisc.edu flags[0] = 0; 4010528Smorr@cs.wisc.edu wait[0] = 1; 4110528Smorr@cs.wisc.edu 4210528Smorr@cs.wisc.edu // monitor (via gcc intrinsic) 4310528Smorr@cs.wisc.edu __builtin_ia32_monitor ((void *)&flags, 0, 0); 4410528Smorr@cs.wisc.edu 4510528Smorr@cs.wisc.edu // invalidate flags in this cpu's cache 4610528Smorr@cs.wisc.edu pthread_create(&threads[0], NULL, DoWork1, NULL); 4710528Smorr@cs.wisc.edu while(wait[0]); 4810528Smorr@cs.wisc.edu 4910528Smorr@cs.wisc.edu // launch thread to invalidate address being monitored 5010528Smorr@cs.wisc.edu pthread_create(&threads[0], NULL, DoWork2, NULL); 5110528Smorr@cs.wisc.edu 5210528Smorr@cs.wisc.edu // wait for other thread to modify flags 5310528Smorr@cs.wisc.edu int mwait_cnt = 0; 5410528Smorr@cs.wisc.edu do { 5510528Smorr@cs.wisc.edu pthread_mutex_lock (&mutex); 5610528Smorr@cs.wisc.edu if(flags[0] != 2) { 5710528Smorr@cs.wisc.edu pthread_mutex_unlock (&mutex); 5810528Smorr@cs.wisc.edu __builtin_ia32_mwait(0, 0); 5910528Smorr@cs.wisc.edu } else { 6010528Smorr@cs.wisc.edu pthread_mutex_unlock (&mutex); 6110528Smorr@cs.wisc.edu } 6210528Smorr@cs.wisc.edu mwait_cnt++; 6310528Smorr@cs.wisc.edu } while(flags[0] != 2 && mwait_cnt < NUM_TRIES); 6410528Smorr@cs.wisc.edu 6510528Smorr@cs.wisc.edu // test may hang if mwait is not working 6610528Smorr@cs.wisc.edu if(flags[0]==2) { 6710528Smorr@cs.wisc.edu printf("mwait regression PASSED, flags[0] = %d\n", flags[0]); 6810528Smorr@cs.wisc.edu } else { 6910528Smorr@cs.wisc.edu printf("mwait regression FAILED, flags[0] = %d\n", flags[0]); 7010528Smorr@cs.wisc.edu } 7110528Smorr@cs.wisc.edu 7210528Smorr@cs.wisc.edu return 0; 7310528Smorr@cs.wisc.edu} 74