1/*
2 * Copyright 2018, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#include "sysinit.h"
6
7#include <sys/cdefs.h>
8#include <sys/kernel.h>
9
10
11//#define TRACE_SYSINIT
12#ifdef TRACE_SYSINIT
13#	define TRACE(x...) dprintf(x)
14#else
15#	define TRACE(x...)
16#endif
17
18
19/* linker sets */
20SET_DECLARE(__freebsd_sysinit, struct sysinit);
21SET_DECLARE(__freebsd_sysuninit, struct sysinit);
22
23/* make sure there's something in both linker sets, so we can link */
24SYSINIT(__dummy, 0, 0, NULL, NULL);
25SYSUNINIT(__dummy, 0, 0, NULL, NULL);
26
27/* orders */
28static const enum sysinit_elem_order orders[6] = {
29	SI_ORDER_FIRST, SI_ORDER_SECOND, SI_ORDER_THIRD, SI_ORDER_FOURTH,
30	SI_ORDER_MIDDLE, SI_ORDER_ANY,
31};
32
33
34void
35init_sysinit()
36{
37	struct sysinit* const* initee;
38	int32 i;
39
40	for (i = 0; i < 6; i++) {
41		SET_FOREACH(initee, __freebsd_sysinit) {
42			if ((*initee)->order != orders[i] || (*initee)->func == NULL)
43				continue;
44			TRACE("sysinit: %d, %d, %s\n", orders[i], (*initee)->order,
45				(*initee)->name);
46			(*initee)->func((*initee)->arg);
47		}
48	}
49}
50
51
52void
53uninit_sysinit()
54{
55	struct sysinit* const* initee;
56	int32 i;
57
58	for (i = 5; i >= 0; i--) {
59		SET_FOREACH(initee, __freebsd_sysuninit) {
60			if ((*initee)->order != orders[i] || (*initee)->func == NULL)
61				continue;
62			TRACE("sysinit: de-initializing %s %p\n", (*initee)->name, (*initee)->func);
63			(*initee)->func((*initee)->arg);
64		}
65	}
66}
67