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,
21 domain_id_t domain) {
22 struct cpu_mask cmask;
23 alloc_or_die(cpu_mask_init(&cmask, global.core_count));
24 size_t threads = global.domains[domain]->num_cores / 4;
25 if (!threads)
26 threads = 1;
27
28 domain_set_cpu_mask(mask: &cmask, domain: global.domains[domain]);
29 struct daemon_attributes attrs = {
30 .thread_cpu_mask = cmask,
31 .max_timesharing_threads = threads,
32 .min_timesharing_threads = threads,
33 .flags = DAEMON_FLAG_HAS_WORKQUEUE | DAEMON_FLAG_HAS_NAME,
34 };
35
36 struct workqueue_attributes wqattrs = {
37 .max_workers = threads,
38 .min_workers = threads,
39 .capacity = WORKQUEUE_DEFAULT_CAPACITY,
40 .spawn_delay = 0,
41 .idle_check = WORKQUEUE_DEFAULT_IDLE_CHECK,
42 .worker_cpu_mask = cmask,
43 .worker_niceness = 0,
44 .flags = WORKQUEUE_FLAG_STATIC_WORKERS | WORKQUEUE_FLAG_ON_DEMAND |
45 WORKQUEUE_FLAG_NAMED | WORKQUEUE_FLAG_NO_WORKER_GC,
46 };
47
48 alloc_or_die(pz->daemon =
49 daemon_create("page_zeroer_daemon_%zu", &attrs,
50 &pz_ts_work, &pz_bg_work, &wqattrs, domain));
51}
52
53PERDOMAIN_DECLARE(page_zeroers, struct page_zeroer, page_zeroer_perdomain_init);
54