#include <stdio.h>
#include "threads.h"
#define debug
#define DEFAULT_ATTR_INITIALIZER \
{ \
{ \
.initialized = true, .detach_state = PTHREAD_CREATE_JOINABLE, \
.guard_size = 0, .inherit_sched = PTHREAD_INHERIT_SCHED, \
.scope = PTHREAD_SCOPE_PROCESS, .sched_param = (struct sched_param){}, \
.sched_policy = SCHED_OTHER, .stack_addr = NULL, .stack_size = 1 << 20, \
} \
}
static const union pthread_attr_t default_attr = DEFAULT_ATTR_INITIALIZER;
#define MAIN_ID 0
static struct pthread_fiber main_thread = {
.id = MAIN_ID,
.state = RUNNING,
.attr = DEFAULT_ATTR_INITIALIZER,
.cancel_state = PTHREAD_CANCEL_ENABLE,
.cancel_type = PTHREAD_CANCEL_DEFERRED,
.sched_policy = SCHED_OTHER,
.list_index = {-1, -1},
};
static pthread_t current = &main_thread;
static const pthread_condattr_t pthread_condattr_default = {
.pshared = PTHREAD_PROCESS_PRIVATE,
.initialized = true,
.clock_id = CLOCK_MONOTONIC,
};
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
debug("pthread_cond_init - c implementation\n");
return 0;
}
int pthread_cond_destroy(pthread_cond_t *cond) {
debug("pthread_cond_destroy - c implementation\n");
return 0;
}
int pthread_cond_signal(pthread_cond_t *cond) {
debug("pthread_cond_signal - c implementation\n");
return 0;
}
int pthread_condattr_init(pthread_condattr_t *attr) {
debug("pthread_condattr_init - c implementation\n");
*attr = pthread_condattr_default;
return 0;
}
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id) {
debug("pthread_condattr_setclock - c implementation\n");
attr->clock_id = clock_id;
return 0;
}
#define SIZE 1000
static void *values[SIZE];
static pthread_key_t keys[SIZE];
static int nkeys = 0;
void *pthread_getspecific(pthread_key_t key) {
debug("pthread_getspecific - key=%d\n", key.id);
for (int i = 0; i < nkeys; i++) {
if (keys[i].id == key.id) {
debug("pthread_getspecific - return value=%p\n", values[i]);
return values[i];
}
}
return 0;
}
int pthread_setspecific(pthread_key_t key, const void *value) {
debug("pthread_setspecific - c implementation, key=%d, value=%p\n", key.id,
value);
for (int i = 0; i < nkeys; i++) {
if (keys[i].id == key.id) {
debug("pthread_setspecific - changing key number %d\n", i);
values[i] = value;
return 0;
}
}
nkeys += 1;
debug("pthread_setspecific; added a new key so now there are %d\n", nkeys);
if (nkeys >= SIZE) {
printf("BOOM! ran out of pthread keys!");
}
keys[nkeys - 1] = key;
values[nkeys - 1] = value;
return 0;
}
int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)) {
debug("pthread_key_create - c implementation\n");
size_t id;
static size_t next_key_id = 1;
id = next_key_id++;
*key = (pthread_key_t){
.id = id,
.destructor = destructor,
.initialized = true,
};
return 0;
}
int pthread_key_delete(pthread_key_t key) {
debug("pthread_key_delete - c implementation\n");
return 0;
}
int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr) {
debug("pthread_mutex_init - c implementation\n");
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t *mutex) {
debug("pthread_mutex_init - c implementation\n");
return 0;
}
int pthread_mutex_lock(pthread_mutex_t *mutex) {
return 0;
}
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
return 0;
}
int pthread_mutex_trylock(pthread_mutex_t *mutex) {
return 0;
}
pthread_t pthread_self() {
debug("pthread_self - c implementation\n");
return current;
}
int pthread_attr_init(union pthread_attr_t *attr) {
debug("pthread_attr_init\n");
return 0;
}
int pthread_attr_destroy(union pthread_attr_t *attr) {
debug("pthread_attr_destroy\n");
return 0;
}
int pthread_attr_setstacksize(union pthread_attr_t *attr, size_t stacksize) {
debug("pthread_attr_setstacksize\n");
attr->data.stack_size = stacksize;
return 0;
}
int pthread_attr_getstacksize(const union pthread_attr_t *attr,
size_t *stacksize) {
debug("pthread_attr_getstacksize\n");
*stacksize = attr->data.stack_size;
return 0;
}
int pthread_create(pthread_t *thread, const union pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
fprintf(stderr,
"pthread_create: creation of threads is not yet implemented.\n");
return -1;
}
int pthread_detach(pthread_t thread) {
debug("pthread_detach\n");
return 0;
}
void pthread_exit(void *retval) { debug("pthread_exit\n"); }
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) {
return 0;
}
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
return 0;
}
int pthread_kill(pthread_t thread, int sig) { return 0; }
int pthread_getcpuclockid(pthread_t thread, clockid_t *clockid) {
*clockid = (clockid_t) CLOCK_THREAD_CPUTIME_ID;
return 0;
}