Example 1

Problem: Verify that -fdata-race-packed-stores doesn't actually mask and store into a larger part of the word than a given field. This test will verify that the code for setting the field will not show any visible side effects to another thread.

The loop continues until the end of the test function is reached. At this point, another inferior function call is made which verifies that each field in the structure contains the correct value, included the variable which was set by the test.

If the generated code is loading a value, masking off the appropriate fields, and storing back into the word, then the value stored back into the other parts of the structure will be an older value than the current one expected by the inferior function call, and the verification will cause a testcase failure.

If the test is working as expected, then the other fields in the structure will always have the correct value.

#include <stdio.h>

 struct test_struct {
   char a;
   char b;
   char c;
   char d;
 } var = {0,0,0,0};

 extern int fini;
 extern void done();

/* Test function which set the value of field 'a' */
 void set_a(char x)
 {
   var.a = x;
 }

 static int global = 0;

/* Bump the value of the global by one every 'cycle', set all other fields.  */
 void other_threads() 
 {
   global++;
   var.b = global;
   var.c = global;
   var.d = global;
 }

/* All other fields should always be the value of 'global' */
 int step_verify()
 {
   int ret = 0;
   if (var.b != global)
     {
       printf("FAIL : Unexpected value. var.b %d should be %d\n", var.b, global);
       ret = 1;
     }
   if (var.c != global)
     {
       printf("FAIL : Unexpected value. var.c %d should be %d\n", var.c, global);
       ret = 1;
     }
   if (var.d != global)
     {
       printf("FAIL : Unexpected value. var.d %d should be %d\n", var.d, global);
       ret = 1;
     }
   return ret;
 }

 void final_verify()
 {
   int ret = verify_globals();
   if (var.a != 1)
     {
       printf("FAIL : Unexpected value. var.b %d should be %d\n", var.a, 1);
       ret = 1;
     }
 }

 main ()
 {
   set_a(1);
   done();
 }

None: Atomic/GCCMM/TestSamp1 (last edited 2010-05-06 15:00:30 by AndrewMacLeod)