/* *******************************************************************************
 * Copyright (c) 2013-2014 Google, Inc.  All rights reserved.
 * *******************************************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/*
 * ksynch_macos.c - synchronization via the kernel
 *
 * FIXME i#58: NYI (see comments below as well):
 * + Haven't really tested this yet
 * + Longer-term i#1291: use raw syscalls instead of libSystem wrappers.
 *   Some of these are basically just Mach syscall wrappers, but others like
 *   semaphore_create() are slightly more involved.
 */

#include "../globals.h"
#include "ksynch.h"

#include <mach/mach.h>
#include <mach/task.h>
#include <mach/semaphore.h>
#include <mach/sync_policy.h>

/* Only in kernel headers, not in user headers */
#define SYNC_POLICY_PREPOST          0x4

#ifndef MACOS
# error Mac-only
#endif

void
ksynch_init(void)
{
}

void
ksynch_exit(void)
{
}

bool
ksynch_kernel_support(void)
{
    return true;
}

bool
ksynch_init_var(mac_synch_t *synch)
{
    /* We use SYNC_POLICY_PREPOST so that a signal sent is not lost if there's
     * no thread waiting at that precise point.
     */
    kern_return_t res = semaphore_create(mach_task_self(), &synch->sem,
                                         SYNC_POLICY_PREPOST, 0);
    ASSERT(synch->sem != 0); /* we assume 0 is never a legitimate value */
    synch->value = 0;
    LOG(THREAD_GET, LOG_THREADS, 2, "semaphore %d created, status %d\n",
        synch->sem, res);
    return (res == KERN_SUCCESS);
}

bool
ksynch_var_initialized(mac_synch_t *synch)
{
    /* semaphore_t is a mach_port_t which is a natural_t == unsigned */
    return (synch->sem != 0);
}

bool
ksynch_free_var(mac_synch_t *synch)
{
    kern_return_t res = semaphore_destroy(mach_task_self(), synch->sem);
    synch->sem = 0;
    return (res == KERN_SUCCESS);
}

ptr_int_t
ksynch_get_value(mac_synch_t *synch)
{
    return synch->value;
}

void
ksynch_set_value(mac_synch_t *synch, int new_val)
{
    synch->value = new_val;
}

ptr_int_t
ksynch_wait(mac_synch_t *synch, int mustbe)
{
    /* We don't need to bother with "mustbe" b/c of SYNC_POLICY_PREPOST */
    kern_return_t res = semaphore_wait(synch->sem);
    return (res == KERN_SUCCESS ? 0 : -1);
}

ptr_int_t
ksynch_wake(mac_synch_t *synch)
{
    kern_return_t res = semaphore_signal(synch->sem);
    return (res == KERN_SUCCESS ? 0 : -1);
}

ptr_int_t
ksynch_wake_all(mac_synch_t *synch)
{
    kern_return_t res = semaphore_signal_all(synch->sem);
    return (res == KERN_SUCCESS ? 0 : -1);
}

mac_synch_t *
mutex_get_contended_event(mutex_t *lock)
{
    if (!ksynch_var_initialized(&lock->contended_event)) {
        mac_synch_t local;
        bool not_yet_created;
        if (!ksynch_init_var(&local)) {
            ASSERT_NOT_REACHED();
            return NULL;
        }
        not_yet_created =
            atomic_compare_exchange_int((int*)&lock->contended_event.sem,
                                        0, (int)local.sem);
        if (not_yet_created) {
            /* we're the ones to initialize it */
        } else {
            /* already created */
            ksynch_free_var(&local);
        }
    }
    return &lock->contended_event;
}

void
mutex_free_contended_event(mutex_t *lock)
{
    ksynch_free_var(&lock->contended_event);
    lock->contended_event.sem = 0;
}
