1*62e84772Spooka /* $NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 pooka Exp $ */ 2c03306bcSpooka 3c03306bcSpooka /* 4c03306bcSpooka * Copyright (c) 2007-2009 Antti Kantee. All Rights Reserved. 5c03306bcSpooka * 6c03306bcSpooka * Development of this software was supported by 7c03306bcSpooka * The Finnish Cultural Foundation. 8c03306bcSpooka * 9c03306bcSpooka * Redistribution and use in source and binary forms, with or without 10c03306bcSpooka * modification, are permitted provided that the following conditions 11c03306bcSpooka * are met: 12c03306bcSpooka * 1. Redistributions of source code must retain the above copyright 13c03306bcSpooka * notice, this list of conditions and the following disclaimer. 14c03306bcSpooka * 2. Redistributions in binary form must reproduce the above copyright 15c03306bcSpooka * notice, this list of conditions and the following disclaimer in the 16c03306bcSpooka * documentation and/or other materials provided with the distribution. 17c03306bcSpooka * 18c03306bcSpooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19c03306bcSpooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20c03306bcSpooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21c03306bcSpooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22c03306bcSpooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23c03306bcSpooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24c03306bcSpooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25c03306bcSpooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26c03306bcSpooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27c03306bcSpooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28c03306bcSpooka * SUCH DAMAGE. 29c03306bcSpooka */ 30c03306bcSpooka 31c03306bcSpooka #include <sys/cdefs.h> 32*62e84772Spooka __KERNEL_RCSID(0, "$NetBSD: threads.c,v 1.4 2009/12/01 09:50:51 pooka Exp $"); 33c03306bcSpooka 34c03306bcSpooka #include <sys/param.h> 35c03306bcSpooka #include <sys/kmem.h> 36c03306bcSpooka #include <sys/kthread.h> 37c03306bcSpooka #include <sys/systm.h> 38c03306bcSpooka 39c03306bcSpooka #include <machine/stdarg.h> 40c03306bcSpooka 41c03306bcSpooka #include <rump/rumpuser.h> 42c03306bcSpooka 43c03306bcSpooka #include "rump_private.h" 44c03306bcSpooka 45c03306bcSpooka struct kthdesc { 46c03306bcSpooka void (*f)(void *); 47c03306bcSpooka void *arg; 48c03306bcSpooka struct lwp *mylwp; 49c03306bcSpooka }; 50c03306bcSpooka 51c03306bcSpooka static void * 52c03306bcSpooka threadbouncer(void *arg) 53c03306bcSpooka { 54c03306bcSpooka struct kthdesc *k = arg; 551029997fSpooka struct lwp *l = k->mylwp; 56c03306bcSpooka void (*f)(void *); 57c03306bcSpooka void *thrarg; 58c03306bcSpooka 59c03306bcSpooka f = k->f; 60c03306bcSpooka thrarg = k->arg; 611029997fSpooka rumpuser_free(k); 621029997fSpooka 6319cde6b5Spooka /* schedule ourselves */ 641029997fSpooka rumpuser_set_curlwp(l); 65c03306bcSpooka rump_schedule(); 66c03306bcSpooka 67c03306bcSpooka if ((curlwp->l_pflag & LP_MPSAFE) == 0) 68c03306bcSpooka KERNEL_LOCK(1, NULL); 69c03306bcSpooka 70c03306bcSpooka f(thrarg); 71c03306bcSpooka 72c03306bcSpooka panic("unreachable, should kthread_exit()"); 73c03306bcSpooka } 74c03306bcSpooka 75c03306bcSpooka int 76c03306bcSpooka kthread_create(pri_t pri, int flags, struct cpu_info *ci, 77c03306bcSpooka void (*func)(void *), void *arg, lwp_t **newlp, const char *fmt, ...) 78c03306bcSpooka { 79c03306bcSpooka char thrstore[MAXCOMLEN]; 80c03306bcSpooka const char *thrname = NULL; 81c03306bcSpooka va_list ap; 82c03306bcSpooka struct kthdesc *k; 83c03306bcSpooka struct lwp *l; 84c03306bcSpooka int rv; 85c03306bcSpooka 86c03306bcSpooka thrstore[0] = '\0'; 87c03306bcSpooka if (fmt) { 88c03306bcSpooka va_start(ap, fmt); 89c03306bcSpooka vsnprintf(thrstore, sizeof(thrstore), fmt, ap); 90c03306bcSpooka va_end(ap); 91c03306bcSpooka thrname = thrstore; 92c03306bcSpooka } 93c03306bcSpooka 94c03306bcSpooka /* 95c03306bcSpooka * We don't want a module unload thread. 96c03306bcSpooka * (XXX: yes, this is a kludge too, and the kernel should 97c03306bcSpooka * have a more flexible method for configuring which threads 98c03306bcSpooka * we want). 99c03306bcSpooka */ 100c03306bcSpooka if (strcmp(thrstore, "modunload") == 0) { 101c03306bcSpooka return 0; 102c03306bcSpooka } 103c03306bcSpooka 104c03306bcSpooka if (!rump_threads) { 105c03306bcSpooka /* fake them */ 106c03306bcSpooka if (strcmp(thrstore, "vrele") == 0) { 107c03306bcSpooka printf("rump warning: threads not enabled, not starting" 108c03306bcSpooka " vrele thread\n"); 109c03306bcSpooka return 0; 110c03306bcSpooka } else if (strcmp(thrstore, "cachegc") == 0) { 111c03306bcSpooka printf("rump warning: threads not enabled, not starting" 112c03306bcSpooka " namecache g/c thread\n"); 113c03306bcSpooka return 0; 114c03306bcSpooka } else if (strcmp(thrstore, "nfssilly") == 0) { 115c03306bcSpooka printf("rump warning: threads not enabled, not enabling" 116c03306bcSpooka " nfs silly rename\n"); 117c03306bcSpooka return 0; 118c03306bcSpooka } else if (strcmp(thrstore, "unpgc") == 0) { 119c03306bcSpooka printf("rump warning: threads not enabled, not enabling" 120c03306bcSpooka " UNP garbage collection\n"); 121c03306bcSpooka return 0; 122c03306bcSpooka } else 123c03306bcSpooka panic("threads not available, setenv RUMP_THREADS 1"); 124c03306bcSpooka } 125c03306bcSpooka KASSERT(fmt != NULL); 126c03306bcSpooka 1271029997fSpooka k = rumpuser_malloc(sizeof(struct kthdesc), 0); 128c03306bcSpooka k->f = func; 129c03306bcSpooka k->arg = arg; 130c03306bcSpooka k->mylwp = l = rump_lwp_alloc(0, rump_nextlid()); 131c03306bcSpooka if (flags & KTHREAD_MPSAFE) 132c03306bcSpooka l->l_pflag |= LP_MPSAFE; 1331029997fSpooka if (flags & KTHREAD_INTR) 1341029997fSpooka l->l_pflag |= LP_INTR; 135*62e84772Spooka if (ci) { 136*62e84772Spooka l->l_pflag |= LP_BOUND; 137*62e84772Spooka l->l_cpu = ci; 138*62e84772Spooka } 139c03306bcSpooka rv = rumpuser_thread_create(threadbouncer, k, thrname); 140c03306bcSpooka if (rv) 141c03306bcSpooka return rv; 142c03306bcSpooka 143c03306bcSpooka if (newlp) 144c03306bcSpooka *newlp = l; 145c03306bcSpooka return 0; 146c03306bcSpooka } 147c03306bcSpooka 148c03306bcSpooka void 149c03306bcSpooka kthread_exit(int ecode) 150c03306bcSpooka { 151c03306bcSpooka 152c03306bcSpooka if ((curlwp->l_pflag & LP_MPSAFE) == 0) 153c03306bcSpooka KERNEL_UNLOCK_ONE(NULL); 154c03306bcSpooka rump_lwp_release(curlwp); 155c03306bcSpooka rump_unschedule(); 156c03306bcSpooka rumpuser_thread_exit(); 157c03306bcSpooka } 158