Skip to content

Instantly share code, notes, and snippets.

@informationsea
Created December 29, 2015 04:14
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save informationsea/f63c2b3854b20bd540ab to your computer and use it in GitHub Desktop.
Save informationsea/f63c2b3854b20bd540ab to your computer and use it in GitHub Desktop.
pthread compatible library for windows
/*
* light weight pthread compatible library for Windows
* (C) 2009 Okamura Yasunobu
*/
#include "crossthread.h"
#include <stdio.h>
#ifdef _WIN32
typedef void (*windows_thread)(void *);
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void
*(*start_routine)(void *), void *arg)
{
uintptr_t handle = _beginthread((windows_thread)start_routine,0,arg);
thread->handle = (HANDLE)handle;
if(thread->handle == (HANDLE)-1){
return 1;
}else{
return 0;
}
}
int pthread_detach(pthread_t thread)
{
/* Do nothing */
return 0;
}
void pthread_exit(void *value_ptr)
{
_endthread();
}
int pthread_join(pthread_t thread, void **value_ptr)
{
DWORD retvalue = WaitForSingleObject(thread.handle,INFINITE);
if(retvalue == WAIT_OBJECT_0){
return 0;
}else{
return EINVAL;
}
}
pthread_t pthread_self(void)
{
pthread_t pt;
pt.handle = GetCurrentThread();
return pt;
}
int pthread_cancel(pthread_t thread)
{
fprintf(stderr,"DO NOT USE THIS FUNCTION. pthread_cancel\n");
abort();
return 0;
}
/* --------------------- MUTEX --------------------*/
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
/* do nothing */
return 0;
}
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
/* do nothing */
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
return !CloseHandle(mutex->handle);
}
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
HANDLE handle = CreateMutex(NULL,FALSE,NULL);
if(handle != NULL){
mutex->handle = handle;
return 0;
}else{
return 1;
}
}
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
DWORD retvalue = WaitForSingleObject(mutex->handle,INFINITE);
if(retvalue == WAIT_OBJECT_0){
return 0;
}else{
return EINVAL;
}
}
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
DWORD retvalue = WaitForSingleObject(mutex->handle,0);
if(retvalue == WAIT_OBJECT_0){
return 0;
}else if(retvalue == WAIT_TIMEOUT){
return EBUSY;
}else{
return EINVAL;
}
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
return !ReleaseMutex(mutex->handle);
}
/* ------------------- Thead Specific Data ------------------ */
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))
{
DWORD dkey = TlsAlloc();
if(dkey != 0xFFFFFFFF){
*key = dkey;
return 0;
}else{
return EAGAIN;
}
}
int pthread_key_delete(pthread_key_t key)
{
if(TlsFree(key)){
return 0;
}else{
return EINVAL;
}
}
int pthread_setspecific(pthread_key_t key, const void *pointer)
{
if(TlsSetValue(key,(LPVOID)pointer)){
return 0;
}else{
return EINVAL;
}
}
void * pthread_getspecific(pthread_key_t key)
{
return TlsGetValue(key);
}
#endif
/*
* light weight pthread compatible library for Windows
* (C) 2009 Okamura Yasunobu
*
* WARNING This library does NOT support all future of pthread
*
*/
#ifndef CROSS_THREAD_H
#define CROSS_THREAD_H
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
#include <windows.h>
#include <process.h>
#include <errno.h>
typedef struct pthread_tag {
HANDLE handle;
} pthread_t;
typedef struct pthread_mutex_tag {
HANDLE handle;
} pthread_mutex_t;
/* stub */
typedef struct pthread_attr_tag {
int attr;
} pthread_attr_t;
typedef struct pthread_mutexattr_tag {
int attr;
} pthread_mutexattr_t;
typedef DWORD pthread_key_t;
/* ignore attribute */
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void
*(*start_routine)(void *), void *arg);
/* ignore value_ptr */
void pthread_exit(void *value_ptr);
/* ignore value_ptr */
int pthread_join(pthread_t thread, void **value_ptr);
pthread_t pthread_self(void);
/* do nothing */
int pthread_detach(pthread_t thread);
/* DO NOT USE */
int pthread_cancel(pthread_t thread);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); /* do nothing */
int pthread_mutexattr_init(pthread_mutexattr_t *attr); /* do nothing */
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
/* ignore deconstructor */
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);
#define sleep(num) Sleep(1000*(num))
#ifdef __cplusplus
}
#endif
#else
#include <pthread.h>
#include <unistd.h>
#define Sleep(num) usleep(num*1000)
#endif
#endif /* CROSS_THREAD_H */
@hbs24
Copy link

hbs24 commented Jan 23, 2019

Add posix condition variable functions.
be aware that pthread_cond_t struct is similar to pthread_mutex_t as defined at crossthread.h
(I'm use EVENT object and not CONDITION VARIABLE which compatible with CRITICAL SECTION object instead of MUTEX)

int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr) {
	
	HANDLE handle= CreateEventA(NULL, FALSE, FALSE, NULL);
	if (handle != NULL) {
		cond->handle = handle;
		return 0;
	
	}
	else {
		return 1;
	}
}

int pthread_cond_signal(pthread_cond_t *cond) {

	return SetEvent(cond->handle);
	
}

DWORD pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {

	ReleaseMutex(mutex->handle);
	WaitForSingleObject(cond->handle, INFINITE);
	return pthread_mutex_lock(mutex);
	

}

@mu578
Copy link

mu578 commented Jun 20, 2021

A bit violent, anyways windows deserves brutal force, that's only thing this OS understands.

int pthread_cancel(pthread_t thread)
{
	WaitForSingleObject(thread->handle, 2);
	TerminateThread(thread->handle, 0);
	CloseHandle(thread->handle);
	return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment