1*0caf8245Sandvar /* $NetBSD: executor.c,v 1.3 2024/07/06 09:53:19 andvar Exp $ */
2bfd0ff91Skamil
3bfd0ff91Skamil /*-
4bfd0ff91Skamil * Copyright (c) 2018 The NetBSD Foundation, Inc.
5bfd0ff91Skamil * All rights reserved.
6bfd0ff91Skamil *
7bfd0ff91Skamil * Redistribution and use in source and binary forms, with or without
8bfd0ff91Skamil * modification, are permitted provided that the following conditions
9bfd0ff91Skamil * are met:
10bfd0ff91Skamil * 1. Redistributions of source code must retain the above copyright
11bfd0ff91Skamil * notice, this list of conditions and the following disclaimer.
12bfd0ff91Skamil * 2. Redistributions in binary form must reproduce the above copyright
13bfd0ff91Skamil * notice, this list of conditions and the following disclaimer in the
14bfd0ff91Skamil * documentation and/or other materials provided with the distribution.
15bfd0ff91Skamil *
16bfd0ff91Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17bfd0ff91Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18bfd0ff91Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19bfd0ff91Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20bfd0ff91Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21bfd0ff91Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22bfd0ff91Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23bfd0ff91Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24bfd0ff91Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25bfd0ff91Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26bfd0ff91Skamil * POSSIBILITY OF SUCH DAMAGE.
27bfd0ff91Skamil */
28bfd0ff91Skamil
29bfd0ff91Skamil #include <sys/cdefs.h>
30*0caf8245Sandvar __KERNEL_RCSID(0, "$NetBSD: executor.c,v 1.3 2024/07/06 09:53:19 andvar Exp $");
31bfd0ff91Skamil
32bfd0ff91Skamil #include <sys/param.h>
33bfd0ff91Skamil #include <sys/module.h>
34bfd0ff91Skamil #include <sys/callout.h>
35bfd0ff91Skamil #include <sys/once.h>
36bfd0ff91Skamil
37bfd0ff91Skamil /*
38bfd0ff91Skamil * Check if dmesg prints
39bfd0ff91Skamil * "executor <no-of-seconds-after-loading>" every second
40bfd0ff91Skamil * and "executor once" exactly once in the beginning
41bfd0ff91Skamil * to test this module
42bfd0ff91Skamil */
43bfd0ff91Skamil
44bfd0ff91Skamil MODULE(MODULE_CLASS_MISC, executor, NULL);
45bfd0ff91Skamil
46bfd0ff91Skamil static void callout_example(void *);
47bfd0ff91Skamil static int runonce_example(void);
48bfd0ff91Skamil
49bfd0ff91Skamil static int executor_count = 0; //To hold the count of seconds
50bfd0ff91Skamil
51bfd0ff91Skamil static callout_t sc;
52bfd0ff91Skamil
53bfd0ff91Skamil /* Creating a variable that marks whether the function has executed or not */
54bfd0ff91Skamil static once_t ctl;
55bfd0ff91Skamil static ONCE_DECL(ctl);
56bfd0ff91Skamil
57bfd0ff91Skamil /*
58bfd0ff91Skamil * runonce_example : This function should execute only once
59bfd0ff91Skamil * It should return 0 as RUN_ONCE calls the function until it returns 0.
60bfd0ff91Skamil */
61bfd0ff91Skamil
62bfd0ff91Skamil static int
runonce_example(void)63bfd0ff91Skamil runonce_example(void) {
64bfd0ff91Skamil printf("executor once\n");
65bfd0ff91Skamil return 0;
66bfd0ff91Skamil }
67bfd0ff91Skamil
68bfd0ff91Skamil /*
69bfd0ff91Skamil * callout_example : This function should get executed every second.
70bfd0ff91Skamil * It calls runonce_example each time.
71*0caf8245Sandvar * It prints the seconds elapsed after the module was loaded.
72bfd0ff91Skamil * It reschedules the callout to the next second using callout_schedule
73bfd0ff91Skamil */
74bfd0ff91Skamil
75bfd0ff91Skamil static void
callout_example(void * arg)76bfd0ff91Skamil callout_example(void *arg) {
77bfd0ff91Skamil RUN_ONCE(&ctl, runonce_example);
78bfd0ff91Skamil executor_count++;
79bfd0ff91Skamil printf("Callout %d\n", executor_count);
80bfd0ff91Skamil callout_schedule(&sc, mstohz(1000));
81bfd0ff91Skamil }
82bfd0ff91Skamil
83bfd0ff91Skamil /*
84bfd0ff91Skamil * executor_modcmd : has two tasks
85bfd0ff91Skamil * On loading the module it needs to initialize a callout handle and schedule
86bfd0ff91Skamil * the first callout.
87bfd0ff91Skamil * On unloading the module it needs to stop and destroy the callout handle
88bfd0ff91Skamil */
89bfd0ff91Skamil
90bfd0ff91Skamil static int
executor_modcmd(modcmd_t cmd,void * arg)91bfd0ff91Skamil executor_modcmd(modcmd_t cmd, void *arg)
92bfd0ff91Skamil {
93bfd0ff91Skamil switch(cmd) {
94bfd0ff91Skamil case MODULE_CMD_INIT:
95bfd0ff91Skamil printf("executor module inserted\n");
968faaa814Sad callout_init(&sc, CALLOUT_MPSAFE);
97bfd0ff91Skamil callout_reset(&sc, mstohz(1000), callout_example, NULL);
98bfd0ff91Skamil break;
99bfd0ff91Skamil case MODULE_CMD_FINI:
100bfd0ff91Skamil printf("executor module unloaded\n");
1018faaa814Sad callout_halt(&sc, NULL);
102bfd0ff91Skamil callout_destroy(&sc);
103bfd0ff91Skamil break;
104bfd0ff91Skamil default:
105bfd0ff91Skamil return ENOTTY;
106bfd0ff91Skamil }
107bfd0ff91Skamil return 0;
108bfd0ff91Skamil }
109