2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/*
2N/A *
2N/A * HEADER: dapl_osd.h
2N/A *
2N/A * PURPOSE: Operating System Dependent layer
2N/A * Description:
2N/A * Provide OS dependent data structures & functions with
2N/A * a canonical DAPL interface. Designed to be portable
2N/A * and hide OS specific quirks of common functions.
2N/A *
2N/A * $Id: dapl_osd.h,v 1.38 2003/08/20 14:08:57 sjs2 Exp $
2N/A */
2N/A
2N/A#ifndef _DAPL_OSD_H_
2N/A#define _DAPL_OSD_H_
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A/*
2N/A * <assert.h> keys off of NDEBUG
2N/A */
2N/A#ifdef DAPL_DBG
2N/A#undef NDEBUG
2N/A#else
2N/A#define NDEBUG
2N/A#endif
2N/A
2N/A#include <dat/udat.h>
2N/A#include <assert.h>
2N/A#include <errno.h>
2N/A#include <pthread.h>
2N/A#include <semaphore.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <stdarg.h>
2N/A#include <time.h>
2N/A#include <syslog.h>
2N/A#include <netdb.h>
2N/A#include <atomic.h>
2N/A#include "dapl_debug.h"
2N/A
2N/A/*
2N/A * networking related headers
2N/A */
2N/A#include <unistd.h>
2N/A#include <fcntl.h>
2N/A#include <sys/types.h>
2N/A#include <sys/socket.h>
2N/A#include <ctype.h>
2N/A#include <arpa/inet.h>
2N/A
2N/A#ifndef _INLINE_
2N/A#define _INLINE_
2N/A#endif /* _INLINE_ */
2N/A
2N/A/*
2N/A * initialization function
2N/A */
2N/Avoid dapl_os_init(void);
2N/A
2N/A#define dapl_os_panic(args) \
2N/A{ \
2N/A fprintf(stderr, "PANIC in %s:%i:\n", __FILE__, __LINE__); \
2N/A fprintf(stderr, args); \
2N/A exit(1); \
2N/A}
2N/A
2N/Aint dapl_os_get_env_bool(
2N/A char *env_str);
2N/A
2N/Aint dapl_os_get_env_val(
2N/A char *env_str,
2N/A int def_val);
2N/A
2N/A/*
2N/A * Atomic operations
2N/A */
2N/Atypedef volatile DAT_COUNT DAPL_ATOMIC;
2N/A
2N/A/*
2N/A * dapl_os_atomic_inc
2N/A *
2N/A * get the current value of '*v', and then increment it.
2N/A *
2N/A * This is equivalent to an IB atomic fetch and add of 1,
2N/A * except that a DAT_COUNT might be 32 bits, rather than 64
2N/A * and it occurs in local memory.
2N/A *
2N/A * DAT_COUNT dapl_os_atomic_inc(INOUT DAPL_ATOMIC *v)
2N/A */
2N/A#define dapl_os_atomic_inc(v) ((DAT_COUNT) \
2N/A (atomic_add_32_nv((uint32_t *)(v), 1) - 1))
2N/A
2N/A/*
2N/A * dapl_os_atomic_dec
2N/A *
2N/A * decrement the current value of '*v'. No return value is required.
2N/A *
2N/A * DAT_COUNT dapl_os_atomic_dec(INOUT DAPL_ATOMIC *v)
2N/A */
2N/A#define dapl_os_atomic_dec(v) assert(*v != 0); \
2N/A ((DAT_COUNT) \
2N/A (atomic_add_32_nv((uint32_t *)(v), -1) + 1))
2N/A
2N/A/*
2N/A * dapl_os_atomic_assign
2N/A *
2N/A * assign 'new_value' to '*v' if the current value
2N/A * matches the provided 'match_value'.
2N/A *
2N/A * Make no assignment if there is no match.
2N/A *
2N/A * Return the current value in any case.
2N/A *
2N/A * This matches the IBTA atomic operation compare & swap
2N/A * except that it is for local memory and a DAT_COUNT may
2N/A * be only 32 bits, rather than 64.
2N/A *
2N/A * DAT_COUNT dapl_os_atomic_assign(INOUT DAPL_ATOMIC *v,
2N/A * IN DAT_COUNT match_value, IN DAT_COUNT new_value)
2N/A */
2N/A#define dapl_os_atomic_assign(v, match_value, new_value) \
2N/A atomic_cas_32((uint32_t *)(v), (uint32_t)(match_value), \
2N/A (uint32_t)(new_value))
2N/A
2N/A/*
2N/A * Thread Functions
2N/A */
2N/Atypedef pthread_t DAPL_OS_THREAD;
2N/A
2N/ADAT_RETURN
2N/Adapl_os_thread_create(
2N/A IN void (*func) (void *),
2N/A IN void *data,
2N/A OUT DAPL_OS_THREAD *thread_id);
2N/A
2N/A
2N/A/*
2N/A * Lock Functions
2N/A */
2N/A
2N/Atypedef pthread_mutex_t DAPL_OS_LOCK;
2N/A
2N/A/*
2N/A * DAT_RETURN dapl_os_lock_init(IN DAPL_OS_LOCK *m)
2N/A */
2N/A#define dapl_os_lock_init(m) (void) \
2N/A ((0 == pthread_mutex_init((m), NULL)) ? \
2N/A DAT_SUCCESS : \
2N/A (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR))
2N/A
2N/A/* DAT_RETURN dapl_os_lock(IN DAPL_OS_LOCK *m) */
2N/A#define dapl_os_lock(m) ((DAT_RETURN)( \
2N/A (0 == pthread_mutex_lock((m))) ? \
2N/A DAT_SUCCESS : \
2N/A (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR)))
2N/A
2N/A/* DAT_RETURN dapl_os_unlock(IN DAPL_OS_LOCK *m) */
2N/A#define dapl_os_unlock(m) ((DAT_RETURN)( \
2N/A (0 == pthread_mutex_unlock((m))) ? \
2N/A DAT_SUCCESS : \
2N/A (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR)))
2N/A
2N/A/* DAT_RETURN dapl_os_lock_destroy(IN DAPL_OS_LOCK *m) */
2N/A#define dapl_os_lock_destroy(m) ((DAT_RETURN)( \
2N/A (0 == pthread_mutex_destroy((m))) ? \
2N/A DAT_SUCCESS : \
2N/A (DAT_CLASS_ERROR | DAT_INTERNAL_ERROR)))
2N/A/*
2N/A * Wait Objects
2N/A */
2N/A
2N/A/*
2N/A * The wait object invariant: Presuming a call to dapl_os_wait_object_wait
2N/A * occurs at some point, there will be at least one wakeup after each call
2N/A * to dapl_os_wait_object_signal. I.e. Signals are not ignored, though
2N/A * they may be coallesced.
2N/A */
2N/A
2N/Atypedef struct
2N/A{
2N/A DAT_BOOLEAN signaled;
2N/A pthread_cond_t cv;
2N/A pthread_mutex_t lock;
2N/A} DAPL_OS_WAIT_OBJECT;
2N/A
2N/A/* function prototypes */
2N/ADAT_RETURN
2N/Adapl_os_wait_object_init(
2N/A IN DAPL_OS_WAIT_OBJECT *wait_obj);
2N/A
2N/ADAT_RETURN
2N/Adapl_os_wait_object_wait(
2N/A IN DAPL_OS_WAIT_OBJECT *wait_obj,
2N/A IN DAT_TIMEOUT timeout_val);
2N/A
2N/ADAT_RETURN
2N/Adapl_os_wait_object_wakeup(
2N/A IN DAPL_OS_WAIT_OBJECT *wait_obj);
2N/A
2N/ADAT_RETURN
2N/Adapl_os_wait_object_destroy(
2N/A IN DAPL_OS_WAIT_OBJECT *wait_obj);
2N/A
2N/A/*
2N/A * Memory Functions
2N/A */
2N/A
2N/A/* void *dapl_os_alloc(int size) */
2N/A#define dapl_os_alloc(size) malloc((size))
2N/A
2N/A/* void *dapl_os_realloc(void *ptr, int size) */
2N/A#define dapl_os_realloc(ptr, size) realloc((ptr), (size))
2N/A
2N/A/* void dapl_os_free(void *ptr, int size) */
2N/A#define dapl_os_free(ptr, size) free((ptr))
2N/A
2N/A/* void * dapl_os_memzero(void *loc, int size) */
2N/A#define dapl_os_memzero(loc, size) memset((loc), 0, (size))
2N/A
2N/A/* void * dapl_os_memcpy(void *dest, const void *src, int len) */
2N/A#define dapl_os_memcpy(dest, src, len) memcpy((dest), (src), (len))
2N/A
2N/A/* int dapl_os_memcmp(const void *mem1, const void *mem2, int len) */
2N/A#define dapl_os_memcmp(mem1, mem2, len) memcmp((mem1), (mem2), (len))
2N/A
2N/A/*
2N/A * String Functions
2N/A */
2N/A
2N/A/* unsigned int dapl_os_strlen(const char *str) */
2N/A#define dapl_os_strlen(str) strlen((str))
2N/A/* char * dapl_os_strdup(const char *str) */
2N/A#define dapl_os_strdup(str) strdup((str))
2N/A/* char *strcpy(char *dest, char *src) */
2N/A#define dapl_os_strcpy(dest, src) strcpy((dest), (src))
2N/A/* char *strncpy(char *s1, const char *s2, size_t n) */
2N/A#define dapl_os_strncpy(dest, src, len) strncpy((dest), (src), (len))
2N/A/* char *strcat(char *dest, char *src) */
2N/A#define dapl_os_strcat(dest, src) strcat((dest), (src))
2N/A
2N/A/*
2N/A * Timer Functions
2N/A */
2N/A
2N/Atypedef DAT_UINT64 DAPL_OS_TIMEVAL;
2N/A
2N/A
2N/Atypedef unsigned long long int DAPL_OS_TICKS;
2N/A
2N/A/* function prototypes */
2N/A
2N/A/*
2N/A * Sleep for the number of micro seconds specified by the invoking
2N/A * function
2N/A *
2N/A * void dapl_os_sleep_usec(int sleep_time)
2N/A */
2N/A#define dapl_os_sleep_usec(sleep_time) { \
2N/A struct timespec sleep_spec; \
2N/A sleep_spec.tv_sec = (sleep_time) / 100000; \
2N/A sleep_spec.tv_nsec = (sleep_time) % 100000 * 1000; \
2N/A nanosleep(&sleep_spec, NULL); \
2N/A }
2N/A
2N/ADAT_RETURN dapl_os_get_time(DAPL_OS_TIMEVAL *);
2N/A
2N/A/*
2N/A *
2N/A * Name Service Helper functions
2N/A *
2N/A */
2N/A#if defined(IBHOSTS_NAMING)
2N/A#define dapls_osd_getaddrinfo(name, addr_ptr) \
2N/A getaddrinfo((name), NULL, NULL, (addr_ptr))
2N/A#define dapls_osd_freeaddrinfo(addr) freeaddrinfo((addr))
2N/A
2N/A#endif /* IBHOSTS_NAMING */
2N/A
2N/A/*
2N/A * *printf format helpers. We use the C string constant concatenation
2N/A * ability to define 64 bit formats, which unfortunatly are non standard
2N/A * in the C compiler world. E.g. %llx for gcc, %I64x for Windows
2N/A */
2N/A#define F64d "%lld"
2N/A#define F64u "%llu"
2N/A#define F64x "%llx"
2N/A#define F64X "%llX"
2N/A
2N/A
2N/A/*
2N/A * Conversion Functions
2N/A */
2N/A
2N/A/* long int dapl_os_strtol(const char *nptr, char **endptr, int base) */
2N/A#define dapl_os_strtol(nptr, endptr, base) strtol((nptr), (endptr), (base))
2N/A
2N/A/*
2N/A * Helper Functions
2N/A */
2N/A
2N/A
2N/A#define dapl_os_assert(expression) assert((expression))
2N/A#define dapl_os_printf printf
2N/A#define dapl_os_vprintf(fmt, args) vprintf((fmt), (args))
2N/A#define dapl_os_syslog(fmt, args) vsyslog(LOG_USER | LOG_DEBUG, \
2N/A (fmt), (args))
2N/A#ifdef __cplusplus
2N/A}
2N/A#endif
2N/A
2N/A#endif /* _DAPL_OSD_H_ */