executor.c revision 1.3
11.3Sandvar/*	$NetBSD: executor.c,v 1.3 2024/07/06 09:53:19 andvar Exp $	*/
21.1Skamil
31.1Skamil/*-
41.1Skamil * Copyright (c) 2018 The NetBSD Foundation, Inc.
51.1Skamil * All rights reserved.
61.1Skamil *
71.1Skamil * Redistribution and use in source and binary forms, with or without
81.1Skamil * modification, are permitted provided that the following conditions
91.1Skamil * are met:
101.1Skamil * 1. Redistributions of source code must retain the above copyright
111.1Skamil *    notice, this list of conditions and the following disclaimer.
121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright
131.1Skamil *    notice, this list of conditions and the following disclaimer in the
141.1Skamil *    documentation and/or other materials provided with the distribution.
151.1Skamil *
161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Skamil * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Skamil * POSSIBILITY OF SUCH DAMAGE.
271.1Skamil */
281.1Skamil
291.1Skamil#include <sys/cdefs.h>
301.3Sandvar__KERNEL_RCSID(0, "$NetBSD: executor.c,v 1.3 2024/07/06 09:53:19 andvar Exp $");
311.1Skamil
321.1Skamil#include <sys/param.h>
331.1Skamil#include <sys/module.h>
341.1Skamil#include <sys/callout.h>
351.1Skamil#include <sys/once.h>
361.1Skamil
371.1Skamil/*
381.1Skamil * Check if dmesg prints
391.1Skamil * "executor <no-of-seconds-after-loading>" every second
401.1Skamil * and "executor once" exactly once in the beginning
411.1Skamil * to test this module
421.1Skamil */
431.1Skamil
441.1SkamilMODULE(MODULE_CLASS_MISC, executor, NULL);
451.1Skamil
461.1Skamilstatic void callout_example(void *);
471.1Skamilstatic int runonce_example(void);
481.1Skamil
491.1Skamilstatic int executor_count = 0; //To hold the count of seconds
501.1Skamil
511.1Skamilstatic callout_t sc;
521.1Skamil
531.1Skamil/* Creating a variable that marks whether the function has executed or not */
541.1Skamilstatic once_t ctl;
551.1Skamilstatic ONCE_DECL(ctl);
561.1Skamil
571.1Skamil/*
581.1Skamil * runonce_example : This function should execute only once
591.1Skamil * It should return 0 as RUN_ONCE calls the function until it returns 0.
601.1Skamil */
611.1Skamil
621.1Skamilstatic int
631.1Skamilrunonce_example(void) {
641.1Skamil	printf("executor once\n");
651.1Skamil	return 0;
661.1Skamil}
671.1Skamil
681.1Skamil/*
691.1Skamil * callout_example : This function should get executed every second.
701.1Skamil * It calls runonce_example each time.
711.3Sandvar * It prints the seconds elapsed after the module was loaded.
721.1Skamil * It reschedules the callout to the next second using callout_schedule
731.1Skamil */
741.1Skamil
751.1Skamilstatic void
761.1Skamilcallout_example(void *arg) {
771.1Skamil	RUN_ONCE(&ctl, runonce_example);
781.1Skamil	executor_count++;
791.1Skamil	printf("Callout %d\n", executor_count);
801.1Skamil	callout_schedule(&sc, mstohz(1000));
811.1Skamil}
821.1Skamil
831.1Skamil/*
841.1Skamil * executor_modcmd : has two tasks
851.1Skamil * On loading the module it needs to initialize a callout handle and schedule
861.1Skamil * the first callout.
871.1Skamil * On unloading the module it needs to stop and destroy the callout handle
881.1Skamil */
891.1Skamil
901.1Skamilstatic int
911.1Skamilexecutor_modcmd(modcmd_t cmd, void *arg)
921.1Skamil{
931.1Skamil	switch(cmd) {
941.1Skamil	case MODULE_CMD_INIT:
951.1Skamil		printf("executor module inserted\n");
961.2Sad		callout_init(&sc, CALLOUT_MPSAFE);
971.1Skamil		callout_reset(&sc, mstohz(1000), callout_example, NULL);
981.1Skamil		break;
991.1Skamil	case MODULE_CMD_FINI:
1001.1Skamil		printf("executor module unloaded\n");
1011.2Sad		callout_halt(&sc, NULL);
1021.1Skamil		callout_destroy(&sc);
1031.1Skamil		break;
1041.1Skamil	default:
1051.1Skamil		return ENOTTY;
1061.1Skamil	}
1071.1Skamil	return 0;
1081.1Skamil}
109