1*23ac9029SStephen Hurd /*- 2*23ac9029SStephen Hurd * Copyright (c) 2014 Jeffrey Roberson <jeff@freebsd.org> 3*23ac9029SStephen Hurd * Copyright (c) 2016 Matthew Macy <mmacy@nextbsd.org> 4*23ac9029SStephen Hurd * All rights reserved. 5*23ac9029SStephen Hurd * 6*23ac9029SStephen Hurd * Redistribution and use in source and binary forms, with or without 7*23ac9029SStephen Hurd * modification, are permitted provided that the following conditions 8*23ac9029SStephen Hurd * are met: 9*23ac9029SStephen Hurd * 1. Redistributions of source code must retain the above copyright 10*23ac9029SStephen Hurd * notice, this list of conditions and the following disclaimer. 11*23ac9029SStephen Hurd * 2. Redistributions in binary form must reproduce the above copyright 12*23ac9029SStephen Hurd * notice, this list of conditions and the following disclaimer in the 13*23ac9029SStephen Hurd * documentation and/or other materials provided with the distribution. 14*23ac9029SStephen Hurd * 15*23ac9029SStephen Hurd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*23ac9029SStephen Hurd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*23ac9029SStephen Hurd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*23ac9029SStephen Hurd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*23ac9029SStephen Hurd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*23ac9029SStephen Hurd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*23ac9029SStephen Hurd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*23ac9029SStephen Hurd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*23ac9029SStephen Hurd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*23ac9029SStephen Hurd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*23ac9029SStephen Hurd * SUCH DAMAGE. 26*23ac9029SStephen Hurd * 27*23ac9029SStephen Hurd * $FreeBSD$ 28*23ac9029SStephen Hurd */ 29*23ac9029SStephen Hurd 30*23ac9029SStephen Hurd #ifndef _SYS_GTASKQUEUE_H_ 31*23ac9029SStephen Hurd #define _SYS_GTASKQUEUE_H_ 32*23ac9029SStephen Hurd #include <sys/taskqueue.h> 33*23ac9029SStephen Hurd 34*23ac9029SStephen Hurd #ifndef _KERNEL 35*23ac9029SStephen Hurd #error "no user-servicable parts inside" 36*23ac9029SStephen Hurd #endif 37*23ac9029SStephen Hurd 38*23ac9029SStephen Hurd struct gtaskqueue; 39*23ac9029SStephen Hurd typedef void (*gtaskqueue_enqueue_fn)(void *context); 40*23ac9029SStephen Hurd 41*23ac9029SStephen Hurd /* 42*23ac9029SStephen Hurd * Taskqueue groups. Manages dynamic thread groups and irq binding for 43*23ac9029SStephen Hurd * device and other tasks. 44*23ac9029SStephen Hurd */ 45*23ac9029SStephen Hurd 46*23ac9029SStephen Hurd void gtaskqueue_block(struct gtaskqueue *queue); 47*23ac9029SStephen Hurd void gtaskqueue_unblock(struct gtaskqueue *queue); 48*23ac9029SStephen Hurd 49*23ac9029SStephen Hurd int gtaskqueue_cancel(struct gtaskqueue *queue, struct gtask *gtask); 50*23ac9029SStephen Hurd void gtaskqueue_drain(struct gtaskqueue *queue, struct gtask *task); 51*23ac9029SStephen Hurd void gtaskqueue_drain_all(struct gtaskqueue *queue); 52*23ac9029SStephen Hurd 53*23ac9029SStephen Hurd int grouptaskqueue_enqueue(struct gtaskqueue *queue, struct gtask *task); 54*23ac9029SStephen Hurd void taskqgroup_attach(struct taskqgroup *qgroup, struct grouptask *grptask, 55*23ac9029SStephen Hurd void *uniq, int irq, char *name); 56*23ac9029SStephen Hurd int taskqgroup_attach_cpu(struct taskqgroup *qgroup, struct grouptask *grptask, 57*23ac9029SStephen Hurd void *uniq, int cpu, int irq, char *name); 58*23ac9029SStephen Hurd void taskqgroup_detach(struct taskqgroup *qgroup, struct grouptask *gtask); 59*23ac9029SStephen Hurd struct taskqgroup *taskqgroup_create(char *name); 60*23ac9029SStephen Hurd void taskqgroup_destroy(struct taskqgroup *qgroup); 61*23ac9029SStephen Hurd int taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride); 62*23ac9029SStephen Hurd 63*23ac9029SStephen Hurd #define TASK_ENQUEUED 0x1 64*23ac9029SStephen Hurd #define TASK_SKIP_WAKEUP 0x2 65*23ac9029SStephen Hurd 66*23ac9029SStephen Hurd 67*23ac9029SStephen Hurd #define GTASK_INIT(task, flags, priority, func, context) do { \ 68*23ac9029SStephen Hurd (task)->ta_flags = flags; \ 69*23ac9029SStephen Hurd (task)->ta_priority = (priority); \ 70*23ac9029SStephen Hurd (task)->ta_func = (func); \ 71*23ac9029SStephen Hurd (task)->ta_context = (context); \ 72*23ac9029SStephen Hurd } while (0) 73*23ac9029SStephen Hurd 74*23ac9029SStephen Hurd #define GROUPTASK_INIT(gtask, priority, func, context) \ 75*23ac9029SStephen Hurd GTASK_INIT(&(gtask)->gt_task, TASK_SKIP_WAKEUP, priority, func, context) 76*23ac9029SStephen Hurd 77*23ac9029SStephen Hurd #define GROUPTASK_ENQUEUE(gtask) \ 78*23ac9029SStephen Hurd grouptaskqueue_enqueue((gtask)->gt_taskqueue, &(gtask)->gt_task) 79*23ac9029SStephen Hurd 80*23ac9029SStephen Hurd #define TASKQGROUP_DECLARE(name) \ 81*23ac9029SStephen Hurd extern struct taskqgroup *qgroup_##name 82*23ac9029SStephen Hurd 83*23ac9029SStephen Hurd 84*23ac9029SStephen Hurd #ifdef EARLY_AP_STARTUP 85*23ac9029SStephen Hurd #define TASKQGROUP_DEFINE(name, cnt, stride) \ 86*23ac9029SStephen Hurd \ 87*23ac9029SStephen Hurd struct taskqgroup *qgroup_##name; \ 88*23ac9029SStephen Hurd \ 89*23ac9029SStephen Hurd static void \ 90*23ac9029SStephen Hurd taskqgroup_define_##name(void *arg) \ 91*23ac9029SStephen Hurd { \ 92*23ac9029SStephen Hurd qgroup_##name = taskqgroup_create(#name); \ 93*23ac9029SStephen Hurd taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \ 94*23ac9029SStephen Hurd } \ 95*23ac9029SStephen Hurd \ 96*23ac9029SStephen Hurd SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST, \ 97*23ac9029SStephen Hurd taskqgroup_define_##name, NULL) 98*23ac9029SStephen Hurd #else 99*23ac9029SStephen Hurd #define TASKQGROUP_DEFINE(name, cnt, stride) \ 100*23ac9029SStephen Hurd \ 101*23ac9029SStephen Hurd struct taskqgroup *qgroup_##name; \ 102*23ac9029SStephen Hurd \ 103*23ac9029SStephen Hurd static void \ 104*23ac9029SStephen Hurd taskqgroup_define_##name(void *arg) \ 105*23ac9029SStephen Hurd { \ 106*23ac9029SStephen Hurd qgroup_##name = taskqgroup_create(#name); \ 107*23ac9029SStephen Hurd } \ 108*23ac9029SStephen Hurd \ 109*23ac9029SStephen Hurd SYSINIT(taskqgroup_##name, SI_SUB_INIT_IF, SI_ORDER_FIRST, \ 110*23ac9029SStephen Hurd taskqgroup_define_##name, NULL); \ 111*23ac9029SStephen Hurd \ 112*23ac9029SStephen Hurd static void \ 113*23ac9029SStephen Hurd taskqgroup_adjust_##name(void *arg) \ 114*23ac9029SStephen Hurd { \ 115*23ac9029SStephen Hurd taskqgroup_adjust(qgroup_##name, (cnt), (stride)); \ 116*23ac9029SStephen Hurd } \ 117*23ac9029SStephen Hurd \ 118*23ac9029SStephen Hurd SYSINIT(taskqgroup_adj_##name, SI_SUB_SMP, SI_ORDER_ANY, \ 119*23ac9029SStephen Hurd taskqgroup_adjust_##name, NULL); \ 120*23ac9029SStephen Hurd \ 121*23ac9029SStephen Hurd struct __hack 122*23ac9029SStephen Hurd #endif 123*23ac9029SStephen Hurd TASKQGROUP_DECLARE(net); 124*23ac9029SStephen Hurd 125*23ac9029SStephen Hurd #endif /* !_SYS_GTASKQUEUE_H_ */ 126