Fixed bug in pthread barrier code
[akaros.git] / user / include / pthread.h
index f9136e2..3690aef 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _PTHREAD_H
 #define _PTHREAD_H
 
+#include <sys/queue.h>
 #include <vcore.h>
 #include <mcs.h>
 
@@ -8,7 +9,30 @@
   extern "C" {
 #endif
 
-/* Detach state.  */
+/* Our internal types for pthread management */
+struct pthread_tcb {
+       TAILQ_ENTRY(pthread_tcb) next;
+       void* (*start_routine)(void*);
+       void* arg;
+
+       struct user_trapframe utf;
+       struct ancillary_state as;
+       void *tls_desc;
+       void *stacktop;
+       uint32_t id;
+
+       int finished;
+       void *retval;
+       int detached;
+       // whether or not the scheduler can migrate you from your vcore
+       // will be slightly difficult to see this when given just a vcoreid and
+       // notif_tf ptr
+       bool dont_migrate;
+};
+typedef struct pthread_tcb* pthread_t;
+TAILQ_HEAD(pthread_queue, pthread_tcb);
+
+/* For compatibility with the existing pthread library */
 enum
 {
   PTHREAD_CREATE_JOINABLE,
@@ -17,14 +41,15 @@ enum
 #define PTHREAD_CREATE_DETACHED        PTHREAD_CREATE_DETACHED
 };
 
-struct pthread_wqt
-{
-  void* (*start_routine)(void*);
-  void* arg;
-  int finished;
-  int detached;
-  struct pthread_wqt* next;
-};
+#define PTHREAD_ONCE_INIT 0
+#define PTHREAD_BARRIER_SERIAL_THREAD 12345
+#define PTHREAD_MUTEX_INITIALIZER {0}
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
+#define PTHREAD_MUTEX_SPINS 100 // totally arbitrary
+#define PTHREAD_BARRIER_SPINS 100 // totally arbitrary
+#define PTHREAD_COND_INITIALIZER {0}
+#define PTHREAD_PROCESS_PRIVATE 0
 
 typedef struct
 {
@@ -37,46 +62,51 @@ typedef struct
   int lock;
 } pthread_mutex_t;
 
+/* TODO: MAX_PTHREADS is arbitrarily defined for now.
+ * It indicates the maximum number of threads that can wait on  
+   the same cond var/ barrier concurrently. */
+
+#define MAX_PTHREADS 32
 typedef struct
 {
-  int local_sense[32*MAX_VCORES];
+  int in_use[MAX_PTHREADS];
+  int next_slot;
   volatile int sense;
   int count;
   int nprocs;
-  mcs_lock_t lock;
+  pthread_mutex_t pmutex;
 } pthread_barrier_t;
 
+#define WAITER_CLEARED 0
+#define WAITER_WAITING 1
+#define SLOT_FREE 0
+#define SLOT_IN_USE 1
 typedef struct
 {
   int pshared;
 } pthread_condattr_t;
 
+
 typedef struct
 {
   const pthread_condattr_t* attr;
-  int waiters[MAX_VCORES];
+  int waiters[MAX_PTHREADS];
+  int in_use[MAX_PTHREADS];
+  int next_waiter; //start the search for an available waiter at this spot
 } pthread_cond_t;
 
-typedef struct pthread_wqt work_queue_t;
-typedef work_queue_t* pthread_t;
 typedef int pthread_attr_t;
 typedef int pthread_barrierattr_t;
 typedef int pthread_once_t;
 typedef void** pthread_key_t;
 
-#define PTHREAD_ONCE_INIT 0
-#define PTHREAD_BARRIER_SERIAL_THREAD 12345
-#define PTHREAD_MUTEX_INITIALIZER {0}
-#define PTHREAD_MUTEX_NORMAL 0
-#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
-#define PTHREAD_COND_INITIALIZER {0}
-#define PTHREAD_PROCESS_PRIVATE 0
-
+/* The pthreads API */
 int pthread_attr_init(pthread_attr_t *);
 int pthread_attr_destroy(pthread_attr_t *);
 int pthread_create(pthread_t *, const pthread_attr_t *,
                    void *(*)(void *), void *);
 int pthread_join(pthread_t, void **);
+int pthread_yield(void);
 
 int pthread_attr_setdetachstate(pthread_attr_t *__attr,int __detachstate);