115813Sse/* 215813Sse * Copyright (c) 2010 Kungliga Tekniska H��gskolan 315813Sse * (Royal Institute of Technology, Stockholm, Sweden). 415813Sse * All rights reserved. 515813Sse * 615813Sse * Portions Copyright (c) 2010 Apple Inc. All rights reserved. 715813Sse * 815813Sse * Redistribution and use in source and binary forms, with or without 915813Sse * modification, are permitted provided that the following conditions 1015813Sse * are met: 1115813Sse * 1215813Sse * 1. Redistributions of source code must retain the above copyright 1315813Sse * notice, this list of conditions and the following disclaimer. 1415813Sse * 1515813Sse * 2. Redistributions in binary form must reproduce the above copyright 1615813Sse * notice, this list of conditions and the following disclaimer in the 1715813Sse * documentation and/or other materials provided with the distribution. 1815813Sse * 1915813Sse * 3. Neither the name of the Institute nor the names of its contributors 2050477Speter * may be used to endorse or promote products derived from this software 2115813Sse * without specific prior written permission. 2215813Sse * 2315813Sse * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2473374Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2550852Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2615813Sse * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2752247Smdodd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2850852Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2950852Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3052247Smdodd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3150852Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3252247Smdodd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3352247Smdodd * SUCH DAMAGE. 3450852Speter */ 3550852Speter 3650852Speter#include "config.h" 3750852Speter 3815813Sse#ifdef HAVE_SYS_TYPES_H 3952247Smdodd#include <sys/types.h> 4052247Smdodd#endif 4152247Smdodd#ifdef HAVE_SYS_SELECT_H 4251442Speter#include <sys/select.h> 4350852Speter#endif 4424995Sdavidn 4524995Sdavidn#include <stdio.h> 4650852Speter#include <stdlib.h> 4750852Speter#include <string.h> 4824995Sdavidn#include <errno.h> 4924995Sdavidn#include <limits.h> 5024995Sdavidn 5128210Sdanny#ifdef HAVE_UNISTD_H 5224995Sdavidn#include <unistd.h> 5324995Sdavidn#endif 5424995Sdavidn 5531347Smsmith#include "heimqueue.h" 5633893Sse#include "heim_threads.h" 5734645Sdanny#include "heimbase.h" 5824995Sdavidn#include "heimbasepriv.h" 5924995Sdavidn 6015813Sse#ifdef HAVE_DISPATCH_DISPATCH_H 6192739Salfred#include <dispatch/dispatch.h> 6292739Salfred#endif 6316289Salex 6450852Speter#if defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH) 6550852Speter 6615813Sse#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1) 6750852Speter#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1) 6824995Sdavidn#define heim_base_atomic_type unsigned int 6924995Sdavidn#define heim_base_atomic_max UINT_MAX 7024995Sdavidn 7124995Sdavidn#define heim_base_exchange_pointer(t,v) __sync_lock_test_and_set((t), (v)) 7250852Speter 7350852Speter#elif defined(_WIN32) 7450852Speter 7550852Speter#define heim_base_atomic_inc(x) InterlockedIncrement(x) 7650852Speter#define heim_base_atomic_dec(x) InterlockedDecrement(x) 7750852Speter#define heim_base_atomic_type LONG 7815813Sse#define heim_base_atomic_max MAXLONG 7915813Sse 8050852Speter#define heim_base_exchange_pointer(t,v) InterlockedExchangePointer((t),(v)) 8150852Speter 8215813Sse#else 8364777Snyan 8464777Snyan#define HEIM_BASE_NEED_ATOMIC_MUTEX 1 8564777Snyanextern HEIMDAL_MUTEX _heim_base_mutex; 8652247Smdodd 8764777Snyan#define heim_base_atomic_type unsigned int 8852247Smdodd 8952247Smdoddstatic inline heim_base_atomic_type 9052247Smdoddheim_base_atomic_inc(heim_base_atomic_type *x) 9152247Smdodd{ 9252247Smdodd heim_base_atomic_type t; 9352247Smdodd HEIMDAL_MUTEX_lock(&_heim_base_mutex); 9452247Smdodd t = ++(*x); 9552247Smdodd HEIMDAL_MUTEX_unlock(&_heim_base_mutex); 9652247Smdodd return t; 9752247Smdodd} 9852247Smdodd 9952247Smdoddstatic inline heim_base_atomic_type 10052247Smdoddheim_base_atomic_dec(heim_base_atomic_type *x) 10152247Smdodd{ 10252247Smdodd heim_base_atomic_type t; 10352247Smdodd HEIMDAL_MUTEX_lock(&_heim_base_mutex); 10452247Smdodd t = --(*x); 10552247Smdodd HEIMDAL_MUTEX_unlock(&_heim_base_mutex); 10652247Smdodd return t; 10750852Speter} 10815813Sse 10950852Speter#define heim_base_atomic_max UINT_MAX 11050852Speter 11150852Speter#endif 11250852Speter 11315813Sse/* tagged strings/object/XXX */ 11450852Speter#define heim_base_is_tagged(x) (((uintptr_t)(x)) & 0x3) 11550852Speter 11615813Sse#define heim_base_is_tagged_object(x) ((((uintptr_t)(x)) & 0x3) == 1) 11750852Speter#define heim_base_make_tagged_object(x, tid) \ 11850852Speter ((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1)) 11950852Speter#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2) 12050852Speter#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5) 12150852Speter 12215813Sse/* 123113506Smdodd * 124113506Smdodd */ 125113506Smdodd 126#undef HEIMDAL_NORETURN_ATTRIBUTE 127#define HEIMDAL_NORETURN_ATTRIBUTE 128#undef HEIMDAL_PRINTF_ATTRIBUTE 129#define HEIMDAL_PRINTF_ATTRIBUTE(x) 130