The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_kthread.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1999 Peter Wemm <peter@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: src/sys/kern/kern_kthread.c,v 1.5.2.3 2001/12/25 01:51:14 dillon Exp $
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/proc.h>
   32 #include <sys/kthread.h>
   33 #include <sys/ptrace.h>
   34 #include <sys/resourcevar.h>
   35 #include <sys/signalvar.h>
   36 #include <sys/unistd.h>
   37 #include <sys/wait.h>
   38 
   39 #include <machine/stdarg.h>
   40 
   41 static struct lwkt_token kpsus_token = LWKT_TOKEN_INITIALIZER(kpsus_token);
   42 
   43 
   44 /*
   45  * Create a new lightweight kernel thread.
   46  */
   47 static int
   48 _kthread_create(void (*func)(void *), void *arg,
   49     struct thread **tdp, int cpu, const char *fmt, __va_list ap)
   50 {
   51     thread_t td;
   52     int flags = 0;
   53 
   54     if (bootverbose)
   55         atomic_set_int(&flags, TDF_VERBOSE);
   56 
   57     td = lwkt_alloc_thread(NULL, LWKT_THREAD_STACK, cpu, flags);
   58     if (tdp)
   59         *tdp = td;
   60     cpu_set_thread_handler(td, kthread_exit, func, arg);
   61 
   62     /*
   63      * Set up arg0 for 'ps' etc
   64      */
   65     kvsnprintf(td->td_comm, sizeof(td->td_comm), fmt, ap);
   66 
   67     td->td_ucred = crhold(proc0.p_ucred);
   68 
   69     /*
   70      * Schedule the thread to run
   71      */
   72     lwkt_schedule(td);
   73 
   74     return 0;
   75 }
   76 
   77 /*
   78  * Creates a lwkt. No CPU preference.
   79  */
   80 int
   81 kthread_create(void (*func)(void *), void *arg,
   82                struct thread **tdp, const char *fmt, ...)
   83 {
   84         __va_list ap;
   85         int ret;
   86 
   87         __va_start(ap, fmt);
   88         ret = _kthread_create(func, arg, tdp, -1, fmt, ap);
   89         __va_end(ap);
   90 
   91         return ret;
   92 }
   93 
   94 /*
   95  * Creates a lwkt and schedule it to run in a specific CPU.
   96  *
   97  */
   98 int
   99 kthread_create_cpu(void (*func)(void *), void *arg,
  100                    struct thread **tdp, int cpu, const char *fmt, ...)
  101 {
  102         __va_list ap;
  103         int ret;
  104 
  105         __va_start(ap, fmt);
  106         ret = _kthread_create(func, arg, tdp, cpu, fmt, ap);
  107         __va_end(ap);
  108 
  109         return ret;
  110 }
  111 
  112 #if 0
  113 /*
  114  * Same as kthread_create() but you can specify a custom stack size.
  115  */
  116 int
  117 kthread_create_stk(void (*func)(void *), void *arg,
  118                    struct thread **tdp, int stksize, const char *fmt, ...)
  119 {
  120     thread_t td;
  121     __va_list ap;
  122 
  123     td = lwkt_alloc_thread(NULL, stksize, -1, TDF_VERBOSE);
  124     if (tdp)
  125         *tdp = td;
  126     cpu_set_thread_handler(td, kthread_exit, func, arg);
  127 
  128     __va_start(ap, fmt);
  129     kvsnprintf(td->td_comm, sizeof(td->td_comm), fmt, ap);
  130     __va_end(ap);
  131 
  132     lwkt_schedule(td);
  133     return 0;
  134 }
  135 #endif
  136 
  137 /*
  138  * Destroy an LWKT thread.   Warning!  This function is not called when
  139  * a process exits, cpu_proc_exit() directly calls cpu_thread_exit() and
  140  * uses a different reaping mechanism.
  141  *
  142  * XXX duplicates lwkt_exit()
  143  */
  144 void
  145 kthread_exit(void)
  146 {
  147     lwkt_exit();
  148 }
  149 
  150 /*
  151  * Start a kernel process.  This is called after a fork() call in
  152  * mi_startup() in the file kern/init_main.c.
  153  *
  154  * This function is used to start "internal" daemons and intended
  155  * to be called from SYSINIT().
  156  *
  157  * These threads are created MPSAFE.
  158  */
  159 void
  160 kproc_start(const void *udata)
  161 {
  162         const struct kproc_desc *kp = udata;
  163         int error;
  164 
  165         error = kthread_create((void (*)(void *))kp->func, NULL,
  166                                 kp->global_threadpp, "%s", kp->arg0);
  167         lwkt_setpri(*kp->global_threadpp, TDPRI_KERN_DAEMON);
  168         if (error)
  169                 panic("kproc_start: %s: error %d", kp->arg0, error);
  170 }
  171 
  172 /*
  173  * Advise a kernel process to suspend (or resume) in its main loop.
  174  * Participation is voluntary.
  175  */
  176 int
  177 suspend_kproc(struct thread *td, int timo)
  178 {
  179         if (td->td_proc == NULL) {
  180                 lwkt_gettoken(&kpsus_token);
  181                 /* request thread pause */
  182                 atomic_set_int(&td->td_mpflags, TDF_MP_STOPREQ);
  183                 wakeup(td);
  184                 while (td->td_mpflags & TDF_MP_STOPREQ) {
  185                         int error = tsleep(td, 0, "suspkp", timo);
  186                         if (error == EWOULDBLOCK)
  187                                 break;
  188                 }
  189                 atomic_clear_int(&td->td_mpflags, TDF_MP_STOPREQ);
  190                 lwkt_reltoken(&kpsus_token);
  191                 return(0);
  192         } else {
  193                 return(EINVAL); /* not a kernel thread */
  194         }
  195 }
  196 
  197 void
  198 kproc_suspend_loop(void)
  199 {
  200         struct thread *td = curthread;
  201 
  202         if (td->td_mpflags & TDF_MP_STOPREQ) {
  203                 lwkt_gettoken(&kpsus_token);
  204                 atomic_clear_int(&td->td_mpflags, TDF_MP_STOPREQ);
  205                 while ((td->td_mpflags & TDF_MP_WAKEREQ) == 0) {
  206                         wakeup(td);
  207                         tsleep(td, 0, "kpsusp", 0);
  208                 }
  209                 atomic_clear_int(&td->td_mpflags, TDF_MP_WAKEREQ);
  210                 wakeup(td);
  211                 lwkt_reltoken(&kpsus_token);
  212         }
  213 }
  214 

Cache object: fa4497197d32076acb43b576b86b4a55


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.