/* This code implemented by cvale@netcom.com */

#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#include "os2.h"
#include "limits.h"

#include "process.h"

#if defined(PYCC_GCC)
#include <sys/builtin.h>
#include <sys/fmutex.h>
#else
long PyThread_get_thread_ident(void);
#endif

/* default thread stack size of 64kB */
#if !defined(THREAD_STACK_SIZE)
#define	THREAD_STACK_SIZE	0x10000
#endif

#define OS2_STACKSIZE(x)	(x ? x : THREAD_STACK_SIZE)

/*
 * Initialization of the C package, should not be needed.
 */
static void
PyThread__init_thread(void)
{
}

/*
 * Thread support.
 */
long
PyThread_start_new_thread(void (*func)(void *), void *arg)
{
	int thread_id;

	thread_id = _beginthread(func,
				NULL,
				OS2_STACKSIZE(_pythread_stacksize),
				arg);

	if (thread_id == -1) {
		dprintf(("_beginthread failed. return %ld\n", errno));
	}

	return thread_id;
}

long
PyThread_get_thread_ident(void)
{
#if !defined(PYCC_GCC)
	PPIB pib;
	PTIB tib;
#endif

	if (!initialized)
		PyThread_init_thread();

#if defined(PYCC_GCC)
	return _gettid();
#else
	DosGetInfoBlocks(&tib, &pib);
	return tib->tib_ptib2->tib2_ultid;
#endif
}

static void
do_PyThread_exit_thread(int no_cleanup)
{
	dprintf(("%ld: PyThread_exit_thread called\n",
		 PyThread_get_thread_ident()));
	if (!initialized)
		if (no_cleanup)
			_exit(0);
		else
			exit(0);
	_endthread();
}

void 
PyThread_exit_thread(void)
{
	do_PyThread_exit_thread(0);
}

void 
PyThread__exit_thread(void)
{
	do_PyThread_exit_thread(1);
}

#ifndef NO_EXIT_PROG
static void 
do_PyThread_exit_prog(int status, int no_cleanup)
{
	dprintf(("PyThread_exit_prog(%d) called\n", status));
	if (!initialized)
		if (no_cleanup)
			_exit(status);
		else
			exit(status);
}

void 
PyThread_exit_prog(int status)
{
	do_PyThread_exit_prog(status, 0);
}

void 
PyThread__exit_prog(int status)
{
	do_PyThread_exit_prog(status, 1);
}
#endif /* NO_EXIT_PROG */

/*
 * Lock support.  This is implemented with an event semaphore and critical
 * sections to make it behave more like a posix mutex than its OS/2 
 * counterparts.
 */

typedef struct os2_lock_t {
	int is_set;
	HEV changed;
} *type_os2_lock;

PyThread_type_lock 
PyThread_allocate_lock(void)
{
#if defined(PYCC_GCC)
	_fmutex *sem = malloc(sizeof(_fmutex));
	if (!initialized)
		PyThread_init_thread();
	dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
		 PyThread_get_thread_ident(),
		 (long)sem));
	if (_fmutex_create(sem, 0)) {
		free(sem);
		sem = NULL;
	}
	return (PyThread_type_lock)sem;
#else
	APIRET rc;
	type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));

	dprintf(("PyThread_allocate_lock called\n"));
	if (!initialized)
		PyThread_init_thread();

	lock->is_set = 0;

	DosCreateEventSem(NULL, &lock->changed, 0, 0);

	dprintf(("%ld: PyThread_allocate_lock() -> %p\n", 
		 PyThread_get_thread_ident(), 
        	 lock->changed));

	return (PyThread_type_lock)lock;
#endif
}

void 
PyThread_free_lock(PyThread_type_lock aLock)
{
#if !defined(PYCC_GCC)
	type_os2_lock lock = (type_os2_lock)aLock;
#endif

	dprintf(("%ld: PyThread_free_lock(%p) called\n",
		 PyThread_get_thread_ident(),aLock));

#if defined(PYCC_GCC)
	if (aLock) {
		_fmutex_close((_fmutex *)aLock);
		free((_fmutex *)aLock);
	}
#else
	DosCloseEventSem(lock->changed);
	free(aLock);
#endif
}

/*
 * Return 1 on success if the lock was acquired
 *
 * and 0 if the lock was not acquired.
 */
int 
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
{
#if !defined(PYCC_GCC)
	int   done = 0;
	ULONG count;
	PID   pid = 0;
	TID   tid = 0;
	type_os2_lock lock = (type_os2_lock)aLock;
#endif

	dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
		 PyThread_get_thread_ident(),
		 aLock,
		 waitflag));

#if defined(PYCC_GCC)
	/* always successful if the lock doesn't exist */
	if (aLock &&
	    _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
		return 0;
#else
	while (!done) {
		/* if the lock is currently set, we have to wait for
		 * the state to change
		 */
		if (lock->is_set) {
			if (!waitflag)
				return 0;
			DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
		}

		/* enter a critical section and try to get the semaphore.  If
		 * it is still locked, we will try again.
		 */
		if (DosEnterCritSec())
			return 0;

		if (!lock->is_set) {
			lock->is_set = 1;
			DosResetEventSem(lock->changed, &count);
			done = 1;
		}

		DosExitCritSec();
	}
#endif

	return 1;
}

void
PyThread_release_lock(PyThread_type_lock aLock)
{
#if !defined(PYCC_GCC)
	type_os2_lock lock = (type_os2_lock)aLock;
#endif

	dprintf(("%ld: PyThread_release_lock(%p) called\n",
		 PyThread_get_thread_ident(),
		 aLock));

#if defined(PYCC_GCC)
	if (aLock)
		_fmutex_release((_fmutex *)aLock);
#else
	if (!lock->is_set) {
		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
			 PyThread_get_thread_ident(),
			 aLock,
			 GetLastError()));
		return;
	}

	if (DosEnterCritSec()) {
		dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
			 PyThread_get_thread_ident(),
			 aLock,
			 GetLastError()));
		return;
	}

	lock->is_set = 0;
	DosPostEventSem(lock->changed);

	DosExitCritSec();
#endif
}

/* minimum/maximum thread stack sizes supported */
#define THREAD_MIN_STACKSIZE	0x8000		/* 32kB */
#define THREAD_MAX_STACKSIZE	0x2000000	/* 32MB */

/* set the thread stack size.
 * Return 0 if size is valid, -1 otherwise.
 */
static int
_pythread_os2_set_stacksize(size_t size)
{
	/* set to default */
	if (size == 0) {
		_pythread_stacksize = 0;
		return 0;
	}

	/* valid range? */
	if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
		_pythread_stacksize = size;
		return 0;
	}

	return -1;
}

#define THREAD_SET_STACKSIZE(x)	_pythread_os2_set_stacksize(x)
