/* Threading for AtheOS.
   Based on thread_beos.h. */

#include <atheos/threads.h>
#include <atheos/semaphore.h>
#include <atheos/atomic.h>
#include <errno.h>
#include <string.h>

/* Missing decl from threads.h */
extern int exit_thread(int);


/* Undefine FASTLOCK to play with simple semaphores. */
#define FASTLOCK


#ifdef FASTLOCK

/* Use an atomic counter and a semaphore for maximum speed. */
typedef struct fastmutex {
    sem_id sem;
    atomic_t count;
} fastmutex_t;


static int fastmutex_create(const char *name, fastmutex_t * mutex);
static int fastmutex_destroy(fastmutex_t * mutex);
static int fastmutex_lock(fastmutex_t * mutex);
static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout);
static int fastmutex_unlock(fastmutex_t * mutex);


static int fastmutex_create(const char *name, fastmutex_t * mutex)
{
    mutex->count = 0;
    mutex->sem = create_semaphore(name, 0, 0);
    return (mutex->sem < 0) ? -1 : 0;
}


static int fastmutex_destroy(fastmutex_t * mutex)
{
    if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
        return delete_semaphore(mutex->sem);
    }
    return 0;
}


static int fastmutex_lock(fastmutex_t * mutex)
{
    atomic_t prev = atomic_add(&mutex->count, 1);
    if (prev > 0)
        return lock_semaphore(mutex->sem);
    return 0;
}


static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout)
{
    atomic_t prev = atomic_add(&mutex->count, 1);
    if (prev > 0)
        return lock_semaphore_x(mutex->sem, 1, 0, timeout);
    return 0;
}


static int fastmutex_unlock(fastmutex_t * mutex)
{
    atomic_t prev = atomic_add(&mutex->count, -1);
    if (prev > 1)
        return unlock_semaphore(mutex->sem);
    return 0;
}


#endif                          /* FASTLOCK */


/*
 * Initialization.
 *
 */
static void PyThread__init_thread(void)
{
    /* Do nothing. */
    return;
}


/*
 * Thread support.
 *
 */

static atomic_t thread_count = 0;

long PyThread_start_new_thread(void (*func) (void *), void *arg)
{
    status_t success = -1;
    thread_id tid;
    char name[OS_NAME_LENGTH];
    atomic_t this_thread;

    dprintf(("PyThread_start_new_thread called\n"));

    this_thread = atomic_add(&thread_count, 1);
    PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);

    tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
    if (tid < 0) {
        dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
    } else {
        success = resume_thread(tid);
        if (success < 0) {
            dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
        }
    }

    return (success < 0 ? -1 : tid);
}


long PyThread_get_thread_ident(void)
{
    return get_thread_id(NULL);
}


void PyThread_exit_thread(void)
{
    dprintf(("PyThread_exit_thread called\n"));

    /* Thread-safe way to read a variable without a mutex: */
    if (atomic_add(&thread_count, 0) == 0) {
        /* No threads around, so exit main(). */
        exit(0);
    } else {
        /* We're a thread */
        exit_thread(0);
    }
}


/*
 * Lock support.
 *
 */

static atomic_t lock_count = 0;

PyThread_type_lock PyThread_allocate_lock(void)
{
#ifdef FASTLOCK
    fastmutex_t *lock;
#else
    sem_id sema;
#endif
    char name[OS_NAME_LENGTH];
    atomic_t this_lock;

    dprintf(("PyThread_allocate_lock called\n"));

#ifdef FASTLOCK
    lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
    if (lock == NULL) {
        dprintf(("PyThread_allocate_lock failed: out of memory\n"));
        return (PyThread_type_lock) NULL;
    }
#endif
    this_lock = atomic_add(&lock_count, 1);
    PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);

#ifdef FASTLOCK
    if (fastmutex_create(name, lock) < 0) {
        dprintf(("PyThread_allocate_lock failed: %s\n",
                 strerror(errno)));
        free(lock);
        lock = NULL;
    }
    dprintf(("PyThread_allocate_lock()-> %p\n", lock));
    return (PyThread_type_lock) lock;
#else
    sema = create_semaphore(name, 1, 0);
    if (sema < 0) {
        dprintf(("PyThread_allocate_lock failed: %s\n",
                 strerror(errno)));
        sema = 0;
    }
    dprintf(("PyThread_allocate_lock()-> %p\n", sema));
    return (PyThread_type_lock) sema;
#endif
}


void PyThread_free_lock(PyThread_type_lock lock)
{
    dprintf(("PyThread_free_lock(%p) called\n", lock));

#ifdef FASTLOCK
    if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
        dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
                 strerror(errno)));
    }
    free(lock);
#else
    if (delete_semaphore((sem_id) lock) < 0) {
        dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
                 strerror(errno)));
    }
#endif
}


int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
{
    int retval;

    dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
             waitflag));

#ifdef FASTLOCK
    if (waitflag)
        retval = fastmutex_lock((fastmutex_t *) lock);
    else
        retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
#else
    if (waitflag)
        retval = lock_semaphore((sem_id) lock);
    else
        retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
#endif
    if (retval < 0) {
        dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
                 lock, waitflag, strerror(errno)));
    }
    dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
             retval));
    return retval < 0 ? 0 : 1;
}


void PyThread_release_lock(PyThread_type_lock lock)
{
    dprintf(("PyThread_release_lock(%p) called\n", lock));

#ifdef FASTLOCK
    if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
        dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
                 strerror(errno)));
    }
#else
    if (unlock_semaphore((sem_id) lock) < 0) {
        dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
                 strerror(errno)));
    }
#endif
}
