test-smob-mark.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* Copyright 2013-2014,2018
  2. Free Software Foundation, Inc.
  3. This file is part of Guile.
  4. Guile is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Lesser General Public License as published
  6. by the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Guile is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with Guile. If not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #if HAVE_CONFIG_H
  16. #include <config.h>
  17. #endif
  18. #undef NDEBUG
  19. #include <assert.h>
  20. #include <libguile.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #define SMOBS_COUNT (10000)
  24. struct x_tag
  25. {
  26. SCM scm_value;
  27. int c_value;
  28. };
  29. typedef struct x_tag x_t;
  30. unsigned int mark_call_count = 0;
  31. static scm_t_bits x_tag;
  32. static SCM make_x (void);
  33. static SCM mark_x (SCM x);
  34. static int print_x (SCM x, SCM port, scm_print_state * pstate);
  35. static size_t free_x (SCM x);
  36. static void init_smob_type (void);
  37. static void test_scm_smob_mark (void);
  38. static SCM
  39. make_x ()
  40. {
  41. static int i = 0;
  42. SCM s_x;
  43. x_t *c_x;
  44. i++;
  45. c_x = (x_t *) scm_gc_malloc (sizeof (x_t), "x");
  46. c_x->scm_value = scm_from_int (i);
  47. c_x->c_value = i;
  48. SCM_NEWSMOB (s_x, x_tag, c_x);
  49. return s_x;
  50. }
  51. static SCM
  52. mark_x (SCM x)
  53. {
  54. x_t *c_x;
  55. c_x = (x_t *) SCM_SMOB_DATA (x);
  56. scm_gc_mark (c_x->scm_value);
  57. mark_call_count++;
  58. return SCM_BOOL_F;
  59. }
  60. static size_t
  61. free_x (SCM x)
  62. {
  63. x_t *c_x;
  64. c_x = (x_t *) SCM_SMOB_DATA (x);
  65. scm_gc_free (c_x, sizeof (x_t), "x");
  66. c_x = NULL;
  67. return 0;
  68. }
  69. static int
  70. print_x (SCM x, SCM port, scm_print_state * pstate SCM_UNUSED)
  71. {
  72. x_t *c_x = (x_t *) SCM_SMOB_DATA (x);
  73. scm_puts ("#<x ", port);
  74. if (c_x == (x_t *) NULL)
  75. scm_puts ("(freed)", port);
  76. else
  77. scm_write (c_x->scm_value, port);
  78. scm_puts (">", port);
  79. return 1;
  80. }
  81. static void
  82. test_scm_smob_mark ()
  83. {
  84. int i;
  85. mark_call_count = 0;
  86. for (i = 0; i < SMOBS_COUNT; i++)
  87. make_x ();
  88. scm_gc ();
  89. if (mark_call_count < SMOBS_COUNT)
  90. {
  91. fprintf (stderr, "FAIL: SMOB mark function called for each SMOB\n");
  92. exit (EXIT_FAILURE);
  93. }
  94. }
  95. static void
  96. init_smob_type ()
  97. {
  98. x_tag = scm_make_smob_type ("x", sizeof (x_t));
  99. scm_set_smob_free (x_tag, free_x);
  100. scm_set_smob_print (x_tag, print_x);
  101. scm_set_smob_mark (x_tag, mark_x);
  102. }
  103. static void
  104. tests (void *data, int argc, char **argv)
  105. {
  106. init_smob_type ();
  107. test_scm_smob_mark ();
  108. }
  109. int
  110. main (int argc, char *argv[])
  111. {
  112. scm_boot_guile (argc, argv, tests, NULL);
  113. return 0;
  114. }