register_set_pair_mt.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include "vtv_utils.h"
  6. #include "vtv_rts.h"
  7. #include "pthread.h"
  8. /* Multi-threaded test for calls to RegisterPair */
  9. /* This configuration will test mostly inserting of elements that are already inserted since
  10. the number of repeats is 10 */
  11. /* This test case may fail depending on the system configuration.
  12. Check the value of /proc/sys/vm/max_map_count and fix by doing
  13. Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */
  14. #define NUM_MAPS 200
  15. #define ELEMENTS_PER_MAP 100
  16. #define NUM_REPEATS 10
  17. #define NUM_THREADS 9
  18. #define KEY_TYPE_FIXED_SIZE 8
  19. void *key_buffer = malloc (17);
  20. typedef char * name_string;
  21. name_string fake_names[NUM_MAPS];
  22. /* This variable has to be put in rel.ro */
  23. void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR;
  24. struct fake_vt {
  25. void * fake_vfp [4];
  26. };
  27. void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];
  28. volatile int current_map = -1;
  29. volatile int threads_completed_it = 0;
  30. void
  31. generate_names (void)
  32. {
  33. int i;
  34. for (i = 0; i < NUM_MAPS; ++i)
  35. {
  36. fake_names[i] = (char *) malloc (9 * sizeof (char));
  37. snprintf (fake_names[i], 9, "name%d", i);
  38. }
  39. }
  40. static uint32_t
  41. vtv_string_hash(const char *in)
  42. {
  43. const char *s = in;
  44. uint32_t h = 0;
  45. for ( ; *s; ++s)
  46. h = 5 * h + *s;
  47. return h;
  48. }
  49. void * do_register_pairs(void *)
  50. {
  51. for (int k = 0; k < NUM_REPEATS; k++)
  52. {
  53. int curr_fake_vt = 0;
  54. for (int i = 0; i < NUM_MAPS; i++)
  55. {
  56. uint32_t *value_ptr = (uint32_t *) key_buffer;
  57. uint32_t len1 = strlen (fake_names[i]);
  58. uint32_t hash_value = vtv_string_hash (fake_names[i]);
  59. void *temp_array[ELEMENTS_PER_MAP];
  60. while (current_map < (k*NUM_MAPS + i))
  61. ;
  62. __VLTChangePermission(__VLTP_READ_WRITE);
  63. *value_ptr = len1;
  64. value_ptr++;
  65. *value_ptr = hash_value;
  66. memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
  67. len1);
  68. #ifdef VTV_DEBUG
  69. __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128,
  70. &fake_vts[curr_fake_vt], "", "");
  71. #else
  72. __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128,
  73. &fake_vts[curr_fake_vt]);
  74. #endif
  75. for (int j = 0; j < ELEMENTS_PER_MAP; j++)
  76. {
  77. temp_array[j] = &fake_vts[curr_fake_vt];
  78. curr_fake_vt++;
  79. }
  80. #ifdef VTV_DEBUG
  81. __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100,
  82. (void **) &temp_array);
  83. #else
  84. __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100,
  85. (void **) &temp_array);
  86. #endif
  87. __VLTChangePermission(__VLTP_READ_ONLY);
  88. int old_value;
  89. do {
  90. old_value = threads_completed_it;
  91. } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1));
  92. if (old_value == (NUM_THREADS - 1)) // Only one thread will do this.
  93. {
  94. threads_completed_it = 0;
  95. printf("%c%d", 13, current_map + 1);
  96. fflush(stdout);
  97. current_map++;
  98. }
  99. }
  100. }
  101. return NULL;
  102. }
  103. int main()
  104. {
  105. pthread_t thread_ids[NUM_THREADS];
  106. generate_names ();
  107. for (int t = 0; t < NUM_THREADS; t++ )
  108. if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0)
  109. {
  110. printf("failed pthread_create\n");
  111. exit(1);
  112. }
  113. current_map = 0; // start the work on the other threads
  114. for (int t = 0; t < NUM_THREADS; t++)
  115. if (pthread_join(thread_ids[t], NULL) != 0)
  116. {
  117. printf("failed pthread_join\n");
  118. exit(2);
  119. }
  120. printf("\n");
  121. return 0;
  122. }