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 : #ifdef ROOTSIM_MPI 67 0 : void msg_allocator_free_at_gvt(struct lp_msg *msg) 68 : { 69 : array_push(free_gvt_list, msg); 70 : } 71 : 72 0 : void msg_allocator_fossil_collect(simtime_t current_gvt) 73 : { 74 : array_count_t j = 0; 75 : for(array_count_t i = 0; i < array_count(free_gvt_list); ++i){ 76 : struct lp_msg *msg = array_get_at(free_gvt_list, i); 77 : // xxx this could need to check the actual sending time instead 78 : // of the destination time in order to avoid a pseudo memory 79 : // leak for LPs which send messages distant in logical time. 80 : if (current_gvt > msg->dest_t) { 81 : msg_allocator_free(msg); 82 : } else { 83 : array_get_at(free_gvt_list, j) = msg; 84 : j++; 85 : } 86 : } 87 : array_count(free_gvt_list) = j; 88 : } 89 : #endif 90 : 91 0 : extern struct lp_msg* msg_allocator_pack(lp_id_t receiver, simtime_t timestamp, 92 : unsigned event_type, const void *payload, unsigned payload_size);