Line data Source code
1 1 : /** 2 : * @file mm/msg_allocator.c 3 : * 4 : * @brief Memory management functions for messages 5 : * 6 : * Memory management functions for messages 7 : * 8 : * SPDX-FileCopyrightText: 2008-2021 HPDCS Group <rootsim@googlegroups.com> 9 : * SPDX-License-Identifier: GPL-3.0-only 10 : */ 11 : #include <mm/msg_allocator.h> 12 : 13 : #include <core/core.h> 14 : #include <datatypes/array.h> 15 : #include <gvt/gvt.h> 16 : 17 0 : static __thread dyn_array(struct lp_msg *) free_list = {0}; 18 : static __thread dyn_array(struct lp_msg *) free_gvt_list = {0}; 19 : 20 0 : void msg_allocator_init(void) 21 : { 22 : array_init(free_list); 23 : array_init(free_gvt_list); 24 : } 25 : 26 0 : void msg_allocator_fini(void) 27 : { 28 : while (!array_is_empty(free_list)) { 29 : mm_free(array_pop(free_list)); 30 : } 31 : array_fini(free_list); 32 : 33 : while (!array_is_empty(free_gvt_list)) { 34 : mm_free(array_pop(free_gvt_list)); 35 : } 36 : array_fini(free_gvt_list); 37 : } 38 : 39 0 : struct lp_msg* msg_allocator_alloc(unsigned payload_size) 40 : { 41 : struct lp_msg *ret; 42 : if (unlikely(payload_size > BASE_PAYLOAD_SIZE)) { 43 : ret = mm_alloc( 44 : offsetof(struct lp_msg, extra_pl) + 45 : (payload_size - BASE_PAYLOAD_SIZE) 46 : ); 47 : ret->pl_size = payload_size; 48 : return ret; 49 : } 50 : if (unlikely(array_is_empty(free_list))) { 51 : ret = mm_alloc(sizeof(struct lp_msg)); 52 : ret->pl_size = payload_size; 53 : return ret; 54 : } 55 : return array_pop(free_list); 56 : } 57 : 58 0 : void msg_allocator_free(struct lp_msg *msg) 59 : { 60 : if(likely(msg->pl_size <= BASE_PAYLOAD_SIZE)) 61 : array_push(free_list, msg); 62 : else 63 : mm_free(msg); 64 : } 65 : 66 0 : void msg_allocator_free_at_gvt(struct lp_msg *msg) 67 : { 68 : array_push(free_gvt_list, msg); 69 : } 70 : 71 0 : void msg_allocator_fossil_collect(simtime_t current_gvt) 72 : { 73 : array_count_t j = 0; 74 : for (array_count_t i = 0; i < array_count(free_gvt_list); ++i) { 75 : struct lp_msg *msg = array_get_at(free_gvt_list, i); 76 : // xxx this could need to check the actual sending time instead 77 : // of the destination time in order to avoid a pseudo memory 78 : // leak for LPs which send messages distant in logical time. 79 : if (current_gvt > msg->dest_t) { 80 : msg_allocator_free(msg); 81 : } else { 82 : array_get_at(free_gvt_list, j) = msg; 83 : j++; 84 : } 85 : } 86 : array_count(free_gvt_list) = j; 87 : } 88 : 89 0 : extern struct lp_msg* msg_allocator_pack(lp_id_t receiver, simtime_t timestamp, 90 : unsigned event_type, const void *payload, unsigned payload_size);