|
PAPI
5.0.1.0
|
00001 /**************************************************************************** 00002 * This program shows how to use PAPI_register_thread, PAPI_lock, * 00003 * PAPI_unlock, PAPI_set_thr_specific, PAPI_get_thr_specific. * 00004 * Warning: Don't use PAPI_lock and PAPI_unlock on platforms on which the * 00005 * locking mechanisms are not implemented. * 00006 ****************************************************************************/ 00007 00008 #include <stdio.h> 00009 #include <stdlib.h> 00010 #include <pthread.h> 00011 #include "papi.h" /* This needs to be included every time you use PAPI */ 00012 00013 #define ERROR_RETURN(retval) { fprintf(stderr, "Error %d %s:line %d: \n", retval,__FILE__,__LINE__); exit(retval); } 00014 00015 #define LOOPS 100000 00016 #define SLEEP_VALUE 20000 00017 00018 int count; 00019 int rank; 00020 00021 void *Master(void *arg) 00022 { 00023 int i, retval, tmp; 00024 int *pointer, * pointer2; 00025 00026 tmp = 20; 00027 pointer = &tmp; 00028 00029 /* register the thread */ 00030 if ( (retval=PAPI_register_thread())!= PAPI_OK ) 00031 ERROR_RETURN(retval); 00032 00033 /* save the pointer for late use */ 00034 if ( (retval=PAPI_set_thr_specific(1,pointer))!= PAPI_OK ) 00035 ERROR_RETURN(retval); 00036 /* change the value of tmp */ 00037 tmp = 15; 00038 00039 usleep(SLEEP_VALUE); 00040 PAPI_lock(PAPI_USR1_LOCK); 00041 /* Make sure Slaves are not sleeping */ 00042 for (i = 0; i < LOOPS; i++) { 00043 count = 2 * count - i; 00044 } 00045 PAPI_unlock(PAPI_USR1_LOCK); 00046 00047 /* retrieve the pointer saved by PAPI_set_thr_specific */ 00048 if ( (retval=PAPI_get_thr_specific(1, (void *)&pointer2)) != PAPI_OK ) 00049 ERROR_RETURN(retval); 00050 00051 /* the output value should be 15 */ 00052 printf("Thread specific data is %d \n", *pointer2); 00053 00054 pthread_exit(NULL); 00055 } 00056 00057 void *Slave(void *arg) 00058 { 00059 int i; 00060 00061 PAPI_lock(PAPI_USR2_LOCK); 00062 PAPI_lock(PAPI_USR1_LOCK); 00063 for (i = 0; i < LOOPS; i++) { 00064 count += i; 00065 } 00066 PAPI_unlock(PAPI_USR1_LOCK); 00067 PAPI_unlock(PAPI_USR2_LOCK); 00068 pthread_exit(NULL); 00069 } 00070 00071 00072 00073 int main(int argc, char **argv) 00074 { 00075 pthread_t master; 00076 pthread_t slave1; 00077 int result_m, result_s, rc, i; 00078 int retval; 00079 00080 /* Setup a random number so compilers can't optimize it out */ 00081 count = rand(); 00082 result_m = count; 00083 rank = 0; 00084 00085 for (i = 0; i < LOOPS; i++) { 00086 result_m = 2 * result_m - i; 00087 } 00088 result_s = result_m; 00089 00090 for (i = 0; i < LOOPS; i++) { 00091 result_s += i; 00092 } 00093 00094 if ((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT) 00095 { 00096 printf("Library initialization error! \n"); 00097 exit(-1); 00098 } 00099 00100 if ((retval = PAPI_thread_init(&pthread_self)) != PAPI_OK) 00101 ERROR_RETURN(retval); 00102 00103 if ((retval = PAPI_set_debug(PAPI_VERB_ECONT)) != PAPI_OK) 00104 ERROR_RETURN(retval); 00105 00106 PAPI_lock(PAPI_USR2_LOCK); 00107 rc = pthread_create(&master, NULL, Master, NULL); 00108 if (rc) { 00109 retval = PAPI_ESYS; 00110 ERROR_RETURN(retval); 00111 } 00112 rc = pthread_create(&slave1, NULL, Slave, NULL); 00113 if (rc) { 00114 retval = PAPI_ESYS; 00115 ERROR_RETURN(retval); 00116 } 00117 pthread_join(master, NULL); 00118 printf("Master: Expected: %d Recieved: %d\n", result_m, count); 00119 if (result_m != count) 00120 ERROR_RETURN(1); 00121 PAPI_unlock(PAPI_USR2_LOCK); 00122 00123 pthread_join(slave1, NULL); 00124 printf("Slave: Expected: %d Recieved: %d\n", result_s, count); 00125 00126 if (result_s != count) 00127 ERROR_RETURN(1); 00128 00129 exit(0); 00130 }