//
//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
//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 3Dlabs Inc. Ltd. 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 THE
//COPYRIGHT HOLDERS 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.
//

//
// This file contains the Linux-specific functions
//
#include "../osinclude.h"
#include "../../../OGLCompilersDLL/InitializeDll.h"

#include <pthread.h>
#include <semaphore.h>
#include <assert.h>
#include <errno.h>
#include <stdint.h>

namespace glslang {

//
// Thread cleanup
//

//
// Wrapper for Linux call to DetachThread.  This is required as pthread_cleanup_push() expects 
// the cleanup routine to return void.
// 
static void DetachThreadLinux(void *)
{
	DetachThread();
}


//
// Registers cleanup handler, sets cancel type and state, and executes the thread specific
// cleanup handler.  This function will be called in the Standalone.cpp for regression 
// testing.  When OpenGL applications are run with the driver code, Linux OS does the 
// thread cleanup.
// 
void OS_CleanupThreadData(void)
{
#ifdef __Fuchsia__
	// Fuchsia does not have a meaningful pthread_cancel, so just do nothing.
#else
#ifdef __ANDROID__
	DetachThreadLinux(NULL);
#else
	int old_cancel_state, old_cancel_type;
	void *cleanupArg = NULL;

	//
	// Set thread cancel state and push cleanup handler.
	//
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
	pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);

	//
	// Put the thread in deferred cancellation mode.
	//
	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);

	//
	// Pop cleanup handler and execute it prior to unregistering the cleanup handler.
	//
	pthread_cleanup_pop(1);

	//
	// Restore the thread's previous cancellation mode.
	//
	pthread_setcanceltype(old_cancel_state, NULL);
#endif
}


//
// Thread Local Storage Operations
//
inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key)
{
	return (OS_TLSIndex)((uintptr_t)key + 1);
}

inline pthread_key_t TLSIndexToPthreadKey(OS_TLSIndex nIndex)
{
	return (pthread_key_t)((uintptr_t)nIndex - 1);
}

OS_TLSIndex OS_AllocTLSIndex()
{
	pthread_key_t pPoolIndex;

	//
	// Create global pool key.
	//
	if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
		assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
		return OS_INVALID_TLS_INDEX;
	}
	else
		return PthreadKeyToTLSIndex(pPoolIndex);
}


bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
{
	if (nIndex == OS_INVALID_TLS_INDEX) {
		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
		return false;
	}

	if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0)
		return true;
	else
		return false;
}

void* OS_GetTLSValue(OS_TLSIndex nIndex)
{
	//
	// This function should return 0 if nIndex is invalid.
	//
	assert(nIndex != OS_INVALID_TLS_INDEX);
	return pthread_getspecific(TLSIndexToPthreadKey(nIndex)); 
}

bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
{
	if (nIndex == OS_INVALID_TLS_INDEX) {
		assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
		return false;
	}

	//
	// Delete the global pool key.
	//
	if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0)
		return true;
	else
		return false;
}

namespace {
pthread_mutex_t gMutex;
}

void InitGlobalLock()
{
  pthread_mutexattr_t mutexattr;
  pthread_mutexattr_init(&mutexattr);
  pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&gMutex, &mutexattr);
}

void GetGlobalLock()
{
  pthread_mutex_lock(&gMutex);
}

void ReleaseGlobalLock()
{
  pthread_mutex_unlock(&gMutex);
}

// TODO: non-windows: if we need these on linux, flesh them out
void* OS_CreateThread(TThreadEntrypoint /*entry*/)
{
    return 0;
}

void OS_WaitForAllThreads(void* /*threads*/, int /*numThreads*/)
{
}

void OS_Sleep(int /*milliseconds*/)
{
}

void OS_DumpMemoryCounters()
{
}

} // end namespace glslang
