1 /* 2 * Copyright (c) 2014,2018,2019 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #ifndef _SYS_CALLOUT_H_ 36 #define _SYS_CALLOUT_H_ 37 38 #ifndef _SYS_QUEUE_H_ 39 #include <sys/queue.h> 40 #endif 41 #ifndef _SYS_LOCK_H_ 42 #include <sys/lock.h> 43 #endif 44 #ifndef _SYS_SPINLOCK_H_ 45 #include <sys/spinlock.h> 46 #endif 47 #ifndef _SYS_EXISLOCK_H_ 48 #include <sys/exislock.h> 49 #endif 50 51 struct callout; 52 struct softclock_pcpu; 53 54 struct _callout { 55 struct spinlock spin; /* typestable spinlock */ 56 exislock_t exis; 57 TAILQ_ENTRY(_callout) entry; 58 struct callout *verifier; 59 uint32_t flags; 60 uint32_t lineno; 61 struct lock *lk; 62 const char *ident; 63 64 struct softclock_pcpu *rsc; /* request info */ 65 void *rarg; 66 void (*rfunc)(void *); 67 int rtick; 68 uint32_t unused01; 69 70 struct softclock_pcpu *qsc; /* active info */ 71 void *qarg; 72 void (*qfunc)(void *); 73 int qtick; 74 int waiters; 75 }; 76 77 struct callout { 78 struct _callout *toc; /* opaque internal pointer */ 79 struct lock *lk; /* callout_init() copy data */ 80 uint32_t flags; /* callout_init() copy data */ 81 uint32_t unused01; 82 }; 83 84 /* 85 * Legacy access/setting of the function and argument. Used only 86 * by netgraph7 and ieee80211_dfs.c. DO NOT USE FOR NEW CODE! 87 */ 88 #define callout_set_arg(cc, _arg) do { \ 89 if ((cc)->toc) \ 90 ((cc)->toc->qarg = (cc)->toc->rarg = (_arg)); \ 91 } while(0) 92 #define callout_arg(cc) ((cc)->toc ? (cc)->toc->rarg : NULL) 93 #define callout_func(cc) ((cc)->toc ? (cc)->toc->rfunc : NULL) 94 95 #ifdef _KERNEL 96 97 #define CALLOUT_DEBUG 98 #ifdef CALLOUT_DEBUG 99 #define CALLOUT_DEBUG_ARGS , const char *ident, int lineno 100 #define CALLOUT_DEBUG_PASSTHRU , ident, lineno 101 #else 102 #define CALLOUT_DEBUG_ARGS 103 #define CALLOUT_DEBUG_PASSTHRU 104 #endif 105 106 struct globaldata; 107 108 extern int ncallout; 109 110 int callout_active(struct callout *ext); 111 int callout_pending(struct callout *ext); 112 void callout_deactivate(struct callout *ext); 113 114 void hardclock_softtick(struct globaldata *); 115 void _callout_init (struct callout *cc 116 CALLOUT_DEBUG_ARGS); 117 void _callout_init_mp (struct callout *cc 118 CALLOUT_DEBUG_ARGS); 119 void _callout_init_lk (struct callout *cc, struct lock *lk 120 CALLOUT_DEBUG_ARGS); 121 122 void _callout_setup_quick(struct callout *cc, struct _callout *c, 123 int ticks, void (*)(void *), void *); 124 void _callout_cancel_quick(struct _callout *c); 125 126 void callout_reset (struct callout *, int, 127 void (*)(void *), void *); 128 void callout_reset_bycpu (struct callout *, int, 129 void (*)(void *), void *, 130 int); 131 int callout_stop (struct callout *cc); 132 int callout_stop_async (struct callout *cc); 133 void callout_terminate (struct callout *cc); 134 int callout_cancel (struct callout *cc); 135 int callout_drain (struct callout *cc); 136 137 #ifdef CALLOUT_DEBUG 138 #define callout_init(co) _callout_init(co, __FILE__, __LINE__) 139 #define callout_init_mp(co) _callout_init_mp(co, __FILE__, __LINE__) 140 #define callout_init_lk(co, lk) _callout_init_lk(co, lk, __FILE__, __LINE__) 141 #else 142 #define callout_init(co) _callout_init(co) 143 #define callout_init_mp(co) _callout_init_mp(co) 144 #define callout_init_lk(co, lk) _callout_init_lk(co, lk) 145 #endif 146 147 #endif /* _KERNEL */ 148 149 #endif /* _SYS_CALLOUT_H_ */ 150