1 // Copyright (c) 2024 Apple Inc. All rights reserved.
2
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 #include <darwintest.h>
7 #include <darwintest_utils.h>
8
9 #include "sched_migration_harness.h"
10 #include "sched_harness_impl.h"
11
12 void
init_migration_harness(test_hw_topology_t hw_topology)13 init_migration_harness(test_hw_topology_t hw_topology)
14 {
15 /* Sets up _log and ATEND to close it */
16 init_harness_logging(T_NAME);
17 assert(_log != NULL);
18
19 fprintf(_log, "\tinitializing migration harness\n");
20 set_hw_topology(hw_topology);
21 impl_init_migration_harness(hw_topology);
22 }
23
24 void
set_tg_sched_bucket_preferred_pset(struct thread_group * tg,int sched_bucket,int cluster_id)25 set_tg_sched_bucket_preferred_pset(struct thread_group *tg, int sched_bucket, int cluster_id)
26 {
27 fprintf(_log, "\tset TG %p bucket %d recommended for pset %d\n", (void *)tg, sched_bucket, cluster_id);
28 impl_set_tg_sched_bucket_preferred_pset(tg, sched_bucket, cluster_id);
29 }
30
31 void
set_thread_cluster_bound(test_thread_t thread,int cluster_id)32 set_thread_cluster_bound(test_thread_t thread, int cluster_id)
33 {
34 fprintf(_log, "\tset thread %p bound to cluster %d\n", (void *)thread, cluster_id);
35 impl_set_thread_cluster_bound(thread, cluster_id);
36 }
37
38 bool
choose_pset_for_thread_expect(test_thread_t thread,int expected_cluster_id)39 choose_pset_for_thread_expect(test_thread_t thread, int expected_cluster_id)
40 {
41 int chosen_pset_id = impl_choose_pset_for_thread(thread);
42 fprintf(_log, "%s: for thread %p we chose pset_id %d, expecting %d\n", chosen_pset_id == expected_cluster_id ?
43 "PASS" : "FAIL", (void *)thread, chosen_pset_id, expected_cluster_id);
44 return chosen_pset_id == expected_cluster_id;
45 }
46
47 void
set_current_processor(int cpu_id)48 set_current_processor(int cpu_id)
49 {
50 fprintf(_log, "\tset current_processor() to cpu id %d\n", cpu_id);
51 impl_set_current_processor(cpu_id);
52 }
53
54 void
set_pset_load_avg(int cluster_id,int QoS,uint64_t load_avg)55 set_pset_load_avg(int cluster_id, int QoS, uint64_t load_avg)
56 {
57 fprintf(_log, "\tset pset_load_avg for cluster %d QoS %d to %llu\n", cluster_id, QoS, load_avg);
58 impl_set_pset_load_avg(cluster_id, QoS, load_avg);
59 }
60
61 void
set_pset_recommended(int cluster_id)62 set_pset_recommended(int cluster_id)
63 {
64 fprintf(_log, "\tset cluster %d as recommended\n", cluster_id);
65 impl_set_pset_recommended(cluster_id);
66 }
67
68 void
set_pset_derecommended(int cluster_id)69 set_pset_derecommended(int cluster_id)
70 {
71 fprintf(_log, "\tset cluster %d as derecommended\n", cluster_id);
72 impl_set_pset_derecommended(cluster_id);
73 }
74
75 bool
ipi_expect(int cpu_id,test_ipi_type_t ipi_type)76 ipi_expect(int cpu_id, test_ipi_type_t ipi_type)
77 {
78 int found_cpu_id = -1;
79 test_ipi_type_t found_ipi_type = TEST_IPI_NONE;
80 impl_pop_ipi(&found_cpu_id, &found_ipi_type);
81 bool pass = (cpu_id == found_cpu_id) && (ipi_type == found_ipi_type);
82 fprintf(_log, "%s: expected ipi to cpu %d type %u, found ipi to cpu %d type %u\n",
83 pass ? "PASS": "FAIL", cpu_id, ipi_type, found_cpu_id, found_ipi_type);
84 return pass;
85 }
86
87 bool
cpu_check_should_yield(int cpu_id,bool yield_expected)88 cpu_check_should_yield(int cpu_id, bool yield_expected)
89 {
90 bool yielding = impl_thread_should_yield(cpu_id);
91 fprintf(_log, "%s: would yield on cpu %d? %d, expecting to yield? %d\n",
92 yielding == yield_expected ? "PASS" : "FAIL", cpu_id, yielding, yield_expected);
93 return yielding == yield_expected;
94 }
95
96 void
cpu_send_ipi_for_thread(int cpu_id,test_thread_t thread,test_ipi_event_t event)97 cpu_send_ipi_for_thread(int cpu_id, test_thread_t thread, test_ipi_event_t event)
98 {
99 fprintf(_log, "requesting IPI to cpu %d thread %p event %u\n", cpu_id,
100 (void *)thread, event);
101 impl_send_ipi(cpu_id, thread, event);
102 }
103
104 bool
max_parallelism_expect(int qos,uint64_t options,uint32_t expected_parallelism)105 max_parallelism_expect(int qos, uint64_t options, uint32_t expected_parallelism)
106 {
107 uint32_t found_parallelism = impl_qos_max_parallelism(qos, options);
108 fprintf(_log, "expected parallelism %u for QoS %d options %llx, found parallelism %u\n",
109 expected_parallelism, qos, options, found_parallelism);
110 return found_parallelism == expected_parallelism;
111 }
112