1226031Sstas/*
2226031Sstas * Copyright (c) 2010 Kungliga Tekniska H��gskolan
3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4226031Sstas * All rights reserved.
5226031Sstas *
6226031Sstas * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
7226031Sstas *
8226031Sstas * Redistribution and use in source and binary forms, with or without
9226031Sstas * modification, are permitted provided that the following conditions
10226031Sstas * are met:
11226031Sstas *
12226031Sstas * 1. Redistributions of source code must retain the above copyright
13226031Sstas *    notice, this list of conditions and the following disclaimer.
14226031Sstas *
15226031Sstas * 2. Redistributions in binary form must reproduce the above copyright
16226031Sstas *    notice, this list of conditions and the following disclaimer in the
17226031Sstas *    documentation and/or other materials provided with the distribution.
18226031Sstas *
19226031Sstas * 3. Neither the name of the Institute nor the names of its contributors
20226031Sstas *    may be used to endorse or promote products derived from this software
21226031Sstas *    without specific prior written permission.
22226031Sstas *
23226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26226031Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33226031Sstas * SUCH DAMAGE.
34226031Sstas */
35226031Sstas
36226031Sstas#include "config.h"
37226031Sstas
38226031Sstas#ifdef HAVE_SYS_TYPES_H
39226031Sstas#include <sys/types.h>
40226031Sstas#endif
41226031Sstas#ifdef HAVE_SYS_SELECT_H
42226031Sstas#include <sys/select.h>
43226031Sstas#endif
44226031Sstas
45226031Sstas#include <stdio.h>
46226031Sstas#include <stdlib.h>
47226031Sstas#include <string.h>
48226031Sstas#include <errno.h>
49226031Sstas#include <limits.h>
50226031Sstas
51226031Sstas#ifdef HAVE_UNISTD_H
52226031Sstas#include <unistd.h>
53226031Sstas#endif
54226031Sstas
55226031Sstas#include "heimqueue.h"
56226031Sstas#include "heim_threads.h"
57226031Sstas#include "heimbase.h"
58226031Sstas#include "heimbasepriv.h"
59226031Sstas
60226031Sstas#ifdef HAVE_DISPATCH_DISPATCH_H
61226031Sstas#include <dispatch/dispatch.h>
62226031Sstas#endif
63226031Sstas
64226031Sstas#if defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH)
65226031Sstas
66226031Sstas#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1)
67226031Sstas#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1)
68226031Sstas#define heim_base_atomic_type	unsigned int
69226031Sstas#define heim_base_atomic_max    UINT_MAX
70226031Sstas
71226031Sstas#define heim_base_exchange_pointer(t,v) __sync_lock_test_and_set((t), (v))
72226031Sstas
73226031Sstas#elif defined(_WIN32)
74226031Sstas
75226031Sstas#define heim_base_atomic_inc(x) InterlockedIncrement(x)
76226031Sstas#define heim_base_atomic_dec(x) InterlockedDecrement(x)
77226031Sstas#define heim_base_atomic_type	LONG
78226031Sstas#define heim_base_atomic_max    MAXLONG
79226031Sstas
80226031Sstas#define heim_base_exchange_pointer(t,v) InterlockedExchangePointer((t),(v))
81226031Sstas
82226031Sstas#else
83226031Sstas
84226031Sstas#define HEIM_BASE_NEED_ATOMIC_MUTEX 1
85226031Sstasextern HEIMDAL_MUTEX _heim_base_mutex;
86226031Sstas
87226031Sstas#define heim_base_atomic_type	unsigned int
88226031Sstas
89226031Sstasstatic inline heim_base_atomic_type
90226031Sstasheim_base_atomic_inc(heim_base_atomic_type *x)
91226031Sstas{
92226031Sstas    heim_base_atomic_type t;
93226031Sstas    HEIMDAL_MUTEX_lock(&_heim_base_mutex);
94226031Sstas    t = ++(*x);
95226031Sstas    HEIMDAL_MUTEX_unlock(&_heim_base_mutex);
96226031Sstas    return t;
97226031Sstas}
98226031Sstas
99226031Sstasstatic inline heim_base_atomic_type
100226031Sstasheim_base_atomic_dec(heim_base_atomic_type *x)
101226031Sstas{
102226031Sstas    heim_base_atomic_type t;
103226031Sstas    HEIMDAL_MUTEX_lock(&_heim_base_mutex);
104226031Sstas    t = --(*x);
105226031Sstas    HEIMDAL_MUTEX_unlock(&_heim_base_mutex);
106226031Sstas    return t;
107226031Sstas}
108226031Sstas
109226031Sstas#define heim_base_atomic_max    UINT_MAX
110226031Sstas
111226031Sstas#endif
112226031Sstas
113226031Sstas/* tagged strings/object/XXX */
114226031Sstas#define heim_base_is_tagged(x) (((uintptr_t)(x)) & 0x3)
115226031Sstas
116226031Sstas#define heim_base_is_tagged_object(x) ((((uintptr_t)(x)) & 0x3) == 1)
117226031Sstas#define heim_base_make_tagged_object(x, tid) \
118226031Sstas    ((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1))
119226031Sstas#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2)
120226031Sstas#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5)
121226031Sstas
122226031Sstas/*
123226031Sstas *
124226031Sstas */
125226031Sstas
126226031Sstas#undef HEIMDAL_NORETURN_ATTRIBUTE
127226031Sstas#define HEIMDAL_NORETURN_ATTRIBUTE
128226031Sstas#undef HEIMDAL_PRINTF_ATTRIBUTE
129226031Sstas#define HEIMDAL_PRINTF_ATTRIBUTE(x)
130