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.

142 line
3.9 KiB

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<stdbool.h>
  4. #include<atomic>
  5. #include<vector>
  6. #include<erl_nif.h>
  7. #include "eNifWorkers.h"
  8. #include "blockingconcurrentqueue.h"
  9. static void *UpdateMapFun(void *obj);
  10. static void *FindPathFun(void *obj);
  11. struct NifTraits : public moodycamel::ConcurrentQueueDefaultTraits {
  12. static const size_t BLOCK_SIZE = 16;
  13. static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 16;
  14. static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 8;
  15. static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 8;
  16. static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 16;
  17. static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256;
  18. static inline void *malloc(std::size_t size) { return enif_alloc(size); }
  19. static inline void free(void *ptr) { enif_free(ptr); }
  20. };
  21. typedef struct UpdateMapData_r {
  22. bool IsBarrier;
  23. } UpdateMapData;
  24. typedef struct FindPathData_r {
  25. bool IsBarrier;
  26. } FindPathData;
  27. using LfqUpdateMap = moodycamel::BlockingConcurrentQueue<UpdateMapData, NifTraits> *;
  28. using LfqFindPath = moodycamel::BlockingConcurrentQueue<FindPathData, NifTraits> *;
  29. LfqUpdateMap QUpdateMap;
  30. LfqFindPath QFindPath;
  31. const size_t BulkDelCnt = 200;
  32. typedef struct Node_r {
  33. bool IsBarrier; // 是否障碍
  34. } Node;
  35. int nifLoad(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) {
  36. enif_fprintf(stdout, "IMY*************nifload00000\n");
  37. NIF_ATOMS(NIF_ATOM_INIT)
  38. enif_fprintf(stdout, "IMY*************nifload00001\n");
  39. *priv_data = NULL;
  40. QUpdateMap = new moodycamel::BlockingConcurrentQueue<UpdateMapData, NifTraits>;
  41. QFindPath = new moodycamel::BlockingConcurrentQueue<FindPathData, NifTraits>;
  42. ErlNifTid Tid;
  43. if (0 != enif_thread_create((char *)"ThreadUpdateMap", &Tid, UpdateMapFun, NULL, NULL)) {
  44. return -1;
  45. }
  46. if (0 != enif_thread_create((char *)"FindPathFun", &Tid, FindPathFun, NULL, NULL)) {
  47. return -1;
  48. }
  49. if (0 != enif_thread_create((char *)"FindPathFun", &Tid, FindPathFun, NULL, NULL)) {
  50. return -1;
  51. }
  52. if (0 != enif_thread_create((char *)"FindPathFun", &Tid, FindPathFun, NULL, NULL)) {
  53. return -1;
  54. }
  55. return 0;
  56. }
  57. int nifUpgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info) {
  58. *priv_data = *old_priv_data;
  59. enif_fprintf(stdout, "IMY*************nifUpgrade %p %T\n", old_priv_data, load_info);
  60. return 0;
  61. }
  62. void nifUnload(ErlNifEnv* env, void* priv_data) {
  63. enif_fprintf(stdout, "IMY*************nifUnload0000 \n");
  64. return;
  65. }
  66. ERL_NIF_TERM nifInitMap(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  67. return atom_ok;
  68. }
  69. ERL_NIF_TERM nifUpdateMap(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  70. UpdateMapData InsertData = {true};
  71. if (QUpdateMap->enqueue(InsertData)) {
  72. return atom_true;
  73. } else {
  74. return atom_false;
  75. }
  76. }
  77. ERL_NIF_TERM nifFindPath(ErlNifEnv *env, int, const ERL_NIF_TERM argv[]) {
  78. FindPathData InsertData = {true};
  79. if (QFindPath->enqueue(InsertData)) {
  80. return atom_true;
  81. } else {
  82. return atom_false;
  83. }
  84. }
  85. static ErlNifFunc nifFuns[] = {
  86. {"initMap", 1, nifInitMap},
  87. {"updateMap", 3, nifUpdateMap},
  88. {"findPath", 5, nifFindPath}
  89. };
  90. ERL_NIF_INIT(eNifWorkers, nifFuns, nifLoad, NULL, nifUpgrade, nifUnload)
  91. static void *UpdateMapFun(void *obj) {
  92. return (void *) 0; // 线程处理结束,退出
  93. }
  94. static void *FindPathFun(void *obj) {
  95. FindPathData Data;
  96. ErlNifTid Tid = enif_thread_self();
  97. while (true)
  98. {
  99. QFindPath->wait_dequeue(Data);
  100. enif_fprintf(stdout, "IMY*************listenerResClose5 %T %d\n", Tid, Data.IsBarrier);
  101. }
  102. return (void *) 0; // 线程处理结束,退出
  103. }
  104. void eLfqFree(ErlNifEnv *, void *obj) {
  105. std::vector <FindPathData> DataList(BulkDelCnt);
  106. size_t OutSize;
  107. do{
  108. OutSize = QFindPath->try_dequeue_bulk(DataList.begin(), DataList.size());
  109. }while(OutSize >= BulkDelCnt);
  110. }