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.

141 lines
2.8 KiB

  1. // This file is part of Jiffy released under the MIT license.
  2. // See the LICENSE file for more information.
  3. #include "jiffy.h"
  4. #include <stdio.h>
  5. ERL_NIF_TERM
  6. make_atom(ErlNifEnv* env, const char* name)
  7. {
  8. ERL_NIF_TERM ret;
  9. if(enif_make_existing_atom(env, name, &ret, ERL_NIF_LATIN1)) {
  10. return ret;
  11. }
  12. return enif_make_atom(env, name);
  13. }
  14. ERL_NIF_TERM
  15. make_ok(jiffy_st* st, ErlNifEnv* env, ERL_NIF_TERM value)
  16. {
  17. return enif_make_tuple2(env, st->atom_ok, value);
  18. }
  19. ERL_NIF_TERM
  20. make_error(jiffy_st* st, ErlNifEnv* env, const char* error)
  21. {
  22. return enif_make_tuple2(env, st->atom_error, make_atom(env, error));
  23. }
  24. ERL_NIF_TERM
  25. make_obj_error(jiffy_st* st, ErlNifEnv* env,
  26. const char* error, ERL_NIF_TERM obj)
  27. {
  28. ERL_NIF_TERM reason = enif_make_tuple2(env, make_atom(env, error), obj);
  29. return enif_make_tuple2(env, st->atom_error, reason);
  30. }
  31. int
  32. get_bytes_per_iter(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi)
  33. {
  34. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  35. const ERL_NIF_TERM* tuple;
  36. int arity;
  37. unsigned int bytes;
  38. if(!enif_get_tuple(env, val, &arity, &tuple)) {
  39. return 0;
  40. }
  41. if(arity != 2) {
  42. return 0;
  43. }
  44. if(enif_compare(tuple[0], st->atom_bytes_per_iter) != 0) {
  45. return 0;
  46. }
  47. if(!enif_get_uint(env, tuple[1], &bytes)) {
  48. return 0;
  49. }
  50. // Calculate the number of bytes per reduction
  51. *bpi = (size_t) (bytes / DEFAULT_ERLANG_REDUCTION_COUNT);
  52. return 1;
  53. }
  54. int
  55. get_bytes_per_red(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi)
  56. {
  57. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  58. const ERL_NIF_TERM* tuple;
  59. int arity;
  60. unsigned int bytes;
  61. if(!enif_get_tuple(env, val, &arity, &tuple)) {
  62. return 0;
  63. }
  64. if(arity != 2) {
  65. return 0;
  66. }
  67. if(enif_compare(tuple[0], st->atom_bytes_per_iter) != 0) {
  68. return 0;
  69. }
  70. if(!enif_get_uint(env, tuple[1], &bytes)) {
  71. return 0;
  72. }
  73. *bpi = (size_t) bytes;
  74. return 1;
  75. }
  76. int
  77. get_null_term(ErlNifEnv* env, ERL_NIF_TERM val, ERL_NIF_TERM *null_term)
  78. {
  79. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  80. const ERL_NIF_TERM* tuple;
  81. int arity;
  82. if(!enif_get_tuple(env, val, &arity, &tuple)) {
  83. return 0;
  84. }
  85. if(arity != 2) {
  86. return 0;
  87. }
  88. if(enif_compare(tuple[0], st->atom_null_term) != 0) {
  89. return 0;
  90. }
  91. if(!enif_is_atom(env, tuple[1])) {
  92. return 0;
  93. }
  94. *null_term = tuple[1];
  95. return 1;
  96. }
  97. int
  98. should_yield(ErlNifEnv* env, size_t* used, size_t bytes_per_red)
  99. {
  100. #if(ERL_NIF_MAJOR_VERSION >= 2 && ERL_NIF_MINOR_VERSION >= 4)
  101. if(((*used) / bytes_per_red) >= 20) {
  102. *used = 0;
  103. return enif_consume_timeslice(env, 1);
  104. }
  105. return 0;
  106. #else
  107. return ((*used) / bytes_per_red) >= DEFAULT_ERLANG_REDUCTION_COUNT;
  108. #endif
  109. }