1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _NSC_THREAD_H
  27 #define _NSC_THREAD_H
  28 
  29 #ifdef  __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 #ifdef _KERNEL
  34 
  35 #include <sys/ksynch.h>           /* for kmutex_t and kcondvar_t */
  36 
  37 /*
  38  * A simple way to marshal kthreads into sets for use by nsctl / nskern
  39  * clients.  The ns threads are created in user land by nskernd, and
  40  * then call into the nskern kernel module for allocation into sets.
  41  */
  42 
  43 struct nsthread;
  44 struct nstset;
  45 
  46 #ifndef _BLIND_T
  47 #define _BLIND_T
  48 typedef void * blind_t;
  49 #endif /* _BLIND_T */
  50 
  51 
  52 /*
  53  * Queue stuff that should really be in the DDI.
  54  */
  55 
  56 typedef struct nst_q {
  57         struct nst_q *q_forw;
  58         struct nst_q *q_back;
  59 } nst_q_t;
  60 
  61 
  62 /*
  63  * Per thread data structure.
  64  */
  65 
  66 typedef struct nsthread {
  67         nst_q_t         tp_link;        /* Doubly linked free list */
  68 
  69         struct nstset   *tp_set;        /* Set to which thread belongs */
  70         struct nsthread *tp_chain;      /* Link in chain of threads in set */
  71 
  72         kcondvar_t      tp_cv;          /* Suspend/resume synchronisation */
  73 
  74         /*
  75          * Everything past this point is cleared when the thread is
  76          * initialised for (re)use.
  77          */
  78 
  79         int             tp_flag;        /* State (below) */
  80 
  81         void            (*tp_func)();   /* First function */
  82         blind_t         tp_arg;         /* Argument to tp_func */
  83 } nsthread_t;
  84 
  85 /*
  86  * Flags for nst_init
  87  */
  88 #define NST_CREATE      0x1     /* Create resources to run thread */
  89 #define NST_SLEEP       0x2     /* Wait for resources to be available */
  90 
  91 /*
  92  * Thread state flags
  93  */
  94 #define NST_TF_INUSE            0x1     /* Thread currently in use */
  95 #define NST_TF_ACTIVE           0x2     /* Thread is being manipulated */
  96 #define NST_TF_PENDING          0x4     /* Thread is pending a create */
  97 #define NST_TF_DESTROY          0x8     /* Destroy thread when finished */
  98 #define NST_TF_KILL             0x10    /* Thread is being killed */
  99 
 100 /*
 101  * Thread set.
 102  */
 103 typedef struct nstset {
 104         struct nstset   *set_next;      /* Next set in list of sets */
 105 
 106         nsthread_t      *set_chain;     /* Chain of all threads in set */
 107         nst_q_t         set_reuse;      /* Chain of reusable threads */
 108         nst_q_t         set_free;       /* Chain of free threads */
 109 
 110         char            set_name[32];   /* Name associated with set */
 111 
 112         ushort_t        set_nlive;      /* No. of active threads */
 113         ushort_t        set_nthread;    /* No. of threads in set */
 114         int             set_flag;       /* State (below) */
 115         int             set_pending;    /* Operation is pending */
 116 
 117         kmutex_t        set_lock;       /* Mutex for chains and counts */
 118         kcondvar_t      set_kill_cv;    /* Kill synchronisation */
 119         kcondvar_t      set_destroy_cv; /* Shutdown synchronisation */
 120         volatile int    set_destroy_cnt; /* No. of waiters */
 121 
 122         kcondvar_t      set_res_cv;     /* Resource alloc synchronisation */
 123         int             set_res_cnt;    /* No. of waiters */
 124 } nstset_t;
 125 
 126 /*
 127  * Set state flags
 128  */
 129 #define NST_SF_KILL     1       /* Set is being killed */
 130 
 131 /*
 132  * General defines
 133  */
 134 #define NST_KILL_TIMEOUT        100000  /* usec to wait for threads to die */
 135 #define NST_MEMORY_TIMEOUT      500000  /* usec to wait for memory */
 136 
 137 /*
 138  * Function prototypes
 139  */
 140 
 141 int             nst_add_thread(nstset_t *, int);
 142 nsthread_t      *nst_create(nstset_t *, void (*)(), blind_t, int);
 143 int             nst_del_thread(nstset_t *, int);
 144 void            nst_destroy(nstset_t *);
 145 nstset_t        *nst_init(char *, int);
 146 int             nst_nlive(nstset_t *);
 147 int             nst_nthread(nstset_t *);
 148 int             nst_startup(void);
 149 void            nst_shutdown(void);
 150 
 151 #endif  /* _KERNEL */
 152 
 153 #ifdef  __cplusplus
 154 }
 155 #endif
 156 
 157 #endif  /* _NSC_THREAD_H */