1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * HEADER: dapl_osd.h 34 * 35 * PURPOSE: Operating System Dependent layer 36 * Description: 37 * Provide OS dependent data structures & functions with 38 * a canonical DAPL interface. Designed to be portable 39 * and hide OS specific quirks of common functions. 40 * 41 * $Id: dapl_osd.h,v 1.38 2003/08/20 14:08:57 sjs2 Exp $ 42 */ 43 44 #ifndef _DAPL_OSD_H_ 45 #define _DAPL_OSD_H_ 46 47 #ifdef __cplusplus 48 extern "C" { 49 #endif 50 51 /* 52 * <assert.h> keys off of NDEBUG 53 */ 54 #ifdef DAPL_DBG 55 #undef NDEBUG 56 #else 57 #define NDEBUG 58 #endif 59 60 #include <dat/udat.h> 61 #include <assert.h> 62 #include <errno.h> 63 #include <pthread.h> 64 #include <semaphore.h> 65 #include <stdio.h> 66 #include <stdlib.h> 67 #include <string.h> 68 #include <stdarg.h> 69 #include <time.h> 70 #include <syslog.h> 71 #include <netdb.h> 72 #include <atomic.h> 73 #include "dapl_debug.h" 74 75 /* 76 * networking related headers 77 */ 78 #include <unistd.h> 79 #include <fcntl.h> 80 #include <sys/types.h> 81 #include <sys/socket.h> 82 #include <ctype.h> 83 #include <arpa/inet.h> 84 85 #ifndef _INLINE_ 86 #define _INLINE_ 87 #endif /* _INLINE_ */ 88 89 /* 90 * initialization function 91 */ 92 void dapl_os_init(void); 93 94 #define dapl_os_panic(args) \ 95 { \ 96 fprintf(stderr, "PANIC in %s:%i:\n", __FILE__, __LINE__); \ 97 fprintf(stderr, args); \ 98 exit(1); \ 99 } 100 101 int dapl_os_get_env_bool( 102 char *env_str); 103 104 int dapl_os_get_env_val( 105 char *env_str, 106 int def_val); 107 108 /* 109 * Atomic operations 110 */ 111 typedef volatile DAT_COUNT DAPL_ATOMIC; 112 113 /* 114 * dapl_os_atomic_inc 115 * 116 * get the current value of '*v', and then increment it. 117 * 118 * This is equivalent to an IB atomic fetch and add of 1, 119 * except that a DAT_COUNT might be 32 bits, rather than 64 120 * and it occurs in local memory. 121 * 122 * DAT_COUNT dapl_os_atomic_inc(INOUT DAPL_ATOMIC *v) 123 */ 124 #define dapl_os_atomic_inc(v) ((DAT_COUNT) \ 125 (atomic_add_32_nv((uint32_t *)(v), 1) - 1)) 126 127 /* 128 * dapl_os_atomic_dec 129 * 130 * decrement the current value of '*v'. No return value is required. 131 * 132 * DAT_COUNT dapl_os_atomic_dec(INOUT DAPL_ATOMIC *v) 133 */ 134 #define dapl_os_atomic_dec(v) assert(*v != 0); \ 135 ((DAT_COUNT) \ 136 (atomic_add_32_nv((uint32_t *)(v), -1) + 1)) 137 138 /* 139 * dapl_os_atomic_assign 140 * 141 * assign 'new_value' to '*v' if the current value 142 * matches the provided 'match_value'. 143 * 144 * Make no assignment if there is no match. 145 * 146 * Return the current value in any case. 147 * 148 * This matches the IBTA atomic operation compare & swap 149 * except that it is for local memory and a DAT_COUNT may 150 * be only 32 bits, rather than 64. 151 * 152 * DAT_COUNT dapl_os_atomic_assign(INOUT DAPL_ATOMIC *v, 153 * IN DAT_COUNT match_value, IN DAT_COUNT new_value) 154 */ 155 #define dapl_os_atomic_assign(v, match_value, new_value) \ 156 atomic_cas_32((uint32_t *)(v), (uint32_t)(match_value), \ 157 (uint32_t)(new_value)) 158 159 /* 160 * Thread Functions 161 */ 162 typedef pthread_t DAPL_OS_THREAD; 163 164 DAT_RETURN 165 dapl_os_thread_create( 166 IN void (*func) (void *), 167 IN void *data, 168 OUT DAPL_OS_THREAD *thread_id); 169 170 171 /* 172 * Lock Functions 173 */ 174 175 typedef pthread_mutex_t DAPL_OS_LOCK; 176 177 /* 178 * DAT_RETURN dapl_os_lock_init(IN DAPL_OS_LOCK *m) 179 */ 180 #define dapl_os_lock_init(m) (void) \ 181 ((0 == pthread_mutex_init((m), NULL)) ? \ 182 DAT_SUCCESS : \ 183 (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR)) 184 185 /* DAT_RETURN dapl_os_lock(IN DAPL_OS_LOCK *m) */ 186 #define dapl_os_lock(m) ((DAT_RETURN)( \ 187 (0 == pthread_mutex_lock((m))) ? \ 188 DAT_SUCCESS : \ 189 (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR))) 190 191 /* DAT_RETURN dapl_os_unlock(IN DAPL_OS_LOCK *m) */ 192 #define dapl_os_unlock(m) ((DAT_RETURN)( \ 193 (0 == pthread_mutex_unlock((m))) ? \ 194 DAT_SUCCESS : \ 195 (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR))) 196 197 /* DAT_RETURN dapl_os_lock_destroy(IN DAPL_OS_LOCK *m) */ 198 #define dapl_os_lock_destroy(m) ((DAT_RETURN)( \ 199 (0 == pthread_mutex_destroy((m))) ? \ 200 DAT_SUCCESS : \ 201 (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR))) 202 /* 203 * Wait Objects 204 */ 205 206 /* 207 * The wait object invariant: Presuming a call to dapl_os_wait_object_wait 208 * occurs at some point, there will be at least one wakeup after each call 209 * to dapl_os_wait_object_signal. I.e. Signals are not ignored, though 210 * they may be coallesced. 211 */ 212 213 typedef struct 214 { 215 DAT_BOOLEAN signaled; 216 pthread_cond_t cv; 217 pthread_mutex_t lock; 218 } DAPL_OS_WAIT_OBJECT; 219 220 /* function prototypes */ 221 DAT_RETURN 222 dapl_os_wait_object_init( 223 IN DAPL_OS_WAIT_OBJECT *wait_obj); 224 225 DAT_RETURN 226 dapl_os_wait_object_wait( 227 IN DAPL_OS_WAIT_OBJECT *wait_obj, 228 IN DAT_TIMEOUT timeout_val); 229 230 DAT_RETURN 231 dapl_os_wait_object_wakeup( 232 IN DAPL_OS_WAIT_OBJECT *wait_obj); 233 234 DAT_RETURN 235 dapl_os_wait_object_destroy( 236 IN DAPL_OS_WAIT_OBJECT *wait_obj); 237 238 /* 239 * Memory Functions 240 */ 241 242 /* void *dapl_os_alloc(int size) */ 243 #define dapl_os_alloc(size) malloc((size)) 244 245 /* void *dapl_os_realloc(void *ptr, int size) */ 246 #define dapl_os_realloc(ptr, size) realloc((ptr), (size)) 247 248 /* void dapl_os_free(void *ptr, int size) */ 249 #define dapl_os_free(ptr, size) free((ptr)) 250 251 /* void * dapl_os_memzero(void *loc, int size) */ 252 #define dapl_os_memzero(loc, size) memset((loc), 0, (size)) 253 254 /* void * dapl_os_memcpy(void *dest, const void *src, int len) */ 255 #define dapl_os_memcpy(dest, src, len) memcpy((dest), (src), (len)) 256 257 /* int dapl_os_memcmp(const void *mem1, const void *mem2, int len) */ 258 #define dapl_os_memcmp(mem1, mem2, len) memcmp((mem1), (mem2), (len)) 259 260 /* 261 * String Functions 262 */ 263 264 /* unsigned int dapl_os_strlen(const char *str) */ 265 #define dapl_os_strlen(str) strlen((str)) 266 /* char * dapl_os_strdup(const char *str) */ 267 #define dapl_os_strdup(str) strdup((str)) 268 /* char *strcpy(char *dest, char *src) */ 269 #define dapl_os_strcpy(dest, src) strcpy((dest), (src)) 270 /* char *strncpy(char *s1, const char *s2, size_t n) */ 271 #define dapl_os_strncpy(dest, src, len) strncpy((dest), (src), (len)) 272 /* char *strcat(char *dest, char *src) */ 273 #define dapl_os_strcat(dest, src) strcat((dest), (src)) 274 275 /* 276 * Timer Functions 277 */ 278 279 typedef DAT_UINT64 DAPL_OS_TIMEVAL; 280 281 282 typedef unsigned long long int DAPL_OS_TICKS; 283 284 /* function prototypes */ 285 286 /* 287 * Sleep for the number of micro seconds specified by the invoking 288 * function 289 * 290 * void dapl_os_sleep_usec(int sleep_time) 291 */ 292 #define dapl_os_sleep_usec(sleep_time) { \ 293 struct timespec sleep_spec; \ 294 sleep_spec.tv_sec = (sleep_time) / 100000; \ 295 sleep_spec.tv_nsec = (sleep_time) % 100000 * 1000; \ 296 nanosleep(&sleep_spec, NULL); \ 297 } 298 299 DAT_RETURN dapl_os_get_time(DAPL_OS_TIMEVAL *); 300 301 /* 302 * 303 * Name Service Helper functions 304 * 305 */ 306 #if defined(IBHOSTS_NAMING) 307 #define dapls_osd_getaddrinfo(name, addr_ptr) \ 308 getaddrinfo((name), NULL, NULL, (addr_ptr)) 309 #define dapls_osd_freeaddrinfo(addr) freeaddrinfo((addr)) 310 311 #endif /* IBHOSTS_NAMING */ 312 313 /* 314 * *printf format helpers. We use the C string constant concatenation 315 * ability to define 64 bit formats, which unfortunatly are non standard 316 * in the C compiler world. E.g. %llx for gcc, %I64x for Windows 317 */ 318 #define F64d "%lld" 319 #define F64u "%llu" 320 #define F64x "%llx" 321 #define F64X "%llX" 322 323 324 /* 325 * Conversion Functions 326 */ 327 328 /* long int dapl_os_strtol(const char *nptr, char **endptr, int base) */ 329 #define dapl_os_strtol(nptr, endptr, base) strtol((nptr), (endptr), (base)) 330 331 /* 332 * Helper Functions 333 */ 334 335 336 #define dapl_os_assert(expression) assert((expression)) 337 #define dapl_os_printf printf 338 #define dapl_os_vprintf(fmt, args) vprintf((fmt), (args)) 339 #define dapl_os_syslog(fmt, args) vsyslog(LOG_USER | LOG_DEBUG, \ 340 (fmt), (args)) 341 #ifdef __cplusplus 342 } 343 #endif 344 345 #endif /* _DAPL_OSD_H_ */ 346