PAPI  5.6.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
multiattach.c File Reference
Include dependency graph for multiattach.c:

Go to the source code of this file.

Macros

#define MULTIPLIER   5
 

Functions

static int wait_for_attach_and_loop (int num)
 
int main (int argc, char **argv)
 

Macro Definition Documentation

#define MULTIPLIER   5

Definition at line 39 of file multiattach.c.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 51 of file multiattach.c.

52 {
53  int status, retval, num_tests = 2, tmp;
55  int PAPI_event, PAPI_event2, mask1, mask2;
56  int num_events1, num_events2;
57  long long **values;
58  long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
59  char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN];
60  const PAPI_component_info_t *cmpinfo;
61  pid_t pid, pid2;
62  double ratio1,ratio2;
63 
64  /* Set TESTS_QUIET variable */
65  tests_quiet( argc, argv );
66 
67  /* Initialize the library */
69  if ( retval != PAPI_VER_CURRENT ) {
70  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
71  }
72 
73  /* get the component info and check if we support attach */
74  if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL ) {
75  test_fail( __FILE__, __LINE__, "PAPI_get_component_info", 0 );
76  }
77 
78  if ( cmpinfo->attach == 0 ) {
79  test_skip( __FILE__, __LINE__,
80  "Platform does not support attaching", 0 );
81  }
82 
83  /* fork off first child */
84  pid = fork( );
85  if ( pid < 0 ) {
86  test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
87  }
88  if ( pid == 0 ) {
90  }
91 
92  /* fork off second child, does twice as much */
93  pid2 = fork( );
94  if ( pid2 < 0 ) {
95  test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
96  }
97  if ( pid2 == 0 ) {
99  }
100 
101  /* add PAPI_TOT_CYC and one of the events in
102  PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS,
103  depending on the availability of the event
104  on the platform */
105  EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
106  EventSet2 = add_two_events( &num_events2, &PAPI_event2, &mask2 );
107 
108  if ( cmpinfo->attach_must_ptrace ) {
109  if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
110  perror( "ptrace(PTRACE_ATTACH)" );
111  return 1 ;
112  }
113  if ( waitpid( pid, &status, 0 ) == -1 ) {
114  perror( "waitpid()" );
115  exit( 1 );
116  }
117  if ( WIFSTOPPED( status ) == 0 ) {
118  test_fail( __FILE__, __LINE__,
119  "Child process didnt return true to WIFSTOPPED", 0 );
120  }
121 
122  if ( ptrace( PTRACE_ATTACH, pid2, NULL, NULL ) == -1 ) {
123  perror( "ptrace(PTRACE_ATTACH)" );
124  return 1;
125  }
126  if ( waitpid( pid2, &status, 0 ) == -1 ) {
127  perror( "waitpid()" );
128  exit( 1 );
129  }
130  if ( WIFSTOPPED( status ) == 0 ) {
131  test_fail( __FILE__, __LINE__,
132  "Child process didnt return true to WIFSTOPPED", 0 );
133  }
134  }
135 
136  retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
137  if ( retval != PAPI_OK ) {
138  test_fail( __FILE__, __LINE__, "PAPI_attach", retval );
139  }
140 
141  retval = PAPI_attach( EventSet2, ( unsigned long ) pid2 );
142  if ( retval != PAPI_OK ) {
143  test_fail( __FILE__, __LINE__, "PAPI_attach", retval );
144  }
145 
146  strcpy(event_name, "PAPI_TOT_INS");
147  sprintf( add_event_str, "PAPI_add_event[%s]", event_name );
148 
149  /* num_events1 is greater than num_events2 so don't worry. */
150 
151  values = allocate_test_space( num_tests, num_events1 );
152 
153  /* Gather before values */
154  elapsed_us = PAPI_get_real_usec( );
155  elapsed_cyc = PAPI_get_real_cyc( );
156  elapsed_virt_us = PAPI_get_virt_usec( );
157  elapsed_virt_cyc = PAPI_get_virt_cyc( );
158 
159  /* Wait for the SIGSTOP. */
160  if ( cmpinfo->attach_must_ptrace ) {
161  if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
162  perror( "ptrace(PTRACE_CONT)" );
163  return 1;
164  }
165  if ( waitpid( pid, &status, 0 ) == -1 ) {
166  perror( "waitpid()" );
167  exit( 1 );
168  }
169  if ( WIFSTOPPED( status ) == 0 ) {
170  test_fail( __FILE__, __LINE__,
171  "Child process didn't return true to WIFSTOPPED", 0 );
172  }
173  if ( WSTOPSIG( status ) != SIGSTOP ) {
174  test_fail( __FILE__, __LINE__,
175  "Child process didn't stop on SIGSTOP", 0 );
176  }
177 
178  if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
179  perror( "ptrace(PTRACE_CONT)" );
180  return 1;
181  }
182  if ( waitpid( pid2, &status, 0 ) == -1 ) {
183  perror( "waitpid()" );
184  exit( 1 );
185  }
186  if ( WIFSTOPPED( status ) == 0 ) {
187  test_fail( __FILE__, __LINE__,
188  "Child process didn't return true to WIFSTOPPED", 0 );
189  }
190  if ( WSTOPSIG( status ) != SIGSTOP ) {
191  test_fail( __FILE__, __LINE__,
192  "Child process didn't stop on SIGSTOP", 0 );
193  }
194  }
195 
196  /* start measuring in first child */
197  retval = PAPI_start( EventSet1 );
198  if ( retval != PAPI_OK ) {
199  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
200  }
201 
202  /* start measuring in second child */
203  retval = PAPI_start( EventSet2 );
204  if ( retval != PAPI_OK ) {
205  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
206  }
207 
208  /* Start first child and Wait for the SIGSTOP. */
209  if ( cmpinfo->attach_must_ptrace ) {
210  if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
211  perror( "ptrace(PTRACE_ATTACH)" );
212  return 1;
213  }
214  if ( waitpid( pid, &status, 0 ) == -1 ) {
215  perror( "waitpid()" );
216  exit( 1 );
217  }
218  if ( WIFSTOPPED( status ) == 0 ) {
219  test_fail( __FILE__, __LINE__,
220  "Child process didn't return true to WIFSTOPPED", 0 );
221  }
222  if ( WSTOPSIG( status ) != SIGSTOP ) {
223  test_fail( __FILE__, __LINE__,
224  "Child process didn't stop on SIGSTOP", 0 );
225  }
226 
227  /* Start second child and Wait for the SIGSTOP. */
228  if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
229  perror( "ptrace(PTRACE_ATTACH)" );
230  return 1;
231  }
232  if ( waitpid( pid2, &status, 0 ) == -1 ) {
233  perror( "waitpid()" );
234  exit( 1 );
235  }
236  if ( WIFSTOPPED( status ) == 0 ) {
237  test_fail( __FILE__, __LINE__,
238  "Child process didn't return true to WIFSTOPPED", 0 );
239  }
240  if ( WSTOPSIG( status ) != SIGSTOP ) {
241  test_fail( __FILE__, __LINE__,
242  "Child process didn't stop on SIGSTOP", 0 );
243  }
244  }
245 
246  elapsed_virt_us = PAPI_get_virt_usec( ) - elapsed_virt_us;
247  elapsed_virt_cyc = PAPI_get_virt_cyc( ) - elapsed_virt_cyc;
248  elapsed_us = PAPI_get_real_usec( ) - elapsed_us;
249  elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc;
250 
251  /* stop measuring and read first child */
252  retval = PAPI_stop( EventSet1, values[0] );
253  if ( retval != PAPI_OK ) {
254  printf( "Warning: PAPI_stop returned error %d, probably ok.\n",
255  retval );
256  }
257 
258  /* stop measuring and read second child */
259  retval = PAPI_stop( EventSet2, values[1] );
260  if ( retval != PAPI_OK ) {
261  printf( "Warning: PAPI_stop returned error %d, probably ok.\n",
262  retval );
263  }
264 
265  /* close down the measurements */
266  remove_test_events( &EventSet1, mask1 );
267  remove_test_events( &EventSet2, mask2 );
268 
269  /* restart events so they can end */
270  if ( cmpinfo->attach_must_ptrace ) {
271  if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
272  perror( "ptrace(PTRACE_CONT)" );
273  return 1;
274  }
275  if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
276  perror( "ptrace(PTRACE_CONT)" );
277  return 1;
278  }
279  }
280 
281  if ( waitpid( pid, &status, 0 ) == -1 ) {
282  perror( "waitpid()" );
283  exit( 1 );
284  }
285  if ( WIFEXITED( status ) == 0 ) {
286  test_fail( __FILE__, __LINE__,
287  "Child process didn't return true to WIFEXITED", 0 );
288  }
289 
290  if ( waitpid( pid2, &status, 0 ) == -1 ) {
291  perror( "waitpid()" );
292  exit( 1 );
293  }
294  if ( WIFEXITED( status ) == 0 ) {
295  test_fail( __FILE__, __LINE__,
296  "Child process didn't return true to WIFEXITED", 0 );
297  }
298 
299  /* This code isn't necessary as we know the child has exited, */
300  /* it *may* return an error if the component so chooses. You */
301  /* should use read() instead. */
302 
303  if (!TESTS_QUIET) {
304  printf( "Test case: multiple 3rd party attach start, stop.\n" );
305  printf( "-----------------------------------------------\n" );
306  tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
307  printf( "Default domain is: %d (%s)\n", tmp,
309  tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
310  printf( "Default granularity is: %d (%s)\n", tmp,
312  printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
313  printf( "-------------------------------------------------------------------------\n" );
314 
315  sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid,
316  event_name );
317  printf( TAB1, add_event_str, values[0][1] );
318  sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t",
319  ( intmax_t ) pid );
320  printf( TAB1, add_event_str, values[0][0] );
321  sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid2,
322  event_name );
323  printf( TAB1, add_event_str,values[1][1] );
324  sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t",
325  ( intmax_t ) pid2 );
326  printf( TAB1, add_event_str, values[1][0] );
327  printf( TAB1, "Real usec : \t", elapsed_us );
328  printf( TAB1, "Real cycles : \t", elapsed_cyc );
329  printf( TAB1, "Virt usec : \t", elapsed_virt_us );
330  printf( TAB1, "Virt cycles : \t", elapsed_virt_cyc );
331 
332  printf( "-------------------------------------------------------------------------\n" );
333 
334  printf("Verification: pid %d results should be %dx pid %d\n",
335  pid2,MULTIPLIER,pid );
336  }
337 
338  /* FLOPS ratio */
339  ratio1=(double)values[1][0]/(double)values[0][0];
340 
341  /* CYCLES ratio */
342  ratio2=(double)values[1][1]/(double)values[0][1];
343 
344  if (!TESTS_QUIET) {
345  printf("\tFLOPS ratio %lld/%lld = %lf\n",
346  values[1][0],values[0][0],ratio1);
347  }
348 
349  double ratio1_high,ratio1_low,ratio2_high,ratio2_low;
350 
351  ratio1_high=(double)MULTIPLIER *1.10;
352  ratio1_low=(double)MULTIPLIER * 0.90;
353 
354  if ((ratio1 > ratio1_high ) || (ratio1 < ratio1_low)) {
355  printf("Ratio out of range, should be ~%lf not %lf\n",
356  (double)MULTIPLIER, ratio1);
357  test_fail( __FILE__, __LINE__,
358  "Error: Counter ratio not two", 0 );
359  }
360 
361  if (!TESTS_QUIET) {
362  printf("\tCycles ratio %lld/%lld = %lf\n",
363  values[1][1],values[0][1],ratio2);
364  }
365 
366  ratio2_high=(double)MULTIPLIER *1.20;
367  ratio2_low=(double)MULTIPLIER * 0.80;
368 
369  if ((ratio2 > ratio2_high ) || (ratio2 < ratio2_low )) {
370  printf("Ratio out of range, should be ~%lf, not %lf\n",
371  (double)MULTIPLIER, ratio2);
372  test_fail( __FILE__, __LINE__,
373  "Known issue: Counter ratio not two", 0 );
374  }
375 
376  test_pass( __FILE__ );
377 
378  return 0;
379 }
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:29
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2314
int mask1
Definition: zero_fork.c:48
int PAPI_event[2]
Definition: data_range.c:30
const PAPI_component_info_t * PAPI_get_component_info(int cidx)
Definition: papi.c:796
void test_pass(const char *filename)
Definition: test_utils.c:432
long long PAPI_get_virt_usec(void)
Definition: papi.c:6372
static int wait_for_attach_and_loop(void)
Definition: attach2.c:41
unsigned int attach
Definition: papi.h:662
char * stringify_granularity(int granularity)
Definition: test_utils.c:353
long long PAPI_get_virt_cyc(void)
Definition: papi.c:6300
#define PAPI_NULL
Definition: papi.h:292
int num_events1
Definition: zero_fork.c:49
#define TAB1
Definition: papi_test.h:88
return PAPI_OK
Definition: linux-nvml.c:497
#define NUM_FLOPS
Definition: sdsc-mpx.c:24
static double
Definition: fileop.c:1281
int int argc
Definition: iozone.c:1609
void test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:559
char ** argv
Definition: iozone.c:1610
int PAPI_library_init(int version)
Definition: papi.c:500
char * stringify_all_domains(int domains)
Definition: test_utils.c:293
unsigned int attach_must_ptrace
Definition: papi.h:663
static int pid
int PAPI_get_opt(int option, PAPI_option_t *ptr)
Definition: papi.c:4143
long long elapsed_cyc
Definition: zero_fork.c:50
#define MULTIPLIER
Definition: multiattach.c:39
#define PAPI_ESYS
Definition: papi.h:255
int add_two_events(int *num_events, int *papi_event, int *mask)
Definition: test_utils.c:615
#define PAPI_DEFGRN
Definition: papi.h:434
int EventSet2
Definition: rapl_overflow.c:16
int num_tests
Definition: zero_fork.c:53
strcpy(filename, default_filename)
long long PAPI_get_real_usec(void)
Definition: papi.c:6264
printf("\tTry: -i 0 -i 1 \n\n")
long long status
Definition: iozone.c:1335
int TESTS_QUIET
Definition: test_utils.c:18
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:468
#define PAPI_DEFDOM
Definition: papi.h:432
#define PAPI_MAX_STR_LEN
Definition: papi.h:465
int PAPI_attach(int EventSet, unsigned long tid)
Definition: papi.c:3201
long long PAPI_get_real_cyc(void)
Definition: papi.c:6217
int PAPI_start(int EventSet)
Definition: papi.c:2096
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
ssize_t retval
Definition: libasync.c:338
long long tmp
Definition: iozone.c:12031
long long elapsed_us
Definition: zero_fork.c:50
long long ** allocate_test_space(int num_tests, int num_events)
Definition: test_utils.c:46
#define PAPI_VER_CURRENT
Definition: papi.h:225
void exit()
int remove_test_events(int *EventSet, int mask)
Definition: test_utils.c:201
int EventSet1
Definition: zero_fork.c:47

Here is the call graph for this function:

static int wait_for_attach_and_loop ( int  num)
static

Definition at line 42 of file multiattach.c.

43 {
44  kill( getpid( ), SIGSTOP );
45  do_flops( NUM_FLOPS * num );
46  kill( getpid( ), SIGSTOP );
47  return 0;
48 }
kill(master_listen_pid, SIGKILL)
#define NUM_FLOPS
Definition: sdsc-mpx.c:24
void int num
Definition: iozone.c:22151
void do_flops(int n)
Definition: multiplex.c:23

Here is the call graph for this function: