Research portable Memory game | Исследовать портируемую игру Память
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.6KB

  1. #include <stdio.h>
  2. #include <setjmp.h>
  3. #define HASH_BLOOM 16
  4. #include "uthash.h"
  5. #undef uthash_malloc
  6. #undef uthash_fatal
  7. #define uthash_malloc(sz) alt_malloc(sz)
  8. #define uthash_fatal(s) alt_fatal(s)
  9. typedef struct example_user_t {
  10. int id;
  11. int cookie;
  12. UT_hash_handle hh;
  13. } example_user_t;
  14. static int malloc_cnt = 0;
  15. static int malloc_failed;
  16. static int is_fatal;
  17. static jmp_buf j_buf;
  18. static example_user_t * users;
  19. static int user_id = 0;
  20. static void *alt_malloc(size_t sz)
  21. {
  22. if (--malloc_cnt <= 0) {
  23. malloc_failed = 1;
  24. return 0;
  25. }
  26. malloc_failed = 0;
  27. return malloc(sz);
  28. }
  29. static void alt_fatal(char const * s) {
  30. (void)s;
  31. is_fatal = 1;
  32. longjmp(j_buf, 1);
  33. }
  34. static void init_users(int need_malloc_cnt) {
  35. users = NULL;
  36. example_user_t * user = (example_user_t*)malloc(sizeof(example_user_t));
  37. user->id = user_id;
  38. is_fatal = 0;
  39. malloc_cnt = need_malloc_cnt;
  40. if (!setjmp(j_buf)) {
  41. HASH_ADD_INT(users, id, user);
  42. } else {
  43. free(user);
  44. }
  45. }
  46. int main()
  47. {
  48. example_user_t *user;
  49. init_users(3); /* bloom filter must fail */
  50. if (!is_fatal) {
  51. printf("fatal not called after bloom failure\n");
  52. }
  53. init_users(2); /* bucket creation must fail */
  54. if (!is_fatal) {
  55. printf("fatal not called after bucket creation failure\n");
  56. }
  57. init_users(1); /* table creation must fail */
  58. if (!is_fatal) {
  59. printf("fatal not called after table creation failure\n");
  60. }
  61. init_users(4); /* hash must create OK */
  62. if (is_fatal) {
  63. printf("fatal error when creating hash normally\n");
  64. /* bad idea to continue running */
  65. return 1;
  66. }
  67. /* let's add users until expansion fails */
  68. users = NULL;
  69. malloc_cnt = 4;
  70. while (1) {
  71. if (user_id++ == 1000) {
  72. printf("there is no way 1000 iterations didn't require realloc\n");
  73. break;
  74. }
  75. user = (example_user_t*)malloc(sizeof(example_user_t));
  76. user->id = user_id;
  77. if (!setjmp(j_buf)) {
  78. HASH_ADD_INT(users, id, user);
  79. } else {
  80. free(user);
  81. }
  82. if (malloc_failed) {
  83. if (!is_fatal) {
  84. printf("fatal not called after bucket not extended\n");
  85. }
  86. if (user_id < 10) {
  87. printf("there is no way your bucket size is 10\n");
  88. }
  89. /* we can't really do anything, the hash is not in consistent
  90. * state, so assume this is a success. */
  91. break;
  92. }
  93. malloc_cnt = 0;
  94. }
  95. HASH_CLEAR(hh, users);
  96. printf("End\n");
  97. return 0;
  98. }