aboutsummaryrefslogblamecommitdiff
path: root/fastnn/threads/lib/THThread.c
blob: 7abc044a65a5dc431afa08e438577ce0b9c2e730 (plain) (tree)




























































































































































































































































































































































                                                                                              
#ifndef TH_THREAD_INC
#define TH_THREAD_INC

#include <stdlib.h>
#include <string.h>

/*#include "TH.h" */
#include "THThread.h"

#if defined(USE_PTHREAD_THREADS)
#include <pthread.h>

#elif defined(USE_WIN32_THREADS)

/* very basic emulation to suit our needs */

#include <process.h>
#include <windows.h>

typedef HANDLE pthread_t;
typedef DWORD pthread_attr_t;
typedef HANDLE pthread_mutex_t;
typedef HANDLE pthread_cond_t;

static int pthread_create(pthread_t *restrict thread,
                          const pthread_attr_t *restrict attr, void *(*start_routine)(void *),
                          void *restrict arg)
{
  *thread = (HANDLE)_beginthreadex(NULL, 0, (THREAD_FUNCTION)start_routine, arg, 0, NULL);
  return (int)(*thread == NULL);
}

static int pthread_join(pthread_t thread, void **value_ptr)
{
  return ((WaitForSingleObject((thread), INFINITE) != WAIT_OBJECT_0) || !CloseHandle(thread));
}

static int pthread_mutex_init(pthread_mutex_t *restrict mutex,
                              const pthread_mutexattr_t *restrict attr)
{
  *mutex = CreateMutex(NULL, FALSE, NULL);
  return (int)(*mutex == NULL);
}

static int pthread_mutex_lock(pthread_mutex_t *mutex)
{
  return WaitForSingleObject(*mutex, INFINITE) == 0;
}

static int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
  return ReleaseMutex(*mutex) == 0;
}

static int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
  return CloseHandle(*mutex) == 0;
}

static int pthread_cond_init(pthread_cond_t *restrict cond,
                             const pthread_condattr_t *restrict attr)
{
  *cond = CreateEvent(NULL, FALSE, FALSE, NULL);
  return (int)(*cond == NULL);
}

static int pthread_cond_wait(pthread_cond_t *restrict cond,
                             pthread_mutex_t *restrict mutex)
{
  SignalObjectAndWait(*mutex, *cond, INFINITE, FALSE);
  return WaitForSingleObject(*mutex, INFINITE) == 0;
}

static int pthread_cond_destroy(pthread_cond_t *cond)
{
  return CloseHandle(*cond) == 0;
}

int pthread_cond_signal(pthread_cond_t *cond)
{
  return SetEvent(*cond) == 0;
}

#else
#error no thread system available
#endif

typedef struct THThread_ {
  pthread_t id;
  int (*func)(void*);
  void* data;
  int status;
} THThread;

typedef struct THMutex_{
  pthread_mutex_t id;
  int refcount;
} THMutex;

typedef struct THCondition_ {
  pthread_cond_t id;
  int refcount;
} THCondition;

typedef struct THSemaphore_ {
	pthread_mutex_t mutex_;
	pthread_cond_t cond_;
	int 	counter_;
	int	refcount;
}THSemaphore;

static void* thread_closure(void *data)
{
  THThread *thread = data;
  thread->status = thread->func(thread->data);
  return NULL;
}

THThread* THThread_new(int (*func)(void*), void *data)
{
  THThread *self = malloc(sizeof(THThread));
  self->func = func;
  self->data = data;
  self->status = 0;
  if(!self)
    return NULL;
  if(pthread_create(&self->id, NULL, thread_closure, self)) {
    free(self);
    return NULL;
  }
  return self;
}

long THThread_id(THThread *self)
{
  return (long)(self);
}

int THThread_free(THThread *self)
{
  int status = 1;
  if(self) {
    if(pthread_join(self->id, NULL))
      return 1;
    status = self->status;
    free(self);
	self = NULL;
  }
  return status;
}

THMutex* THMutex_new(void)
{
  THMutex *self = malloc(sizeof(THMutex));
  if(!self)
    return NULL;
  if(pthread_mutex_init(&self->id, NULL) != 0) {
    free(self);
    return NULL;
  }
  self->refcount = 1;
  return self;
}

