aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc
blob: 1d480a1e3b86aaa44a5502c22e047472c03ba074 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include "vtv_utils.h"
#include "vtv_rts.h"
#include "pthread.h"


/* Multi-threaded test for calls to RegisterPair */

/* This configuration will test mostly inserting of elements that are already inserted since 
   the number of repeats is 10 */

/* This test case may fail depending on the system configuration.
   Check the value of  /proc/sys/vm/max_map_count and fix by doing
   Ex: sudo sh -c  "echo 131060 > /proc/sys/vm/max_map_count" */

#define NUM_MAPS 200
#define ELEMENTS_PER_MAP 100
#define NUM_REPEATS 10

#define NUM_THREADS 9

#define KEY_TYPE_FIXED_SIZE 8
void *key_buffer = malloc (17);
typedef char * name_string;
name_string fake_names[NUM_MAPS];

/* This variable has to be put in rel.ro */
void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR;

struct fake_vt {
  void * fake_vfp [4];
};
void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];

volatile int current_map = -1;
volatile int threads_completed_it = 0;

void
generate_names (void)
{
  int i;

  for (i = 0; i < NUM_MAPS; ++i)
    {
      fake_names[i] = (char *) malloc (9 * sizeof (char));
      snprintf (fake_names[i], 9, "name%d", i);
    }
}

static uint32_t
vtv_string_hash(const char *in)
{
  const char *s = in;
  uint32_t h = 0;

  for ( ; *s; ++s)
    h = 5 * h + *s;
  return h;
}

void * do_register_pairs(void *)
{
  for (int k = 0; k < NUM_REPEATS; k++)
    {
      int curr_fake_vt = 0;
      for (int i = 0; i < NUM_MAPS; i++)
	{
	  uint32_t *value_ptr = (uint32_t *) key_buffer;
	  uint32_t len1 = strlen (fake_names[i]);
	  uint32_t hash_value = vtv_string_hash (fake_names[i]);
	  void *temp_array[ELEMENTS_PER_MAP];
	  
	  while (current_map < (k*NUM_MAPS + i))
	    ;
	  
	  __VLTChangePermission(__VLTP_READ_WRITE);
	  
	  *value_ptr = len1;
	  value_ptr++;
	  *value_ptr = hash_value;
	  
	  memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
		  len1);


#ifdef VTV_DEBUG
	  __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128,
				  &fake_vts[curr_fake_vt], "", "");
#else
	  __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128,
			     &fake_vts[curr_fake_vt]);
#endif
	  for (int j = 0; j < ELEMENTS_PER_MAP; j++)
	    {
	      temp_array[j] = &fake_vts[curr_fake_vt];
	      curr_fake_vt++;
	    }

#ifdef VTV_DEBUG
	  __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100,
			       (void **) &temp_array);
#else
	  __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100,
			  (void **) &temp_array);
#endif
	  __VLTChangePermission(__VLTP_READ_ONLY);

	  int old_value;
	  do {
	    old_value = threads_completed_it;
	  } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1));

	  if (old_value == (NUM_THREADS - 1)) // Only one thread will do this.
	    {
	      threads_completed_it = 0;
	      printf("%c%d", 13, current_map + 1);
	      fflush(stdout);
	      current_map++;
	    }
	}
    }

  return NULL;
}


int main()
{
  pthread_t thread_ids[NUM_THREADS];

  generate_names ();
 
  for (int t = 0; t < NUM_THREADS; t++ )
    if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0)
      {
	printf("failed pthread_create\n");
	exit(1);
      }

  current_map = 0; // start the work on the other threads

  for (int t = 0; t < NUM_THREADS; t++)
    if (pthread_join(thread_ids[t], NULL) != 0)
      { 
	printf("failed pthread_join\n");
	exit(2);
      }

  printf("\n");


  
  return 0;
}