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 : 50071 : Return mem_delete(memory *memory_structure)
21 : : {
22 : : /* Status returned by this function through provide()
23 : : Default value assumes successful completion */
24 : 50071 : Return status = SUCCESS;
25 : :
26 [ - + ]: 50071 : if(memory_structure == NULL)
27 : : {
28 : 0 : report("Memory management; Descriptor is NULL");
29 : 0 : status = FAILURE;
30 : : }
31 : :
32 [ + - + + : 50071 : 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 [ + + ]: 50071 : if(TRIUMPH & status)
39 : : {
40 : 50070 : const size_t previously_allocated = memory_structure->actually_allocated_bytes;
41 : 50070 : size_t previous_payload_bytes = 0;
42 : 50070 : size_t previous_block_overhead = 0;
43 : :
44 : 50070 : run(mem_guarded_byte_size(memory_structure,memory_structure->length,&previous_payload_bytes));
45 : :
46 [ + + ]: 50070 : if(previously_allocated > previous_payload_bytes)
47 : : {
48 : : /* Direct subtraction is safe because the if-guard above proves no underflow */
49 : 29214 : previous_block_overhead = previously_allocated - previous_payload_bytes;
50 : : }
51 : :
52 [ + + ]: 50070 : if(memory_structure->data != NULL)
53 : : {
54 : 29721 : free(memory_structure->data);
55 : :
56 [ + - ]: 29721 : if(previously_allocated > 0)
57 : : {
58 : 29721 : telemetry_current_heap_reserved_bytes_released(previously_allocated);
59 : 29721 : telemetry_total_heap_reserved_bytes_released(previously_allocated);
60 : : }
61 : :
62 : 29721 : telemetry_heap_buffer_releases();
63 : 29721 : telemetry_active_descriptors_released();
64 : : }
65 : :
66 [ + + ]: 50070 : if(previous_payload_bytes > 0)
67 : : {
68 : 29713 : telemetry_current_payload_bytes_removed(previous_payload_bytes);
69 : : }
70 : :
71 [ + + ]: 50070 : if(previous_block_overhead > 0)
72 : : {
73 : 29214 : telemetry_current_block_overhead_bytes_removed(previous_block_overhead);
74 : : }
75 : :
76 : 50070 : memory_structure->data = NULL;
77 : 50070 : memory_structure->length = 0;
78 : 50070 : memory_structure->actually_allocated_bytes = 0;
79 : 50070 : memory_structure->string_length = 0;
80 : : }
81 : :
82 : 50071 : provide(status);
83 : : }
|