THMutex* THMutex_newWithId(long id)
{
  THMutex *self = (THMutex*)id;
  __sync_fetch_and_add(&self->refcount, 1);
  return self;
}

long THMutex_id(THMutex *self)
{
  return (long)(self);
}

int THMutex_lock(THMutex *self)
{
  if(pthread_mutex_lock(&self->id) != 0)
    return 1;
  return 0;
}

int THMutex_trylock(THMutex *self)
{
  if (pthread_mutex_trylock(&self->id) != 0)
	return 1; 
  return 0;
}

int THMutex_unlock(THMutex *self)
{
  if(pthread_mutex_unlock(&self->id) != 0)
    return 1;
  return 0;
}

void THMutex_free(THMutex *self)
{
  if(self) {
    if(__sync_fetch_and_add(&self->refcount, -1) == 1) {
      pthread_mutex_destroy(&self->id);
      free(self);
	self = NULL;
    }
  }
}

THCondition* THCondition_new(void)
{
  THCondition *self = malloc(sizeof(THCondition));
  if(!self)
    return NULL;
  if(pthread_cond_init(&self->id, NULL)) {
    free(self);
    return NULL;
  }
  self->refcount = 1;
  return self;
}

THCondition* THCondition_newWithId(long id)
{
  THCondition *self = (THCondition*)id;
  __sync_fetch_and_add(&self->refcount, 1);
  return self;
}

long THCondition_id(THCondition *self)
{
  return (long)(self);
}

int THCondition_signal(THCondition *self)
{
  if(pthread_cond_signal(&self->id))
    return 1;
  return 0;
}

int THCondition_wait(THCondition *self, THMutex *mutex)
{
  if(pthread_cond_wait(&self->id, &mutex->id))
    return 1;
  return 0;
}

void THCondition_free(THCondition *self)
{
  if(self) {
    if(__sync_fetch_and_add(&self->refcount, -1) == 1) {
      pthread_cond_destroy(&self->id);
	free(self);
	self = NULL;
    }
  }
}

THSemaphore* THSemaphore_new(int initValue)
{
	THSemaphore *self = malloc(sizeof(THSemaphore));
  	if(!self)
    		return NULL;
	self->counter_ = initValue;	
  	if(pthread_mutex_init(&self->mutex_, NULL) != 0) 
	{
    		free(self);
    		return NULL;
  	}

	if(pthread_cond_init(&self->cond_, NULL) != 0) 
	{
    		free(self);
    		return NULL;
	}
	
  	self->refcount = 1;

  return self;
}

THSemaphore* THSemaphore_newWithId(long id)
{
	THSemaphore *self = (THSemaphore*)id;
  	__sync_fetch_and_add(&self->refcount, 1);
	return self;
}

long    THSemaphore_id(THSemaphore *self)
{
	return (long)(self);
}

int     THSemaphore_wait(THSemaphore *self)
{
	int ret = 0;
	ret |= pthread_mutex_lock(&self->mutex_);	
	
	while (self->counter_ <= 0)
		ret |= pthread_cond_wait(&self->cond_, &self->mutex_);
	
	self->counter_--;	
	ret |= pthread_mutex_unlock(&self->mutex_);

	return ret;	
	
}

int     THSemaphore_signal(THSemaphore *self)
{
	int ret = 0;
	ret |= pthread_mutex_lock(&self->mutex_);
	self->counter_++;
	ret |= pthread_cond_signal(&self->cond_);
	ret |= pthread_mutex_unlock(&self->mutex_);

	return ret;
}

int     THSemaphore_trywait(THSemaphore *self)
{
	int ret = 0;
	int try_wait_succeeded = 1;
	ret |= pthread_mutex_lock(&self->mutex_);
  	if (self->counter_ > 0) {
    		self->counter_--;
    		try_wait_succeeded = 0;
  	}
  	ret |= pthread_mutex_unlock(&self->mutex_);
	return try_wait_succeeded;
}

void    THSemaphore_free(THSemaphore *self)
{
	if(self) 
	{
    		if(__sync_fetch_and_add(&self->refcount, -1) == 1) 
		{
			pthread_mutex_destroy(&self->mutex_);
			pthread_cond_destroy(&self->cond_);
			free(self);
			self = NULL;
    		}
	}
  }
	


#endif