1#include <mem/alloc_or_die.h>
2#include <mem/page_zeroer.h>
3#include <smp/domain.h>
4#include <smp/perdomain.h>
5
6static enum daemon_thread_command page_zeroer_ts_thread(void *a, void *b) {
7 return DAEMON_THREAD_COMMAND_DEFAULT;
8}
9
10static enum daemon_thread_command page_zeroer_bg_thread(void *a, void *b) {
11 return DAEMON_THREAD_COMMAND_DEFAULT;
12}
13
14static struct daemon_work pz_ts_work =
15 DAEMON_WORK_FROM(page_zeroer_ts_thread, WORK_ARGS(NULL, NULL));
16
17static struct daemon_work pz_bg_work =
18 DAEMON_WORK_FROM(page_zeroer_bg_thread, WORK_ARGS(NULL, NULL));
19
20static void page_zeroer_perdomain_init(struct page_zeroer *pz, size_t domain) {
21 struct cpu_mask cmask;
22 alloc_or_die(cpu_mask_init(&cmask, global.core_count));
23 size_t threads = global.domains[domain]->num_cores / 4;
24 if (!threads)
25 threads = 1;
26
27 domain_set_cpu_mask(mask: &cmask, domain: global.domains[domain]);
28 struct daemon_attributes attrs = {
29 .thread_cpu_mask = cmask,
30 .max_timesharing_threads = threads,
31 .min_timesharing_threads = threads,
32 .flags = DAEMON_FLAG_HAS_WORKQUEUE | DAEMON_FLAG_HAS_NAME,
33 };
34
35 struct workqueue_attributes wqattrs = {
36 .max_workers = threads,
37 .min_workers = threads,
38 .capacity = WORKQUEUE_DEFAULT_CAPACITY,
39 .spawn_delay = 0,
40 .idle_check = WORKQUEUE_DEFAULT_IDLE_CHECK,
41 .worker_cpu_mask = cmask,
42 .worker_niceness = 0,
43 .flags = WORKQUEUE_FLAG_STATIC_WORKERS | WORKQUEUE_FLAG_ON_DEMAND |
44 WORKQUEUE_FLAG_NAMED | WORKQUEUE_FLAG_NO_WORKER_GC,
45 };
46
47 alloc_or_die(pz->daemon =
48 daemon_create("page_zeroer_daemon_%zu", &attrs,
49 &pz_ts_work, &pz_bg_work, &wqattrs, domain));
50}
51
52PERDOMAIN_DECLARE(page_zeroers, struct page_zeroer, page_zeroer_perdomain_init);
53