LCOV - code coverage report
Current view: top level - kern - kern_kthread.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 37 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: kern_kthread.c,v 1.42 2018/07/05 14:42:30 visa Exp $  */
       2             : /*      $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $  */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      10             :  * NASA Ames Research Center.
      11             :  *
      12             :  * Redistribution and use in source and binary forms, with or without
      13             :  * modification, are permitted provided that the following conditions
      14             :  * are met:
      15             :  * 1. Redistributions of source code must retain the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer.
      17             :  * 2. Redistributions in binary form must reproduce the above copyright
      18             :  *    notice, this list of conditions and the following disclaimer in the
      19             :  *    documentation and/or other materials provided with the distribution.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      22             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      23             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      24             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      25             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      26             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      27             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      29             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      31             :  * POSSIBILITY OF SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include <sys/param.h>
      35             : #include <sys/systm.h>
      36             : #include <sys/kthread.h>
      37             : #include <sys/proc.h>
      38             : #include <sys/wait.h>
      39             : #include <sys/malloc.h>
      40             : #include <sys/queue.h>
      41             : 
      42             : 
      43             : /*
      44             :  * note that stdarg.h and the ansi style va_start macro is used for both
      45             :  * ansi and traditional c compilers.
      46             :  * XXX: this requires that stdarg.h define: va_alist and va_dcl
      47             :  */
      48             : #include <sys/stdarg.h>
      49             : 
      50             : int     kthread_create_now;
      51             : 
      52             : /*
      53             :  * Fork a kernel thread.  Any process can request this to be done.
      54             :  * The VM space and limits, etc. will be shared with proc0.
      55             :  */
      56             : int
      57           0 : kthread_create(void (*func)(void *), void *arg,
      58             :     struct proc **newpp, const char *name)
      59             : {
      60           0 :         struct proc *p;
      61             :         int error;
      62             : 
      63           0 :         KERNEL_LOCK();
      64             : 
      65             :         /*
      66             :          * First, create the new process.  Share the memory, file
      67             :          * descriptors and don't leave the exit status around for the
      68             :          * parent to wait for.
      69             :          */
      70           0 :         error = fork1(&proc0, FORK_SHAREVM|FORK_SHAREFILES|FORK_NOZOMBIE|
      71             :             FORK_SYSTEM|FORK_SIGHAND, func, arg, NULL, &p);
      72           0 :         if (error) {
      73           0 :                 KERNEL_UNLOCK();
      74           0 :                 return (error);
      75             :         }
      76             : 
      77             :         /* Name it as specified. */
      78           0 :         strlcpy(p->p_p->ps_comm, name, sizeof p->p_p->ps_comm);
      79             : 
      80           0 :         KERNEL_UNLOCK();
      81             : 
      82             :         /* All done! */
      83           0 :         if (newpp != NULL)
      84           0 :                 *newpp = p;
      85           0 :         return (0);
      86           0 : }
      87             : 
      88             : /*
      89             :  * Cause a kernel thread to exit.  Assumes the exiting thread is the
      90             :  * current context.
      91             :  */
      92             : void
      93           0 : kthread_exit(int ecode)
      94             : {
      95             : 
      96             :         /*
      97             :          * XXX What do we do with the exit code?  Should we even bother
      98             :          * XXX with it?  The parent (proc0) isn't going to do much with
      99             :          * XXX it.
     100             :          */
     101           0 :         if (ecode != 0)
     102           0 :                 printf("WARNING: thread `%s' (%d) exits with status %d\n",
     103           0 :                     curproc->p_p->ps_comm, curproc->p_tid, ecode);
     104             : 
     105           0 :         exit1(curproc, W_EXITCODE(ecode, 0), EXIT_NORMAL);
     106             : 
     107             :         /*
     108             :          * XXX Fool the compiler.  Making exit1() __dead is a can
     109             :          * XXX of worms right now.
     110             :          */
     111           0 :         for (;;);
     112             : }
     113             : 
     114             : struct kthread_q {
     115             :         SIMPLEQ_ENTRY(kthread_q) kq_q;
     116             :         void (*kq_func)(void *);
     117             :         void *kq_arg;
     118             : };
     119             : 
     120             : SIMPLEQ_HEAD(, kthread_q) kthread_q = SIMPLEQ_HEAD_INITIALIZER(kthread_q);
     121             : 
     122             : /*
     123             :  * Defer the creation of a kernel thread.  Once the standard kernel threads
     124             :  * and processes have been created, this queue will be run to callback to
     125             :  * the caller to create threads for e.g. file systems and device drivers.
     126             :  */
     127             : void
     128           0 : kthread_create_deferred(void (*func)(void *), void *arg)
     129             : {
     130             :         struct kthread_q *kq;
     131             : 
     132           0 :         if (kthread_create_now) {
     133           0 :                 (*func)(arg);
     134           0 :                 return;
     135             :         }
     136             : 
     137           0 :         kq = malloc(sizeof *kq, M_TEMP, M_NOWAIT|M_ZERO);
     138           0 :         if (kq == NULL)
     139           0 :                 panic("unable to allocate kthread_q");
     140             : 
     141           0 :         kq->kq_func = func;
     142           0 :         kq->kq_arg = arg;
     143             : 
     144           0 :         SIMPLEQ_INSERT_TAIL(&kthread_q, kq, kq_q);
     145           0 : }
     146             : 
     147             : void
     148           0 : kthread_run_deferred_queue(void)
     149             : {
     150             :         struct kthread_q *kq;
     151             : 
     152             :         /* No longer need to defer kthread creation. */
     153           0 :         kthread_create_now = 1;
     154             : 
     155           0 :         while ((kq = SIMPLEQ_FIRST(&kthread_q)) != NULL) {
     156           0 :                 SIMPLEQ_REMOVE_HEAD(&kthread_q, kq_q);
     157           0 :                 (*kq->kq_func)(kq->kq_arg);
     158           0 :                 free(kq, M_TEMP, sizeof(*kq));
     159             :         }
     160           0 : }

Generated by: LCOV version 1.13