tid_allocator.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "tid_allocator.h"
  6. #include "wasm_export.h"
  7. #include "bh_log.h"
  8. bh_static_assert(TID_MIN <= TID_MAX);
  9. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  10. bool
  11. tid_allocator_init(TidAllocator *tid_allocator)
  12. {
  13. tid_allocator->size = MIN(TID_ALLOCATOR_INIT_SIZE, TID_MAX - TID_MIN + 1);
  14. tid_allocator->pos = tid_allocator->size;
  15. tid_allocator->ids =
  16. wasm_runtime_malloc(tid_allocator->size * sizeof(int32));
  17. if (tid_allocator->ids == NULL)
  18. return false;
  19. for (int64 i = tid_allocator->pos - 1; i >= 0; i--)
  20. tid_allocator->ids[i] =
  21. (uint32)(TID_MIN + (tid_allocator->pos - 1 - i));
  22. return true;
  23. }
  24. void
  25. tid_allocator_deinit(TidAllocator *tid_allocator)
  26. {
  27. wasm_runtime_free(tid_allocator->ids);
  28. }
  29. int32
  30. tid_allocator_get_tid(TidAllocator *tid_allocator)
  31. {
  32. if (tid_allocator->pos == 0) { // Resize stack and push new thread ids
  33. if (tid_allocator->size == TID_MAX - TID_MIN + 1) {
  34. LOG_ERROR("Maximum thread identifier reached");
  35. return -1;
  36. }
  37. uint32 old_size = tid_allocator->size;
  38. uint32 new_size = MIN(tid_allocator->size * 2, TID_MAX - TID_MIN + 1);
  39. if (new_size != TID_MAX - TID_MIN + 1
  40. && new_size / 2 != tid_allocator->size) {
  41. LOG_ERROR("Overflow detected during new size calculation");
  42. return -1;
  43. }
  44. size_t realloc_size = new_size * sizeof(int32);
  45. if (realloc_size / sizeof(int32) != new_size) {
  46. LOG_ERROR("Overflow detected during realloc");
  47. return -1;
  48. }
  49. int32 *tmp =
  50. wasm_runtime_realloc(tid_allocator->ids, (uint32)realloc_size);
  51. if (tmp == NULL) {
  52. LOG_ERROR("Thread ID allocator realloc failed");
  53. return -1;
  54. }
  55. tid_allocator->size = new_size;
  56. tid_allocator->pos = new_size - old_size;
  57. tid_allocator->ids = tmp;
  58. for (int64 i = tid_allocator->pos - 1; i >= 0; i--)
  59. tid_allocator->ids[i] =
  60. (uint32)(TID_MIN + (tid_allocator->size - 1 - i));
  61. }
  62. // Pop available thread identifier from the stack
  63. return tid_allocator->ids[--tid_allocator->pos];
  64. }
  65. void
  66. tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id)
  67. {
  68. // Release thread identifier by pushing it into the stack
  69. bh_assert(tid_allocator->pos < tid_allocator->size);
  70. tid_allocator->ids[tid_allocator->pos++] = thread_id;
  71. }