Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save heuripedes/ef4bfc033252d511075b to your computer and use it in GitHub Desktop.
Save heuripedes/ef4bfc033252d511075b to your computer and use it in GitHub Desktop.
libco pthread by aliaspider
#define LIBCO_C
#include <libco.h>
#include <stdlib.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
pthread_t pthread_id;
pthread_cond_t running_cond;
void (*coentry)(void);
}co_pthread_t;
static co_pthread_t* co_running = 0;
static pthread_mutex_t* co_switch_mutex = NULL;
static bool co_inited = false;
static void co_init(void)
{
co_switch_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(co_switch_mutex,NULL);
pthread_mutex_lock(co_switch_mutex);
co_running = (co_pthread_t*)calloc(1,sizeof(co_pthread_t));
pthread_cond_init(&co_running->running_cond,NULL);
co_inited = true;
}
cothread_t co_active(void)
{
if (!co_inited)
co_init();
return (cothread_t)co_running;
}
void* co_entry_wrap (void* args)
{
co_pthread_t* thread = (co_pthread_t*)args;
pthread_mutex_lock(co_switch_mutex);
pthread_cond_signal(&co_running->running_cond);
pthread_cond_wait(&thread->running_cond, co_switch_mutex);
thread->coentry();
return NULL;
}
cothread_t co_create(unsigned int stacksize, void (*coentry)(void))
{
if (!co_inited)
co_init();
pthread_attr_t attr;
co_pthread_t* thread = (co_pthread_t*)malloc(sizeof(co_pthread_t));
thread->coentry = coentry;
pthread_cond_init(&thread->running_cond, NULL);
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stacksize);
pthread_create(&thread->pthread_id, &attr, co_entry_wrap, thread);
pthread_attr_destroy(&attr);
pthread_cond_wait(&co_running->running_cond, co_switch_mutex);
return (cothread_t)thread;
}
void co_delete(cothread_t cothread)
{
co_pthread_t* thread = (co_pthread_t*)cothread;
if (!thread)
return;
// pthread_cancel(thread->pthread_id);
pthread_cond_destroy(&thread->running_cond);
free(thread);
}
void co_switch(cothread_t cothread)
{
co_pthread_t *old_thread;
old_thread = co_running;
co_running = (co_pthread_t*)cothread;
pthread_cond_signal(&co_running->running_cond);
pthread_cond_wait(&old_thread->running_cond, co_switch_mutex);
}
#ifdef __cplusplus
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment