erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

264 rader
7.5 KiB

3 år sedan
  1. #include <string.h>
  2. #include "erl_nif.h"
  3. #include "concurrentqueue.h"
  4. struct qData {
  5. ErlNifEnv *env;
  6. ERL_NIF_TERM term;
  7. };
  8. struct lfqIns {
  9. moodycamel::ConcurrentQueue<qData> *LFQ;
  10. moodycamel::ConcurrentQueue<ErlNifEnv *> *G_ENV;
  11. };
  12. ERL_NIF_TERM atomOk;
  13. ERL_NIF_TERM atomError;
  14. ERL_NIF_TERM atomTrue;
  15. ERL_NIF_TERM atomFalse;
  16. ERL_NIF_TERM atomEmpty;
  17. ERL_NIF_TERM make_binary(ErlNifEnv *env, const char *buff, size_t length) {
  18. ERL_NIF_TERM term;
  19. unsigned char *destination_buffer = enif_make_new_binary(env, length, &term);
  20. memcpy(destination_buffer, buff, length);
  21. return term;
  22. }
  23. ERL_NIF_TERM make_error(ErlNifEnv *env, const char *error) {
  24. return enif_make_tuple2(env, atomError, make_binary(env, error, strlen(error)));
  25. }
  26. void eLfqFree(ErlNifEnv *, void *obj) {
  27. lfqIns *ObjIns = static_cast<lfqIns *>(obj);
  28. if (ObjIns != nullptr) {
  29. qData Data;
  30. while (ObjIns->LFQ->try_dequeue(Data)) {
  31. enif_free_env(Data.env);
  32. }
  33. ErlNifEnv *StoreEnv;
  34. while (ObjIns->G_ENV->try_dequeue(StoreEnv)) {
  35. enif_free_env(StoreEnv);
  36. }
  37. delete ObjIns->LFQ;
  38. delete ObjIns->G_ENV;
  39. }
  40. }
  41. int nifLoad(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM) {
  42. ErlNifResourceFlags flags = static_cast<ErlNifResourceFlags>(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
  43. ErlNifResourceType *ResIns;
  44. ResIns = enif_open_resource_type(env, NULL, "eLfqRes", NULL, flags, NULL);
  45. if (NULL == ResIns)
  46. return -1;
  47. *priv_data = ResIns;
  48. atomOk = enif_make_atom(env, "ok");
  49. atomError = enif_make_atom(env, "error");
  50. atomTrue = enif_make_atom(env, "true");
  51. atomFalse = enif_make_atom(env, "false");
  52. atomEmpty = enif_make_atom(env, "empty");
  53. return 0;
  54. }
  55. int nifUpgrade(ErlNifEnv *env, void **priv_data, void **, ERL_NIF_TERM) {
  56. ErlNifResourceFlags flags = static_cast<ErlNifResourceFlags>(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER);
  57. ErlNifResourceType *ResIns;
  58. ResIns = enif_open_resource_type(env, NULL, "eLfqRes", NULL, flags, NULL);
  59. if (NULL == ResIns)
  60. return -1;
  61. *priv_data = ResIns;
  62. return 0;
  63. }
  64. void nifUnload(ErlNifEnv *, void *priv_data) {
  65. return;
  66. }
  67. ERL_NIF_TERM nifNew(ErlNifEnv *env, int, const ERL_NIF_TERM *) {
  68. ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
  69. lfqIns *ObjIns = static_cast<lfqIns *>(enif_alloc_resource(ResIns, sizeof(lfqIns)));
  70. ObjIns->LFQ = new moodycamel::ConcurrentQueue<qData>;
  71. ObjIns->G_ENV = new moodycamel::ConcurrentQueue<ErlNifEnv *>;
  72. if (ObjIns == NULL)
  73. return make_error(env, "enif_alloc_resource failed");
  74. ERL_NIF_TERM term = enif_make_resource(env, ObjIns);
  75. enif_release_resource(ResIns);
  76. return enif_make_tuple2(env, atomOk, term);
  77. }
  78. ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  79. ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
  80. lfqIns *ObjIns = NULL;
  81. if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
  82. return enif_make_badarg(env);
  83. }
  84. qData InTerm;
  85. InTerm.env = enif_alloc_env();
  86. InTerm.term = enif_make_copy(InTerm.env, argv[1]);
  87. if (ObjIns->LFQ->enqueue(InTerm)){
  88. return atomTrue;
  89. } else {
  90. return atomFalse;
  91. }
  92. }
  93. // ERL_NIF_TERM nifIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  94. // ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
  95. //
  96. // lfqIns *ObjIns = NULL;
  97. //
  98. // if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
  99. // return enif_make_badarg(env);
  100. // }
  101. //
  102. // qData InTerm;
  103. // if (ObjIns->G_ENV->try_dequeue(InTerm.env) != true) {
  104. // //enif_fprintf(stdout, "IMY************\n");
  105. // InTerm.env = enif_alloc_env();
  106. // }
  107. //
  108. // InTerm.term = enif_make_copy(InTerm.env, argv[1]);
  109. //
  110. // if (ObjIns->LFQ->enqueue(InTerm)){
  111. // return atomTrue;
  112. // } else {
  113. // return atomFalse;
  114. // }
  115. // }
  116. ERL_NIF_TERM nifIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  117. return atomTrue;
  118. }
  119. ERL_NIF_TERM nifIns2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  120. return atomTrue;
  121. }
  122. ERL_NIF_TERM nifIns3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  123. return atomTrue;
  124. }
  125. ERL_NIF_TERM nifTryIn2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  126. return atomTrue;
  127. }
  128. ERL_NIF_TERM nifTryIn3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  129. return atomTrue;
  130. }
  131. ERL_NIF_TERM nifTryIns2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  132. return atomTrue;
  133. }
  134. ERL_NIF_TERM nifTryIns3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  135. return atomTrue;
  136. }
  137. ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  138. ErlNifResourceType *ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
  139. lfqIns *ObjIns = NULL;
  140. if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
  141. return enif_make_badarg(env);
  142. }
  143. ERL_NIF_TERM OutTerm;
  144. qData Data;
  145. if (ObjIns->LFQ->try_dequeue(Data)) {
  146. OutTerm = enif_make_copy(env, Data.term);
  147. enif_free_env(Data.env);
  148. return OutTerm;
  149. } else {
  150. return atomEmpty;
  151. }
  152. }
  153. // ERL_NIF_TERM nifTryOut1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  154. // ErlNifResourceType* ResIns = static_cast<ErlNifResourceType *>(enif_priv_data(env));
  155. // lfqIns *ObjIns = NULL;
  156. //
  157. // if (!enif_get_resource(env, argv[0], ResIns, (void **) &ObjIns)) {
  158. // return enif_make_badarg(env);
  159. // }
  160. //
  161. // ERL_NIF_TERM OutTerm;
  162. // qData Data;
  163. //
  164. // if (ObjIns->LFQ->try_dequeue(Data)) {
  165. // OutTerm = enif_make_copy(env, Data.term);
  166. //
  167. // if(ObjIns->G_ENV->size_approx() > 1000){
  168. // enif_free_env(Data.env);
  169. // }else{
  170. // enif_clear_env(Data.env);
  171. // if (!ObjIns->G_ENV->enqueue(Data.env)){
  172. // enif_free_env(Data.env);
  173. // }
  174. // }
  175. // return enif_make_tuple2(env, atomOk, OutTerm);
  176. // } else {
  177. // return atomEmpty;
  178. // }
  179. // }
  180. ERL_NIF_TERM nifTryOut2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  181. return atomEmpty;
  182. }
  183. ERL_NIF_TERM nifTryOuts2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  184. return atomEmpty;
  185. }
  186. ERL_NIF_TERM nifTryOuts3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  187. return atomEmpty;
  188. }
  189. ERL_NIF_TERM nifTryOutByProd2(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  190. return atomEmpty;
  191. }
  192. ERL_NIF_TERM nifTryOutByProd3(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  193. return atomEmpty;
  194. }
  195. ERL_NIF_TERM nifSize1(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  196. return atomEmpty;
  197. }
  198. static ErlNifFunc nifFuncs[] =
  199. {
  200. {"new", 0, nifNew},
  201. {"in", 2, nifIn2},
  202. {"in", 3, nifIn3},
  203. {"ins", 2, nifIns2},
  204. {"ins", 3, nifIns3},
  205. {"tryIn", 2, nifTryIn2},
  206. {"tryIn", 3, nifTryIn3},
  207. {"tryIns", 2, nifTryIns2},
  208. {"tryIns", 3, nifTryIns3},
  209. {"tryOut", 1, nifTryOut1},
  210. {"tryOut", 2, nifTryOut2},
  211. {"tryOuts", 2, nifTryOuts2},
  212. {"tryOuts", 3, nifTryOuts3},
  213. {"tryOutByProd", 2, nifTryOutByProd2},
  214. {"tryOutsByProd", 3, nifTryOutByProd3},
  215. {"size", 1, nifSize1}
  216. };
  217. ERL_NIF_INIT(eLfq, nifFuncs, nifLoad, NULL, nifUpgrade, nifUnload
  218. )