Process pending deferred cross-thread deallocations
| 1084 | |
| 1085 | //! Process pending deferred cross-thread deallocations |
| 1086 | static int |
| 1087 | _memory_deallocate_deferred(heap_t* heap, size_t size_class) { |
| 1088 | //Grab the current list of deferred deallocations |
| 1089 | atomic_thread_fence_acquire(); |
| 1090 | void* p = atomic_load_ptr(&heap->defer_deallocate); |
| 1091 | if (!p) |
| 1092 | return 0; |
| 1093 | if (!atomic_cas_ptr(&heap->defer_deallocate, 0, p)) |
| 1094 | return 0; |
| 1095 | //Keep track if we deallocate in the given size class |
| 1096 | int got_class = 0; |
| 1097 | do { |
| 1098 | void* next = *(void**)p; |
| 1099 | //Get span and check which type of block |
| 1100 | span_t* span = (void*)((uintptr_t)p & SPAN_MASK); |
| 1101 | if (span->size_class < SIZE_CLASS_COUNT) { |
| 1102 | //Small/medium block |
| 1103 | got_class |= (span->size_class == size_class); |
| 1104 | _memory_deallocate_to_heap(heap, span, p); |
| 1105 | } |
| 1106 | else { |
| 1107 | //Large block |
| 1108 | got_class |= ((span->size_class >= size_class) && (span->size_class <= (size_class + 2))); |
| 1109 | _memory_deallocate_large_to_heap(heap, span); |
| 1110 | } |
| 1111 | //Loop until all pending operations in list are processed |
| 1112 | p = next; |
| 1113 | } while (p); |
| 1114 | return got_class; |
| 1115 | } |
| 1116 | |
| 1117 | //! Defer deallocation of the given block to the given heap |
| 1118 | static void |
no test coverage detected