threading.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * Copyright (c) 2016 Tino Reichardt
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. *
  9. * You can contact the author at:
  10. * - zstdmt source repository: https://github.com/mcmilk/zstdmt
  11. */
  12. /**
  13. * This file will hold wrapper for systems, which do not support pthreads
  14. */
  15. #include "threading.h"
  16. /* create fake symbol to avoid empty translation unit warning */
  17. int g_ZSTD_threading_useless_symbol;
  18. #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
  19. /**
  20. * Windows minimalist Pthread Wrapper, based on :
  21. * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
  22. */
  23. /* === Dependencies === */
  24. #include <process.h>
  25. #include <errno.h>
  26. /* === Implementation === */
  27. static unsigned __stdcall worker(void *arg)
  28. {
  29. ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
  30. thread->arg = thread->start_routine(thread->arg);
  31. return 0;
  32. }
  33. int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
  34. void* (*start_routine) (void*), void* arg)
  35. {
  36. (void)unused;
  37. thread->arg = arg;
  38. thread->start_routine = start_routine;
  39. thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
  40. if (!thread->handle)
  41. return errno;
  42. else
  43. return 0;
  44. }
  45. int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
  46. {
  47. DWORD result;
  48. if (!thread.handle) return 0;
  49. result = WaitForSingleObject(thread.handle, INFINITE);
  50. switch (result) {
  51. case WAIT_OBJECT_0:
  52. if (value_ptr) *value_ptr = thread.arg;
  53. return 0;
  54. case WAIT_ABANDONED:
  55. return EINVAL;
  56. default:
  57. return GetLastError();
  58. }
  59. }
  60. #endif /* ZSTD_MULTITHREAD */
  61. #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
  62. #include <stdlib.h>
  63. int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
  64. {
  65. *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
  66. if (!*mutex)
  67. return 1;
  68. return pthread_mutex_init(*mutex, attr);
  69. }
  70. int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
  71. {
  72. if (!*mutex)
  73. return 0;
  74. {
  75. int const ret = pthread_mutex_destroy(*mutex);
  76. free(*mutex);
  77. return ret;
  78. }
  79. }
  80. int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
  81. {
  82. *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
  83. if (!*cond)
  84. return 1;
  85. return pthread_cond_init(*cond, attr);
  86. }
  87. int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
  88. {
  89. if (!*cond)
  90. return 0;
  91. {
  92. int const ret = pthread_cond_destroy(*cond);
  93. free(*cond);
  94. return ret;
  95. }
  96. }
  97. #endif