kernel - Refactor the lwkt_token code, making it faster
[dragonfly.git] / sys / sys / thread.h
index 6be7d18..18baa57 100644 (file)
@@ -31,6 +31,9 @@
 #ifndef _SYS_SPINLOCK_H_
 #include <sys/spinlock.h>
 #endif
+#ifndef _SYS_IOSCHED_H_
+#include <sys/iosched.h>
+#endif
 #ifndef _MACHINE_THREAD_H_
 #include <machine/thread.h>
 #endif
@@ -95,54 +98,26 @@ struct intrframe;
  * Tokens are managed through a helper reference structure, lwkt_tokref,
  * which is typically declared on the caller's stack.  Multiple tokref's
  * may reference the same token.
- *
- * It is possible to detect that your token was temporarily lost via
- * lwkt_token_is_stale(), which uses the t_lastowner field.  This field
- * does NOT necessarily represent the current owner and can become stale
- * (not point to a valid structure).  It is used solely to detect
- * whether the token was temporarily lost to another thread.  The lost
- * state is cleared by the function.
  */
 
 typedef struct lwkt_token {
-#ifdef SMP
-    struct spinlock    t_spinlock;     /* Controls access */
-#else
-    struct spinlock    t_unused01;
-#endif
-    struct thread      *t_owner;       /* The current owner of the token */
-    int                        t_count;        /* Per-thread count */
-    struct thread       *t_lastowner;  /* Last owner that acquired token */ 
+    struct lwkt_tokref *t_ref;         /* Owning ref or NULL */
 } lwkt_token;
 
-#ifdef SMP
-#define LWKT_TOKEN_INITIALIZER(head) \
-{ \
-       .t_spinlock = SPINLOCK_INITIALIZER(head.t_spinlock), \
-       .t_owner = NULL, \
-       .t_lastowner = NULL, \
-       .t_count = 0 \
+#define LWKT_TOKEN_INITIALIZER(head)   \
+{                                      \
+       .t_ref = NULL                   \
 }
-#else
-#define LWKT_TOKEN_INITIALIZER(head) \
-{ \
-       .t_owner = NULL, \
-       .t_lastowner = NULL, \
-       .t_count = 0 \
-}
-#endif
+
+#define ASSERT_LWKT_TOKEN_HELD(tok) \
+       KKASSERT((tok)->t_ref->tr_owner == curthread)
 
 typedef struct lwkt_tokref {
     lwkt_token_t       tr_tok;         /* token in question */
+    struct thread      *tr_owner;      /* me */
     lwkt_tokref_t      tr_next;        /* linked list */
-    int                        tr_state;       /* 0 = don't have, 1 = have */
 } lwkt_tokref;
 
-#define LWKT_TOKREF_INIT(tok)          \
-                       { tok, NULL, 0 }
-#define LWKT_TOKREF_DECLARE(name, tok) \
-                       lwkt_tokref name = LWKT_TOKREF_INIT(tok)
-
 #define MAXCPUFIFO      16     /* power of 2 */
 #define MAXCPUFIFO_MASK        (MAXCPUFIFO - 1)
 #define LWKT_MAXTOKENS 16      /* max tokens beneficially held by thread */
@@ -205,6 +180,11 @@ typedef struct lwkt_cpu_msg {
  *
  * NOTE: td_pri is bumped by TDPRI_CRIT when entering a critical section,
  * but this does not effect how the thread is scheduled by LWKT.
+ *
+ * NOTE: td_ucred is synchronized from the p_ucred on user->kernel syscall,
+ *      trap, and AST/signal transitions to provide a stable ucred for
+ *      (primarily) system calls.  This field will be NULL for pure kernel
+ *      threads.
  */
 struct md_intr_info;
 struct caps_kinfo;
@@ -212,6 +192,7 @@ struct caps_kinfo;
 struct thread {
     TAILQ_ENTRY(thread) td_threadq;
     TAILQ_ENTRY(thread) td_allq;
+    TAILQ_ENTRY(thread) td_sleepq;
     lwkt_port  td_msgport;     /* built-in message port for replies */
     struct lwp *td_lwp;        /* (optional) associated lwp */
     struct proc        *td_proc;       /* (optional) associated process */
@@ -242,9 +223,11 @@ struct thread {
     int                td_mpcount_unused;      /* filler so size matches */
     int                td_cscount_unused;
 #endif
+    struct iosched_data td_iosdata;    /* Dynamic I/O scheduling data */
     struct timeval td_start;   /* start time for a thread/process */
     char       td_comm[MAXCOMLEN+1]; /* typ 16+1 bytes */
     struct thread *td_preempted; /* we preempted this thread */
+    struct ucred *td_ucred;            /* synchronized from p_ucred */
     struct caps_kinfo *td_caps;        /* list of client and server registrations */
     lwkt_tokref_t td_toks;     /* tokens beneficially held */
 #ifdef DEBUG_CRIT_SECTIONS
@@ -292,7 +275,7 @@ struct thread {
 #define TDF_WAKEREQ            0x4000  /* resume_kproc */
 #define TDF_TIMEOUT            0x8000  /* tsleep timeout */
 #define TDF_INTTHREAD          0x00010000      /* interrupt thread */
-#define TDF_UNUSED20000                0x00020000
+#define TDF_TSLEEP_DESCHEDULED 0x00020000      /* tsleep core deschedule */
 #define TDF_BLOCKED            0x00040000      /* Thread is blocked */
 #define TDF_PANICWARN          0x00080000      /* panic warning in switch */
 #define TDF_BLOCKQ             0x00100000      /* on block queue */
@@ -355,7 +338,6 @@ extern void lwkt_schedule_self(thread_t);
 extern void lwkt_deschedule(thread_t);
 extern void lwkt_deschedule_self(thread_t);
 extern void lwkt_yield(void);
-extern void lwkt_yield_quick(void);
 extern void lwkt_user_yield(void);
 extern void lwkt_token_wait(void);
 extern void lwkt_hold(thread_t);
@@ -372,12 +354,13 @@ extern void lwkt_relalltokens(thread_t);
 extern void lwkt_drain_token_requests(void);
 extern void lwkt_token_init(lwkt_token_t);
 extern void lwkt_token_uninit(lwkt_token_t);
-extern int  lwkt_token_is_stale(lwkt_tokref_t);
 
 extern void lwkt_token_pool_init(void);
-extern lwkt_token_t lwkt_token_pool_get(void *);
+extern lwkt_token_t lwkt_token_pool_lookup(void *);
+extern void lwkt_getpooltoken(lwkt_tokref_t, void *);
 
 extern void lwkt_setpri(thread_t, int);
+extern void lwkt_setpri_initial(thread_t, int);
 extern void lwkt_setpri_self(int);
 extern int lwkt_check_resched(thread_t);
 extern void lwkt_setcpu_self(struct globaldata *);
@@ -418,8 +401,6 @@ extern int  lwkt_create (void (*func)(void *), void *, struct thread **,
                         struct thread *, int, int, const char *, ...);
 extern void lwkt_exit (void) __dead2;
 extern void lwkt_remove_tdallq (struct thread *);
-extern void lwkt_mp_lock_contested(void);
-extern void lwkt_mp_lock_uncontested(void);
 
 #endif