senc2d_device.c (3949B)
1 /* Copyright (C) 2018-2021, 2023, 2024 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "senc2d.h" 17 #include "senc2d_device_c.h" 18 19 #include <rsys/logger.h> 20 #include <rsys/mem_allocator.h> 21 22 #include <omp.h> 23 24 /****************************************************************************** 25 * Helper functions 26 *****************************************************************************/ 27 static void 28 log_msg 29 (struct senc2d_device* dev, 30 const enum log_type stream, 31 const char* msg, 32 va_list vargs) 33 { 34 ASSERT(dev && msg); 35 if(dev->verbose) { 36 res_T res; (void)res; 37 res = logger_vprint(dev->logger, stream, msg, vargs); 38 ASSERT(res == RES_OK); 39 } 40 } 41 42 static void 43 device_release(ref_T* ref) 44 { 45 struct senc2d_device* dev; 46 ASSERT(ref); 47 dev = CONTAINER_OF(ref, struct senc2d_device, ref); 48 MEM_RM(dev->allocator, dev); 49 } 50 51 /****************************************************************************** 52 * Local functions 53 *****************************************************************************/ 54 void 55 log_err(struct senc2d_device* dev, const char* msg, ...) 56 { 57 va_list vargs_list; 58 ASSERT(dev && msg); 59 60 va_start(vargs_list, msg); 61 log_msg(dev, LOG_ERROR, msg, vargs_list); 62 va_end(vargs_list); 63 } 64 65 void 66 log_warn(struct senc2d_device* dev, const char* msg, ...) 67 { 68 va_list vargs_list; 69 ASSERT(dev && msg); 70 71 va_start(vargs_list, msg); 72 log_msg(dev, LOG_WARNING, msg, vargs_list); 73 va_end(vargs_list); 74 } 75 76 void 77 log_info(struct senc2d_device* dev, const char* msg, ...) 78 { 79 va_list vargs_list; 80 ASSERT(dev && msg); 81 82 va_start(vargs_list, msg); 83 log_msg(dev, LOG_OUTPUT, msg, vargs_list); 84 va_end(vargs_list); 85 } 86 87 /****************************************************************************** 88 * Exported functions 89 *****************************************************************************/ 90 res_T 91 senc2d_device_create 92 (struct logger* logger, 93 struct mem_allocator* mem_allocator, 94 const unsigned nthreads_hint, 95 const int verbose, 96 struct senc2d_device** out_dev) 97 { 98 struct logger* log = NULL; 99 struct senc2d_device* dev = NULL; 100 struct mem_allocator* allocator = NULL; 101 res_T res = RES_OK; 102 if(nthreads_hint == 0 || !out_dev) return RES_BAD_ARG; 103 104 log = logger ? logger : LOGGER_DEFAULT; 105 allocator = mem_allocator ? mem_allocator : &mem_default_allocator; 106 dev = MEM_CALLOC(allocator, 1, sizeof(struct senc2d_device)); 107 if(!dev) { 108 if(verbose) { 109 /* Do not use helper log functions since dev is not initialised */ 110 CHK(logger_print(log, LOG_ERROR, 111 "%s: could not allocate the star-enclosures-2d device.\n", FUNC_NAME) == RES_OK); 112 } 113 res = RES_MEM_ERR; 114 goto error; 115 } 116 dev->logger = log; 117 dev->allocator = allocator; 118 dev->verbose = verbose; 119 /* Cannot use int args for MMIN here as default is -1 */ 120 dev->nthreads = (int)MMIN(nthreads_hint, (unsigned)omp_get_num_procs()); 121 ref_init(&dev->ref); 122 123 exit: 124 if(dev) *out_dev = dev; 125 return res; 126 error: 127 if(dev) { 128 SENC2D(device_ref_put(dev)); 129 dev = NULL; 130 } 131 goto exit; 132 } 133 134 res_T 135 senc2d_device_ref_get(struct senc2d_device* dev) 136 { 137 if(!dev) return RES_BAD_ARG; 138 ref_get(&dev->ref); 139 return RES_OK; 140 } 141 142 res_T 143 senc2d_device_ref_put(struct senc2d_device* dev) 144 { 145 if(!dev) return RES_BAD_ARG; 146 ref_put(&dev->ref, device_release); 147 return RES_OK; 148 }