mt_testing.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #ifndef OPEN62541_MT_TESTING_H
  2. #define OPEN62541_MT_TESTING_H
  3. #include <open62541/server_config_default.h>
  4. typedef struct {
  5. void (*func)(void *param); //function to execute
  6. size_t counter; //index of the iteration
  7. size_t index; // index within workerContext array of global TestContext
  8. size_t upperBound; //number of iterations each thread schould execute func
  9. THREAD_HANDLE handle;
  10. } ThreadContext;
  11. typedef struct {
  12. size_t numberOfWorkers;
  13. ThreadContext *workerContext;
  14. size_t numberofClients;
  15. ThreadContext *clientContext;
  16. UA_Boolean running;
  17. UA_Server *server;
  18. UA_Client **clients;
  19. void (*checkServerNodes)(void);
  20. } TestContext;
  21. TestContext tc;
  22. THREAD_HANDLE server_thread;
  23. THREAD_CALLBACK(serverloop) {
  24. while(tc.running)
  25. UA_Server_run_iterate(tc.server, true);
  26. return 0;
  27. }
  28. static
  29. void teardown(void) {
  30. for (size_t i = 0; i < tc.numberOfWorkers; i++)
  31. THREAD_JOIN(tc.workerContext[i].handle);
  32. for (size_t i = 0; i < tc.numberofClients; i++)
  33. THREAD_JOIN(tc.clientContext[i].handle);
  34. tc.running = false;
  35. THREAD_JOIN(server_thread);
  36. if (tc.checkServerNodes)
  37. tc.checkServerNodes();
  38. UA_Server_run_shutdown(tc.server);
  39. UA_Server_delete(tc.server);
  40. }
  41. THREAD_CALLBACK_PARAM(workerLoop, val) {
  42. ThreadContext tmp = (*(ThreadContext *) val);
  43. for (size_t i = 0; i < tmp.upperBound; i++) {
  44. tmp.counter = i;
  45. tmp.func(&tmp);
  46. }
  47. return 0;
  48. }
  49. THREAD_CALLBACK_PARAM(clientLoop, val) {
  50. ThreadContext tmp = (*(ThreadContext *) val);
  51. tc.clients[tmp.index] = UA_Client_new();
  52. UA_ClientConfig_setDefault(UA_Client_getConfig(tc.clients[tmp.index]));
  53. UA_StatusCode retval = UA_Client_connect(tc.clients[tmp.index], "opc.tcp://localhost:4840");
  54. ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
  55. for(size_t i = 0; i < tmp.upperBound; i++) {
  56. tmp.counter = i;
  57. tmp.func(&tmp);
  58. }
  59. UA_Client_disconnect(tc.clients[tmp.index]);
  60. UA_Client_delete(tc.clients[tmp.index]);
  61. return 0;
  62. }
  63. static UA_INLINE void
  64. initThreadContext(size_t numberOfWorkers, size_t numberOfClients, void (*checkServerNodes)(void)) {
  65. tc.numberOfWorkers = numberOfWorkers;
  66. tc.numberofClients = numberOfClients;
  67. tc.checkServerNodes = checkServerNodes;
  68. tc.workerContext = (ThreadContext*) UA_calloc(tc.numberOfWorkers, sizeof(ThreadContext));
  69. tc.clients = (UA_Client**) UA_calloc(tc.numberofClients, sizeof(UA_Client*));
  70. tc.clientContext = (ThreadContext*) UA_calloc(tc.numberofClients, sizeof(ThreadContext));
  71. }
  72. static UA_INLINE void
  73. setThreadContext(ThreadContext *workerContext, size_t index, size_t upperBound, void (*func)(void *param)) {
  74. workerContext->index = index;
  75. workerContext->upperBound = upperBound;
  76. workerContext->func = func;
  77. }
  78. static UA_INLINE void
  79. startMultithreading(void) {
  80. for (size_t i = 0; i < tc.numberOfWorkers; i++)
  81. THREAD_CREATE_PARAM(tc.workerContext[i].handle, workerLoop, tc.workerContext[i]);
  82. for (size_t i = 0; i < tc.numberofClients; i++)
  83. THREAD_CREATE_PARAM(tc.clientContext[i].handle, clientLoop, tc.clientContext[i]);
  84. }
  85. #endif //OPEN62541_MT_TESTING_H