Branch data Line data Source code
1 : : #include "mem.h"
2 : : #include "mem_internal.h"
3 : :
4 : : /**
5 : : * @brief Free the allocated block and clear the descriptor lengths
6 : : *
7 : : * @param memory_structure Pointer to a descriptor
8 : : *
9 : : * @post For descriptors that pass validation, sets @ref memory::data to `NULL`,
10 : : * @ref memory::length to `0`, @ref memory::actually_allocated_bytes to `0`,
11 : : * and @ref memory::string_length to `0`. The current value of
12 : : * @ref memory::is_string is preserved, and
13 : : * @ref memory::single_element_size remains unchanged so the descriptor can be
14 : : * allocated again for the same element type in the same mode
15 : : *
16 : : * @note Descriptors that advertise non-zero length with a `NULL` data pointer
17 : : * are reported as invalid and left unchanged. In that case the function
18 : : * returns `FAILURE`
19 : : */
20 : 32361 : Return mem_delete(memory *memory_structure)
21 : : {
22 : : /* Status returned by this function through provide()
23 : : Default value assumes successful completion */
24 : 32361 : Return status = SUCCESS;
25 : :
26 [ - + ]: 32361 : if(memory_structure == NULL)
27 : : {
28 : 0 : report("Memory management; Descriptor is NULL");
29 : 0 : status = FAILURE;
30 : : }
31 : :
32 [ + - + + : 32361 : if((TRIUMPH & status) && memory_structure->length > 0 && memory_structure->data == NULL)
+ + ]
33 : : {
34 : 1 : report("Memory management; Descriptor has non-zero length with NULL data pointer");
35 : 1 : status = FAILURE;
36 : : }
37 : :
38 [ + + ]: 32361 : if(TRIUMPH & status)
39 : : {
40 : 32360 : const size_t previously_allocated = memory_structure->actually_allocated_bytes;
41 : 32360 : size_t previous_payload_bytes = 0;
42 : 32360 : size_t previous_block_overhead = 0;
43 : :
44 : 32360 : run(mem_guarded_byte_size(memory_structure,memory_structure->length,&previous_payload_bytes));
45 : :
46 [ + + ]: 32360 : if(previously_allocated > previous_payload_bytes)
47 : : {
48 : : /* Direct subtraction is safe because the if-guard above proves no underflow */
49 : 22257 : previous_block_overhead = previously_allocated - previous_payload_bytes;
50 : : }
51 : :
52 [ + + ]: 32360 : if(memory_structure->data != NULL)
53 : : {
54 : 22259 : free(memory_structure->data);
55 : :
56 [ + - ]: 22259 : if(previously_allocated > 0)
57 : : {
58 : 22259 : telemetry_current_heap_reserved_bytes_released(previously_allocated);
59 : 22259 : telemetry_total_heap_reserved_bytes_released(previously_allocated);
60 : : }
61 : :
62 : 22259 : telemetry_heap_buffer_releases();
63 : 22259 : telemetry_active_descriptors_released();
64 : : }
65 : :
66 [ + + ]: 32360 : if(previous_payload_bytes > 0)
67 : : {
68 : 22251 : telemetry_current_payload_bytes_removed(previous_payload_bytes);
69 : : }
70 : :
71 [ + + ]: 32360 : if(previous_block_overhead > 0)
72 : : {
73 : 22257 : telemetry_current_block_overhead_bytes_removed(previous_block_overhead);
74 : : }
75 : :
76 : 32360 : memory_structure->data = NULL;
77 : 32360 : memory_structure->length = 0;
78 : 32360 : memory_structure->actually_allocated_bytes = 0;
79 : 32360 : memory_structure->string_length = 0;
80 : : }
81 : :
82 : 32361 : provide(status);
83 : : }
|