167754Smsmith/*
267754Smsmith * Copyright (c) 2010 Kungliga Tekniska H��gskolan
377424Smsmith * (Royal Institute of Technology, Stockholm, Sweden).
491116Smsmith * All rights reserved.
567754Smsmith *
667754Smsmith * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
767754Smsmith *
867754Smsmith * Redistribution and use in source and binary forms, with or without
967754Smsmith * modification, are permitted provided that the following conditions
1067754Smsmith * are met:
1167754Smsmith *
1291116Smsmith * 1. Redistributions of source code must retain the above copyright
1370243Smsmith *    notice, this list of conditions and the following disclaimer.
1467754Smsmith *
1567754Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1667754Smsmith *    notice, this list of conditions and the following disclaimer in the
1767754Smsmith *    documentation and/or other materials provided with the distribution.
1867754Smsmith *
1967754Smsmith * 3. Neither the name of the Institute nor the names of its contributors
2067754Smsmith *    may be used to endorse or promote products derived from this software
2167754Smsmith *    without specific prior written permission.
2267754Smsmith *
2367754Smsmith * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2467754Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2567754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2667754Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2767754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2867754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2967754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3067754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3167754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3267754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3367754Smsmith * SUCH DAMAGE.
3467754Smsmith */
3567754Smsmith
3667754Smsmith#include "config.h"
3767754Smsmith
3867754Smsmith#ifdef HAVE_SYS_TYPES_H
3967754Smsmith#include <sys/types.h>
4067754Smsmith#endif
4167754Smsmith#ifdef HAVE_SYS_SELECT_H
4267754Smsmith#include <sys/select.h>
4367754Smsmith#endif
4467754Smsmith
4567754Smsmith#include <stdio.h>
4667754Smsmith#include <stdlib.h>
4767754Smsmith#include <string.h>
4867754Smsmith#include <errno.h>
4967754Smsmith#include <limits.h>
5067754Smsmith
5167754Smsmith#ifdef HAVE_UNISTD_H
5267754Smsmith#include <unistd.h>
5367754Smsmith#endif
5467754Smsmith
5567754Smsmith#include "heimqueue.h"
5667754Smsmith#include "heim_threads.h"
5767754Smsmith#include "heimbase.h"
5867754Smsmith#include "heimbasepriv.h"
5967754Smsmith
6067754Smsmith#ifdef HAVE_DISPATCH_DISPATCH_H
6167754Smsmith#include <dispatch/dispatch.h>
6267754Smsmith#endif
6367754Smsmith
6467754Smsmith#if defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH)
6567754Smsmith
6667754Smsmith#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1)
6767754Smsmith#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1)
6867754Smsmith#define heim_base_atomic_type	unsigned int
6967754Smsmith#define heim_base_atomic_max    UINT_MAX
7067754Smsmith
7167754Smsmith#define heim_base_exchange_pointer(t,v) __sync_lock_test_and_set((t), (v))
7267754Smsmith
7367754Smsmith#elif defined(_WIN32)
7467754Smsmith
7567754Smsmith#define heim_base_atomic_inc(x) InterlockedIncrement(x)
7667754Smsmith#define heim_base_atomic_dec(x) InterlockedDecrement(x)
7767754Smsmith#define heim_base_atomic_type	LONG
7867754Smsmith#define heim_base_atomic_max    MAXLONG
7967754Smsmith
8067754Smsmith#define heim_base_exchange_pointer(t,v) InterlockedExchangePointer((t),(v))
8167754Smsmith
8267754Smsmith#else
8367754Smsmith
8467754Smsmith#define HEIM_BASE_NEED_ATOMIC_MUTEX 1
8567754Smsmithextern HEIMDAL_MUTEX _heim_base_mutex;
8667754Smsmith
8767754Smsmith#define heim_base_atomic_type	unsigned int
8867754Smsmith
8967754Smsmithstatic inline heim_base_atomic_type
9067754Smsmithheim_base_atomic_inc(heim_base_atomic_type *x)
9167754Smsmith{
9267754Smsmith    heim_base_atomic_type t;
9367754Smsmith    HEIMDAL_MUTEX_lock(&_heim_base_mutex);
9467754Smsmith    t = ++(*x);
9567754Smsmith    HEIMDAL_MUTEX_unlock(&_heim_base_mutex);
9667754Smsmith    return t;
9767754Smsmith}
9867754Smsmith
9967754Smsmithstatic inline heim_base_atomic_type
10067754Smsmithheim_base_atomic_dec(heim_base_atomic_type *x)
10167754Smsmith{
10267754Smsmith    heim_base_atomic_type t;
10367754Smsmith    HEIMDAL_MUTEX_lock(&_heim_base_mutex);
10467754Smsmith    t = --(*x);
10567754Smsmith    HEIMDAL_MUTEX_unlock(&_heim_base_mutex);
10667754Smsmith    return t;
10767754Smsmith}
10867754Smsmith
10967754Smsmith#define heim_base_atomic_max    UINT_MAX
11067754Smsmith
11167754Smsmith#endif
11267754Smsmith
11367754Smsmith/* tagged strings/object/XXX */
11467754Smsmith#define heim_base_is_tagged(x) (((uintptr_t)(x)) & 0x3)
11567754Smsmith
11667754Smsmith#define heim_base_is_tagged_object(x) ((((uintptr_t)(x)) & 0x3) == 1)
11767754Smsmith#define heim_base_make_tagged_object(x, tid) \
11867754Smsmith    ((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1))
11967754Smsmith#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2)
12067754Smsmith#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5)
12169450Smsmith
12267754Smsmith/*
12377424Smsmith *
12491116Smsmith */
12567754Smsmith
12667754Smsmith#undef HEIMDAL_NORETURN_ATTRIBUTE
12783174Smsmith#define HEIMDAL_NORETURN_ATTRIBUTE
12883174Smsmith#undef HEIMDAL_PRINTF_ATTRIBUTE
12967754Smsmith#define HEIMDAL_PRINTF_ATTRIBUTE(x)
13067754Smsmith