akaros/user/pthread/pthread.h
<<
>>
Prefs
   1#pragma once
   2
   3#include <sys/queue.h>
   4#include <signal.h>
   5#include <parlib/vcore.h>
   6#include <parlib/uthread.h>
   7#include <parlib/mcs.h>
   8#include <parlib/dtls.h>
   9#include <parlib/spinlock.h>
  10#include <parlib/signal.h>
  11#include <parlib/parlib.h>
  12/* GNU / POSIX scheduling crap */
  13#include <sched.h>
  14
  15__BEGIN_DECLS
  16
  17/* Pthread states.  These are mostly examples for other 2LSs */
  18#define PTH_CREATED             1
  19#define PTH_RUNNABLE            2
  20#define PTH_RUNNING             3
  21#define PTH_EXITING             4
  22#define PTH_BLK_YIELDING        5       /* btw pth_yield and pth_runnable */
  23#define PTH_BLK_SYSC            6       /* blocked on a syscall */
  24#define PTH_BLK_MUTEX           7       /* blocked externally */
  25#define PTH_BLK_PAUSED          8       /* handed back from uthread code */
  26#define PTH_BLK_MISC            9       /* catch-all from uthread code */
  27
  28/* Entry for a pthread_cleanup_routine on the stack of cleanup handlers. */
  29struct pthread_cleanup_routine {
  30        SLIST_ENTRY(pthread_cleanup_routine) cr_next;
  31        void (*routine)(void *);
  32        void *arg;
  33};
  34SLIST_HEAD(pthread_cleanup_stack, pthread_cleanup_routine);
  35
  36/* Pthread struct.  First has to be the uthread struct, which the vcore code
  37 * will access directly (as if pthread_tcb is a struct uthread). */
  38struct pthread_tcb;
  39struct pthread_tcb {
  40        struct uthread uthread;
  41        TAILQ_ENTRY(pthread_tcb) tq_next;
  42        int state;
  43        uint32_t id;
  44        uint64_t fork_generation;
  45        uint32_t stacksize;
  46        void *stacktop;
  47        void *(*start_routine)(void*);
  48        void *arg;
  49        struct pthread_cleanup_stack cr_stack;
  50};
  51typedef struct pthread_tcb* pthread_t;
  52TAILQ_HEAD(pthread_queue, pthread_tcb);
  53
  54/* Per-vcore data structures to manage syscalls.  The ev_q is where we tell the
  55 * kernel to signal us.  We don't need a lock since this is per-vcore and
  56 * accessed in vcore context. */
  57struct sysc_mgmt {
  58        struct event_queue              *ev_q;
  59};
  60
  61#define PTHREAD_ONCE_INIT PARLIB_ONCE_INIT
  62#define PTHREAD_BARRIER_SERIAL_THREAD 12345
  63#define PTHREAD_BARRIER_SPINS 100 // totally arbitrary
  64#define PTHREAD_PROCESS_PRIVATE 0
  65#define PTHREAD_PROCESS_SHARED 1
  66
  67#define PTHREAD_MUTEX_NORMAL 0
  68#define PTHREAD_MUTEX_RECURSIVE 1
  69#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
  70typedef struct {
  71        int type;
  72} pthread_mutexattr_t;
  73
  74typedef struct {
  75        int                             type;
  76        uth_mutex_t                     mtx;
  77        uth_recurse_mutex_t             r_mtx;
  78} pthread_mutex_t;
  79#define PTHREAD_MUTEX_INITIALIZER { PTHREAD_MUTEX_DEFAULT, UTH_MUTEX_INIT, \
  80                                    UTH_RECURSE_MUTEX_INIT }
  81
  82typedef int clockid_t;
  83typedef struct {
  84        int                             pshared;
  85        clockid_t                       clock;
  86} pthread_condattr_t;
  87#define PTHREAD_COND_INITIALIZER UTH_COND_VAR_INIT
  88
  89/* Regarding the spinlock vs MCS, I don't expect this lock to be heavily
  90 * contended.  Most of the time, the caller already holds the mutex associated
  91 * with the cond var. */
  92typedef uth_cond_var_t pthread_cond_t;
  93
  94typedef uth_rwlock_t pthread_rwlock_t;
  95#define PTHREAD_RWLOCK_INITIALIZER UTH_RWLOCK_INIT
  96/* Will try to avoid the rwlockattr_t business for now */
  97typedef void * pthread_rwlockattr_t;
  98
  99typedef struct
 100{
 101        int                             total_threads;
 102        /* state of barrier, flips btw runs */
 103        volatile int                    sense;
 104        atomic_t                        count;
 105        struct spin_pdr_lock            lock;
 106        uth_sync_t                      waiters;
 107        int                             nr_waiters;
 108} pthread_barrier_t;
 109
 110/* Detach state.  */
 111enum
 112{
 113  PTHREAD_CREATE_JOINABLE,
 114#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
 115  PTHREAD_CREATE_DETACHED
 116#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
 117};
 118
 119#define PTHREAD_STACK_PAGES 1024
 120#define PTHREAD_STACK_SIZE (PTHREAD_STACK_PAGES*PGSIZE)
 121#define PTHREAD_STACK_MIN PTHREAD_STACK_SIZE
 122
 123typedef struct 
 124{
 125        void *stackaddr;
 126        size_t stacksize;
 127        size_t guardsize;
 128        int detachstate;
 129        int sched_priority;
 130        int sched_policy;
 131        int sched_inherit;
 132} pthread_attr_t;
 133typedef int pthread_barrierattr_t;
 134typedef parlib_once_t pthread_once_t;
 135typedef dtls_key_t pthread_key_t;
 136
 137/* Akaros pthread extensions / hacks */
 138void pthread_need_tls(bool need);                       /* default is TRUE */
 139void pthread_mcp_init(void);
 140void __pthread_generic_yield(struct pthread_tcb *pthread);
 141
 142/* Profiling alarms for pthreads.  (profalarm.c) */
 143void enable_profalarm(uint64_t usecs);
 144void disable_profalarm(void);
 145
 146/* The pthreads API */
 147int pthread_attr_init(pthread_attr_t *);
 148int pthread_attr_destroy(pthread_attr_t *);
 149int __pthread_create(pthread_t *, const pthread_attr_t *,
 150                     void *(*)(void *), void *);
 151int pthread_create(pthread_t *, const pthread_attr_t *,
 152                   void *(*)(void *), void *);
 153int pthread_detach(pthread_t __th);
 154int pthread_join(pthread_t, void **);
 155int pthread_yield(void);
 156
 157int pthread_attr_setdetachstate(pthread_attr_t *__attr,int __detachstate);
 158int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
 159int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
 160int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
 161int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
 162
 163int pthread_mutex_destroy(pthread_mutex_t *);
 164int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
 165int pthread_mutex_lock(pthread_mutex_t *);
 166int pthread_mutex_trylock(pthread_mutex_t *);
 167int pthread_mutex_unlock(pthread_mutex_t *);
 168int pthread_mutex_destroy(pthread_mutex_t *);
 169
 170int pthread_mutexattr_init(pthread_mutexattr_t *);
 171int pthread_mutexattr_destroy(pthread_mutexattr_t *);
 172int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *);
 173int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
 174
 175int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
 176int pthread_cond_destroy(pthread_cond_t *);
 177int pthread_cond_broadcast(pthread_cond_t *);
 178int pthread_cond_signal(pthread_cond_t *);
 179int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
 180
 181int pthread_condattr_init(pthread_condattr_t *);
 182int pthread_condattr_destroy(pthread_condattr_t *);
 183int pthread_condattr_getpshared(pthread_condattr_t *, int *);
 184int pthread_condattr_setpshared(pthread_condattr_t *, int);
 185int pthread_condattr_getclock(const pthread_condattr_t *attr,
 186                              clockid_t *clock_id);
 187int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id);
 188
 189int pthread_rwlock_init(pthread_rwlock_t *rwl, const pthread_rwlockattr_t *a);
 190int pthread_rwlock_destroy(pthread_rwlock_t *rwl);
 191int pthread_rwlock_rdlock(pthread_rwlock_t *rwl);
 192int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwl);
 193int pthread_rwlock_wrlock(pthread_rwlock_t *rwl);
 194int pthread_rwlock_trywrlock(pthread_rwlock_t *rwl);
 195int pthread_rwlock_unlock(pthread_rwlock_t *rwl);
 196
 197pthread_t pthread_self();
 198int pthread_equal(pthread_t t1, pthread_t t2);
 199void pthread_exit(void* ret);
 200int pthread_once(pthread_once_t* once_control, void (*init_routine)(void));
 201
 202int pthread_barrier_init(pthread_barrier_t* b, const pthread_barrierattr_t* a, int count);
 203int pthread_barrier_wait(pthread_barrier_t* b);
 204int pthread_barrier_destroy(pthread_barrier_t* b);
 205
 206// POSIX signal compliance
 207int pthread_kill (pthread_t __threadid, int __signo);
 208int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
 209int pthread_sigqueue(pthread_t *thread, int sig, const union sigval value);
 210
 211// Dynamic TLS stuff
 212int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
 213int pthread_key_delete(pthread_key_t key);
 214void *pthread_getspecific(pthread_key_t key);
 215int pthread_setspecific(pthread_key_t key, const void *value);
 216
 217/* Common stuff. */
 218int pthread_equal(pthread_t __thread1, pthread_t __thread2);
 219int pthread_getattr_np(pthread_t __th, pthread_attr_t *__attr);
 220int pthread_attr_getstack(const pthread_attr_t *__attr,
 221                           void **__stackaddr, size_t *__stacksize);
 222int pthread_cancel(pthread_t __th);
 223void pthread_cleanup_push(void (*routine)(void *), void *arg);
 224void pthread_cleanup_pop(int execute);
 225
 226/* Scheduling Stuff, mostly ignored by the actual 2LS */
 227int pthread_attr_setschedparam(pthread_attr_t *attr,
 228                               const struct sched_param *param);
 229int pthread_attr_getschedparam(pthread_attr_t *attr,
 230                               struct sched_param *param);
 231/* Policies are from sched.h. */
 232int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
 233int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);
 234
 235#define PTHREAD_SCOPE_SYSTEM    1
 236#define PTHREAD_SCOPE_PROCESS   2
 237int pthread_attr_setscope(pthread_attr_t *attr, int scope);
 238int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
 239
 240#define PTHREAD_INHERIT_SCHED   1
 241#define PTHREAD_EXPLICIT_SCHED  2
 242int pthread_attr_setinheritsched(pthread_attr_t *attr,
 243                                 int inheritsched);
 244int pthread_attr_getinheritsched(const pthread_attr_t *attr,
 245                                 int *inheritsched);
 246
 247int pthread_setschedparam(pthread_t thread, int policy,
 248                          const struct sched_param *param);
 249int pthread_getschedparam(pthread_t thread, int *policy,
 250                          struct sched_param *param);
 251
 252/* Unsupported Stuff */
 253extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
 254                    const struct timespec *__restrict
 255                    __abstime) __THROWNL __nonnull ((1, 2));
 256extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
 257                   pthread_mutex_t *__restrict __mutex,
 258                   const struct timespec *__restrict __abstime)
 259     __nonnull ((1, 2, 3));
 260
 261__END_DECLS
 262