suvm_device.c (4097B)
1 /* Copyright (C) 2020-2023 |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 "suvm.h" 17 #include "suvm_c.h" 18 #include "suvm_device.h" 19 20 #include <rsys/logger.h> 21 #include <rsys/mem_allocator.h> 22 23 /******************************************************************************* 24 * Helper functions 25 ******************************************************************************/ 26 static void 27 log_msg 28 (const struct suvm_device* dev, 29 const enum log_type stream, 30 const char* msg, 31 va_list vargs) 32 { 33 ASSERT(dev && msg); 34 if(dev->verbose) { 35 res_T res; (void)res; 36 res = logger_vprint(dev->logger, stream, msg, vargs); 37 ASSERT(res == RES_OK); 38 } 39 } 40 41 static void 42 device_release(ref_T* ref) 43 { 44 struct suvm_device* dev; 45 ASSERT(ref); 46 dev = CONTAINER_OF(ref, struct suvm_device, ref); 47 if(dev->rtc) rtcReleaseDevice(dev->rtc); 48 MEM_RM(dev->allocator, dev); 49 } 50 51 /******************************************************************************* 52 * Exported functions 53 ******************************************************************************/ 54 res_T 55 suvm_device_create 56 (struct logger* log, 57 struct mem_allocator* mem_allocator, 58 int verbose, 59 struct suvm_device** out_dev) 60 { 61 char embree_opts[512]; 62 struct suvm_device* dev = NULL; 63 struct mem_allocator* allocator = NULL; 64 struct logger* logger = NULL; 65 int sz; 66 res_T res = RES_OK; 67 68 if(!out_dev) { 69 res = RES_BAD_ARG; 70 goto error; 71 } 72 73 allocator = mem_allocator ? mem_allocator : &mem_default_allocator; 74 logger = log ? log : LOGGER_DEFAULT; 75 76 dev = MEM_CALLOC(allocator, 1, sizeof(*dev)); 77 if(!dev) { 78 res = RES_MEM_ERR; 79 goto error; 80 } 81 ref_init(&dev->ref); 82 dev->allocator = allocator; 83 dev->logger = logger; 84 dev->verbose = verbose; 85 86 sz = snprintf(embree_opts, sizeof(embree_opts), "verbose=%d", verbose > 1 ? 1 : 0); 87 if((size_t)sz >= sizeof(embree_opts)) { 88 log_err(dev, "Could not setup the Embree option string.\n"); 89 res = RES_MEM_ERR; 90 goto error; 91 } 92 93 dev->rtc = rtcNewDevice(embree_opts); 94 if(dev->rtc == NULL) { 95 const enum RTCError err = rtcGetDeviceError(NULL); 96 log_err(dev, "Could not create the Embree device -- %s.\n", 97 rtc_error_string(err)); 98 res = rtc_error_to_res_T(err); 99 goto error; 100 } 101 102 exit: 103 if(out_dev) *out_dev = dev; 104 return res; 105 error: 106 if(dev) { 107 SUVM(device_ref_put(dev)); 108 dev = NULL; 109 } 110 goto exit; 111 } 112 113 res_T 114 suvm_device_ref_get(struct suvm_device* dev) 115 { 116 if(!dev) return RES_BAD_ARG; 117 ref_get(&dev->ref); 118 return RES_OK; 119 } 120 121 res_T 122 suvm_device_ref_put(struct suvm_device* dev) 123 { 124 if(!dev) return RES_BAD_ARG; 125 ref_put(&dev->ref, device_release); 126 return RES_OK; 127 } 128 129 /******************************************************************************* 130 * Local functions 131 ******************************************************************************/ 132 void 133 log_info(struct suvm_device* dev, const char* msg, ...) 134 { 135 va_list vargs_list; 136 ASSERT(dev && msg); 137 138 va_start(vargs_list, msg); 139 log_msg(dev, LOG_OUTPUT, msg, vargs_list); 140 va_end(vargs_list); 141 } 142 143 void 144 log_err(struct suvm_device* dev, const char* msg, ...) 145 { 146 va_list vargs_list; 147 ASSERT(dev && msg); 148 149 va_start(vargs_list, msg); 150 log_msg(dev, LOG_ERROR, msg, vargs_list); 151 va_end(vargs_list); 152 } 153 154 void 155 log_warn(struct suvm_device* dev, const char* msg, ...) 156 { 157 va_list vargs_list; 158 ASSERT(dev && msg); 159 160 va_start(vargs_list, msg); 161 log_msg(dev, LOG_WARNING, msg, vargs_list); 162 va_end(vargs_list); 163 } 164