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