aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-02-05 00:31:08 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2014-02-24 14:01:11 -0500
commit1f323b00f95c4704cdeea7918853f1e9e8d26c2e (patch)
tree76a6856b2465ba7d114009f231c0dae9c9e5ef2c
parent871eef081ff9db7289a6947d0160cd984232c34c (diff)
Use /proc/litmus/domains to set up affinity masks
This patch replaces the algorithm used to compute CPU affinity masks. The old algorithm was fragile and would break on systems with multiple levels of shared caches. (As found on some older Intel chips, and as one would probably find on a system with hyper-threading enabled.) The bug stems from fact that Linux enumerates consecutive CPUs in a way that distributes them across the physical system, thereby reducing contention resources (e.g., cache). Cluster size no longer needs to be provided now that cluster/CPU mappings are explicit in /proc/litmus/domains/. This keeps the following migration functions, but marks them as deprecated: - be_migrate_to_cluster() - cluster_to_first_cpu() - partition_to_cpu() Although the deprecated interfaces are supported, the implementations for these functions call the new be_migrate_to_domain() and domain_to_first_cpu() functions. [bbb: resolved several merge conflicts]
-rw-r--r--bin/rt_launch.c10
-rw-r--r--bin/rtspin.c10
-rw-r--r--include/litmus.h35
-rw-r--r--include/migration.h53
-rw-r--r--src/litmus.c10
-rw-r--r--src/migration.c113
-rw-r--r--src/task.c8
7 files changed, 119 insertions, 120 deletions
diff --git a/bin/rt_launch.c b/bin/rt_launch.c
index 93f10d5..5e29893 100644
--- a/bin/rt_launch.c
+++ b/bin/rt_launch.c
@@ -42,7 +42,7 @@ void usage(char *error) {
42} 42}
43 43
44 44
45#define OPTSTR "p:z:c:vwq:" 45#define OPTSTR "p:c:vwq:"
46 46
47int main(int argc, char** argv) 47int main(int argc, char** argv)
48{ 48{
@@ -51,7 +51,6 @@ int main(int argc, char** argv)
51 lt_t period; 51 lt_t period;
52 int migrate = 0; 52 int migrate = 0;
53 int cluster = 0; 53 int cluster = 0;
54 int cluster_size = 1;
55 int opt; 54 int opt;
56 int verbose = 0; 55 int verbose = 0;
57 int wait = 0; 56 int wait = 0;
@@ -71,9 +70,6 @@ int main(int argc, char** argv)
71 cluster = atoi(optarg); 70 cluster = atoi(optarg);
72 migrate = 1; 71 migrate = 1;
73 break; 72 break;
74 case 'z':
75 cluster_size = atoi(optarg);
76 break;
77 case 'q': 73 case 'q':
78 priority = atoi(optarg); 74 priority = atoi(optarg);
79 if (!litmus_is_valid_fixed_prio(priority)) 75 if (!litmus_is_valid_fixed_prio(priority))
@@ -114,11 +110,11 @@ int main(int argc, char** argv)
114 info.argv = argv + optind + 2; 110 info.argv = argv + optind + 2;
115 info.wait = wait; 111 info.wait = wait;
116 if (migrate) { 112 if (migrate) {
117 ret = be_migrate_to_cluster(cluster, cluster_size); 113 ret = be_migrate_to_domain(cluster);
118 if (ret < 0) 114 if (ret < 0)
119 bail_out("could not migrate to target partition or cluster"); 115 bail_out("could not migrate to target partition or cluster");
120 } 116 }
121 ret = __create_rt_task(launch, &info, cluster, cluster_size, wcet, period, 117 ret = __create_rt_task(launch, &info, cluster, wcet, period,
122 priority, class); 118 priority, class);
123 119
124 120
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 167741d..b4156cc 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -184,7 +184,7 @@ static int job(double exec_time, double program_end, int lock_od, double cs_leng
184 } 184 }
185} 185}
186 186
187#define OPTSTR "p:z:c:wlveo:f:s:q:X:L:Q:" 187#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:"
188int main(int argc, char** argv) 188int main(int argc, char** argv)
189{ 189{
190 int ret; 190 int ret;
@@ -194,7 +194,6 @@ int main(int argc, char** argv)
194 unsigned int priority = LITMUS_LOWEST_PRIORITY; 194 unsigned int priority = LITMUS_LOWEST_PRIORITY;
195 int migrate = 0; 195 int migrate = 0;
196 int cluster = 0; 196 int cluster = 0;
197 int cluster_size = 1;
198 int opt; 197 int opt;
199 int wait = 0; 198 int wait = 0;
200 int test_loop = 0; 199 int test_loop = 0;
@@ -226,9 +225,6 @@ int main(int argc, char** argv)
226 cluster = atoi(optarg); 225 cluster = atoi(optarg);
227 migrate = 1; 226 migrate = 1;
228 break; 227 break;
229 case 'z':
230 cluster_size = atoi(optarg);
231 break;
232 case 'q': 228 case 'q':
233 priority = atoi(optarg); 229 priority = atoi(optarg);
234 if (!litmus_is_valid_fixed_prio(priority)) 230 if (!litmus_is_valid_fixed_prio(priority))
@@ -326,7 +322,7 @@ int main(int argc, char** argv)
326 duration += period_ms * 0.001 * (num_jobs - 1); 322 duration += period_ms * 0.001 * (num_jobs - 1);
327 323
328 if (migrate) { 324 if (migrate) {
329 ret = be_migrate_to_cluster(cluster, cluster_size); 325 ret = be_migrate_to_domain(cluster);
330 if (ret < 0) 326 if (ret < 0)
331 bail_out("could not migrate to target partition or cluster."); 327 bail_out("could not migrate to target partition or cluster.");
332 } 328 }
@@ -339,7 +335,7 @@ int main(int argc, char** argv)
339 param.budget_policy = (want_enforcement) ? 335 param.budget_policy = (want_enforcement) ?
340 PRECISE_ENFORCEMENT : NO_ENFORCEMENT; 336 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
341 if (migrate) 337 if (migrate)
342 param.cpu = cluster_to_first_cpu(cluster, cluster_size); 338 param.cpu = domain_to_first_cpu(cluster);
343 ret = set_rt_task_param(gettid(), &param); 339 ret = set_rt_task_param(gettid(), &param);
344 if (ret < 0) 340 if (ret < 0)
345 bail_out("could not setup rt task params"); 341 bail_out("could not setup rt task params");
diff --git a/include/litmus.h b/include/litmus.h
index 5a79b7d..5a5461f 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -51,6 +51,7 @@ extern "C" {
51 * @param param Pointer to the struct to initialise 51 * @param param Pointer to the struct to initialise
52 */ 52 */
53void init_rt_task_param(struct rt_task* param); 53void init_rt_task_param(struct rt_task* param);
54
54/** 55/**
55 * Set real-time task parameters for given process 56 * Set real-time task parameters for given process
56 * @param pid PID of process 57 * @param pid PID of process
@@ -58,6 +59,7 @@ void init_rt_task_param(struct rt_task* param);
58 * @return 0 on success 59 * @return 0 on success
59 */ 60 */
60int set_rt_task_param(pid_t pid, struct rt_task* param); 61int set_rt_task_param(pid_t pid, struct rt_task* param);
62
61/** 63/**
62 * Get real-time task parameters for given process 64 * Get real-time task parameters for given process
63 * @param pid PID of process 65 * @param pid PID of process
@@ -74,20 +76,26 @@ int get_rt_task_param(pid_t pid, struct rt_task* param);
74 * Release-master-aware functions for getting the first 76 * Release-master-aware functions for getting the first
75 * CPU in a particular cluster or partition. Use these 77 * CPU in a particular cluster or partition. Use these
76 * to set rt_task::cpu for cluster/partitioned scheduling. 78 * to set rt_task::cpu for cluster/partitioned scheduling.
79 *
80 * \deprecated{Use domain_to_first_cpu() in new code.}
77 */ 81 */
78int partition_to_cpu(int partition); 82int partition_to_cpu(int partition);
83
79/** 84/**
80 * For given cluster, return the identifier for the first associated CPU 85 * For given cluster, return the identifier for the first associated CPU
81 * @param cluster Identifier of the cluster 86 * @param cluster Identifier of the cluster
82 * @param cluster_size Size for this cluster 87 * @param cluster_size Size for this cluster
83 * @return Identifier for the first associated CPU 88 * @return Identifier for the first associated CPU
89 *
90 * \deprecated{Use domain_to_first_cpu() in new code.}
84 */ 91 */
85int cluster_to_first_cpu(int cluster, int cluster_size); 92int cluster_to_first_cpu(int cluster, int cluster_size);
86 93
87/* Convenience functions for setting up real-time tasks. 94
88 * Default behaviors set by init_rt_task_params() used. 95/* The following three functions are convenience functions for setting up
89 * Also sets affinity masks for clustered/partitions 96 * real-time tasks. Default behaviors set by init_rt_task_params() are used.
90 * functions. Time units in nanoseconds. */ 97 * Also sets affinity masks for clustered/partitions functions. Time units in
98 * nanoseconds. */
91/** 99/**
92 * Set up a sporadic task with global scheduling 100 * Set up a sporadic task with global scheduling
93 * @param e_ns Execution time in nanoseconds 101 * @param e_ns Execution time in nanoseconds
@@ -95,6 +103,7 @@ int cluster_to_first_cpu(int cluster, int cluster_size);
95 * @return 0 on success 103 * @return 0 on success
96 */ 104 */
97int sporadic_global(lt_t e_ns, lt_t p_ns); 105int sporadic_global(lt_t e_ns, lt_t p_ns);
106
98/** 107/**
99 * Set up a sporadic task with partitioned scheduling 108 * Set up a sporadic task with partitioned scheduling
100 * @param e_ns Execution time in nanoseconds 109 * @param e_ns Execution time in nanoseconds
@@ -103,15 +112,15 @@ int sporadic_global(lt_t e_ns, lt_t p_ns);
103 * @return 0 on success 112 * @return 0 on success
104 */ 113 */
105int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition); 114int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition);
115
106/** 116/**
107 * Set up a sporadic task with clustered scheduling 117 * Set up a sporadic task with clustered scheduling
108 * @param e_ns Execution time in nanoseconds 118 * @param e_ns Execution time in nanoseconds
109 * @param p_ns Period in nanoseconds 119 * @param p_ns Period in nanoseconds
110 * @param cluster Cluster to add this task to 120 * @param cluster Cluster to add this task to
111 * @param cluster_size Size of the cluster
112 * @return 0 on success 121 * @return 0 on success
113 */ 122 */
114int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size); 123int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster);
115 124
116/* simple time unit conversion macros */ 125/* simple time unit conversion macros */
117/** Convert seconds to nanoseconds 126/** Convert seconds to nanoseconds
@@ -250,29 +259,25 @@ typedef int (*rt_fn_t)(void*);
250 * @param arg Pointer to arguments to pass to the pointer in rt_prog 259 * @param arg Pointer to arguments to pass to the pointer in rt_prog
251 * @param cluster Cluster to schedule this task on. For partitioned scheduling, 260 * @param cluster Cluster to schedule this task on. For partitioned scheduling,
252 * set to the desired partition. For global scheduling, set to 0 261 * set to the desired partition. For global scheduling, set to 0
253 * @param cluster_size Size of the cluster. For partitioned scheduling, set to
254 * 1, for global scheduling set to 0.
255 * @param wcet Worst-Case execution time for this task 262 * @param wcet Worst-Case execution time for this task
256 * @param period Period at which this task should be launched 263 * @param period Period at which this task should be launched
257 * @param prio Priority for this task 264 * @param prio Priority for this task
258 */ 265 */
259int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, 266int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
260 lt_t wcet, lt_t period, unsigned int prio); 267 lt_t wcet, lt_t period, unsigned int prio);
261/** 268/**
262 * Create a real-time task 269 * Create a real-time task
263 * @param rt_prog Function pointer to real-time task body 270 * @param rt_prog Function pointer to real-time task body
264 * @param arg Pointer to arguments to pass to the pointer in rt_prog 271 * @param arg Pointer to arguments to pass to the pointer in rt_prog
265 * @param cluster Cluster to schedule this task on. For partitioned scheduling, 272 * @param cluster Cluster to schedule this task on. For partitioned scheduling,
266 * set to the desired partition. For global scheduling, set to 0 273 * set to the desired partition. For global scheduling, set to 0
267 * @param cluster_size Size of the cluster. For partitioned scheduling, set to
268 * 1, for global scheduling set to 0.
269 * @param wcet Worst-Case execution time for this task 274 * @param wcet Worst-Case execution time for this task
270 * @param period Period at which this task should be launched 275 * @param period Period at which this task should be launched
271 * @param prio Priority for this task 276 * @param prio Priority for this task
272 * @param cls Task class (???) 277 * @param cls Task class (unused)
273 */ 278 */
274int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, 279int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
275 lt_t wcet, lt_t period, unsigned int prio, task_class_t cls); 280 lt_t wcet, lt_t period, unsigned int prio, task_class_t cls);
276 281
277/* per-task modes */ 282/* per-task modes */
278enum rt_task_mode_t { 283enum rt_task_mode_t {
diff --git a/include/migration.h b/include/migration.h
index 32d933b..f60dfe9 100644
--- a/include/migration.h
+++ b/include/migration.h
@@ -19,62 +19,55 @@ pid_t gettid();
19 * @return 0 if successful 19 * @return 0 if successful
20 */ 20 */
21int be_migrate_thread_to_cpu(pid_t tid, int target_cpu); 21int be_migrate_thread_to_cpu(pid_t tid, int target_cpu);
22/** 22
23 * Migrate and assign a task to a given partition
24 * @param tid Process ID for migrated task, 0 for current task
25 * @param partition Partition ID to migrate the task to
26 * @pre tid is not yet in real-time mode (it's a best effort task)
27 * @return 0 if successful
28 */
29int be_migrate_thread_to_partition(pid_t tid, int partition);
30/** 23/**
31 * Migrate current task to a given cluster 24 * Migrate current task to a given cluster
32 * @param tid Process ID for migrated task, 0 for current task 25 * @param tid Process ID for migrated task, 0 for current task
33 * @param cluster Cluster ID to migrate the task to 26 * @param domain Cluster ID to migrate the task to
34 * @param cluster_sz Size of the cluster to migrate to
35 * @pre tid is not yet in real-time mode (it's a best effort task) 27 * @pre tid is not yet in real-time mode (it's a best effort task)
36 * @return 0 if successful 28 * @return 0 if successful
37 *
38 * If using release master, set cluster_sz to size of largest cluster. tid
39 * will not be scheduled on release master
40 */
41int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz);
42
43/**
44 * @private
45 * set ignore_rm == 1 to include release master in tid's cpu affinity
46 */ 29 */
47int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, int ignore_rm); 30int be_migrate_thread_to_cluster(pid_t tid, int domain);
48 31
49/** 32/**
50 * Migrate current task to a given CPU 33 * Migrate current task to a given CPU
51 * @param target_cpu ID for CPU to migrate to 34 * @param target_cpu ID for CPU to migrate to
52 * @pre tid is not yet in real-time mode (it's a best effort task) 35 * @pre The current task is not yet in real-time mode (it's a best-effort task)
53 * @return 0 if successful 36 * @return 0 if successful
54 */ 37 */
55int be_migrate_to_cpu(int target_cpu); 38int be_migrate_to_cpu(int target_cpu);
56/** 39
57 * Migrate current task to a given partition
58 * @param partition Partition ID to migrate the task to
59 * @pre tid is not yet in real-time mode (it's a best effort task)
60 * @return 0 if successful
61 */
62int be_migrate_to_partition(int partition);
63/** 40/**
64 * Migrate current task to a given cluster 41 * Migrate current task to a given cluster
65 * @param cluster Cluster ID to migrate the task to 42 * @param cluster Cluster ID to migrate the task to
66 * @param cluster_sz Size of the cluster to migrate to 43 * @param cluster_sz Size of the cluster to migrate to (unused)
67 * @pre tid is not yet in real-time mode (it's a best effort task) 44 * @pre The current task is not yet in real-time mode (it's a best-effort task)
68 * @return 0 if successful 45 * @return 0 if successful
46 *
47 * \deprecated{Use be_migrate_to_domain() instead in new code.}
69 */ 48 */
70int be_migrate_to_cluster(int cluster, int cluster_sz); 49int be_migrate_to_cluster(int cluster, int cluster_sz);
71 50
72/** 51/**
52 * Migrate current task to a given scheduling domain (i.e., cluster or
53 * partition).
54 * @param domain The cluster/partition to migrate to.
55 * @pre The current task is not yet in real-time mode (it's a best-effort task).
56 * @return 0 if successful
57 */
58int be_migrate_to_domain(int domain);
59
60/**
73 * Return the number of CPUs currently online 61 * Return the number of CPUs currently online
74 * @return The number of online CPUs 62 * @return The number of online CPUs
75 */ 63 */
76int num_online_cpus(); 64int num_online_cpus();
65
77/** 66/**
78 * @todo Document! 67 * @todo Document!
79 */ 68 */
80int release_master(); 69int release_master();
70int domain_to_cpus(int domain, unsigned long long int* mask);
71int cpu_to_domains(int cpu, unsigned long long int* mask);
72
73int domain_to_first_cpu(int domain);
diff --git a/src/litmus.c b/src/litmus.c
index dce8e1b..4631eea 100644
--- a/src/litmus.c
+++ b/src/litmus.c
@@ -135,7 +135,7 @@ int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition)
135 int ret; 135 int ret;
136 struct rt_task param; 136 struct rt_task param;
137 137
138 ret = be_migrate_to_partition(partition); 138 ret = be_migrate_to_domain(partition);
139 check("be_migrate_to_partition()"); 139 check("be_migrate_to_partition()");
140 if (ret != 0) 140 if (ret != 0)
141 return ret; 141 return ret;
@@ -143,17 +143,17 @@ int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition)
143 init_rt_task_param(&param); 143 init_rt_task_param(&param);
144 param.exec_cost = e_ns; 144 param.exec_cost = e_ns;
145 param.period = p_ns; 145 param.period = p_ns;
146 param.cpu = partition_to_cpu(partition); 146 param.cpu = domain_to_first_cpu(partition);
147 147
148 return set_rt_task_param(gettid(), &param); 148 return set_rt_task_param(gettid(), &param);
149} 149}
150 150
151int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size) 151int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster)
152{ 152{
153 int ret; 153 int ret;
154 struct rt_task param; 154 struct rt_task param;
155 155
156 ret = be_migrate_to_cluster(cluster, cluster_size); 156 ret = be_migrate_to_domain(cluster);
157 check("be_migrate_to_cluster()"); 157 check("be_migrate_to_cluster()");
158 if (ret != 0) 158 if (ret != 0)
159 return ret; 159 return ret;
@@ -161,7 +161,7 @@ int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size)
161 init_rt_task_param(&param); 161 init_rt_task_param(&param);
162 param.exec_cost = e_ns; 162 param.exec_cost = e_ns;
163 param.period = p_ns; 163 param.period = p_ns;
164 param.cpu = cluster_to_first_cpu(cluster, cluster_size); 164 param.cpu = domain_to_first_cpu(cluster);
165 165
166 return set_rt_task_param(gettid(), &param); 166 return set_rt_task_param(gettid(), &param);
167} 167}
diff --git a/src/migration.c b/src/migration.c
index 5de81d5..3bd6d0a 100644
--- a/src/migration.c
+++ b/src/migration.c
@@ -27,31 +27,48 @@ int num_online_cpus()
27 return sysconf(_SC_NPROCESSORS_ONLN); 27 return sysconf(_SC_NPROCESSORS_ONLN);
28} 28}
29 29
30int partition_to_cpu(int partition) 30static int read_mapping(int idx, const char* which, unsigned long long int* mask)
31{ 31{
32 int cpu = partition; 32 int ret = -1;
33 int master = release_master(); 33 char buf[129] = {0};
34 if (master != -1 && master <= cpu) { 34 char fname[80] = {0};
35 ++cpu; /* skip over the release master */ 35
36 if (num_online_cpus() > 64) {
37 /* XXX: Support more than 64 CPUs.
38 * User can still set appropriate values directly. */
39 goto out;
36 } 40 }
37 return cpu;
38}
39 41
40int cluster_to_first_cpu(int cluster, int cluster_sz) 42 snprintf(fname, sizeof(fname), "/proc/litmus/%s/%d", which, idx);
41{ 43
42 int first_cpu; 44 ret = read_file(fname, &buf, sizeof(buf)-1);
43 int master; 45 if (ret <= 0)
46 goto out;
44 47
45 if (cluster_sz == 1) 48 *mask = strtoull(buf, NULL, 16);
46 return partition_to_cpu(cluster); 49 ret = 0;
47 50
48 master = release_master(); 51out:
49 first_cpu = cluster * cluster_sz; 52 return ret;
53}
54
55int domain_to_cpus(int domain, unsigned long long int* mask)
56{
57 return read_mapping(domain, "domains", mask);
58}
50 59
51 if (master == first_cpu) 60int cpu_to_domains(int cpu, unsigned long long int* mask)
52 ++first_cpu; 61{
62 return read_mapping(cpu, "cpus", mask);
63}
53 64
54 return first_cpu; 65int domain_to_first_cpu(int domain)
66{
67 unsigned long long int mask;
68 int ret = domain_to_cpus(domain, &mask);
69 if(ret == 0)
70 return (ffsll(mask)-1);
71 return ret;
55} 72}
56 73
57int be_migrate_thread_to_cpu(pid_t tid, int target_cpu) 74int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
@@ -89,44 +106,29 @@ int be_migrate_thread_to_cpu(pid_t tid, int target_cpu)
89 return ret; 106 return ret;
90} 107}
91 108
92int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz) 109int be_migrate_thread_to_domain(pid_t tid, int domain)
93{
94 return __be_migrate_thread_to_cluster(tid, cluster, cluster_sz, 0);
95}
96
97int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
98 int ignore_rm)
99{ 110{
100 int first_cpu = cluster * cluster_sz; /* first CPU in cluster */ 111 int ret, num_cpus;
101 int last_cpu = first_cpu + cluster_sz - 1;
102 int master;
103 int num_cpus;
104 cpu_set_t *cpu_set; 112 cpu_set_t *cpu_set;
105 size_t sz; 113 size_t sz;
106 int i; 114 unsigned long long int mask;
107 int ret;
108
109 /* TODO: Error check to make sure that tid is not a real-time task. */
110 115
111 if (cluster_sz == 1) { 116 ret = domain_to_cpus(domain, &mask);
112 /* we're partitioned */ 117 if (ret != 0)
113 return be_migrate_thread_to_partition(tid, cluster); 118 return ret;
114 }
115 119
116 master = (ignore_rm) ? -1 : release_master();
117 num_cpus = num_online_cpus(); 120 num_cpus = num_online_cpus();
118 121 if (num_cpus == -1)
119 if (num_cpus == -1 || last_cpu >= num_cpus || first_cpu < 0)
120 return -1; 122 return -1;
121 123
122 cpu_set = CPU_ALLOC(num_cpus); 124 cpu_set = CPU_ALLOC(num_cpus);
123 sz = CPU_ALLOC_SIZE(num_cpus); 125 sz = CPU_ALLOC_SIZE(num_cpus);
124 CPU_ZERO_S(sz, cpu_set); 126 CPU_ZERO_S(sz, cpu_set);
125 127
126 for (i = first_cpu; i <= last_cpu; ++i) { 128 while(mask) {
127 if (i != master) { 129 int idx = ffsll(mask) - 1;
128 CPU_SET_S(i, sz, cpu_set); 130 CPU_SET_S(idx, sz, cpu_set);
129 } 131 mask &= ~(1ull<<idx);
130 } 132 }
131 133
132 /* apply to caller */ 134 /* apply to caller */
@@ -140,23 +142,30 @@ int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz,
140 return ret; 142 return ret;
141} 143}
142 144
143int be_migrate_thread_to_partition(pid_t tid, int partition) 145int be_migrate_to_cpu(int target_cpu)
146{
147 return be_migrate_thread_to_cpu(0, target_cpu);
148}
149
150int be_migrate_to_domain(int domain)
144{ 151{
145 return be_migrate_thread_to_cpu(tid, partition_to_cpu(partition)); 152 return be_migrate_thread_to_domain(0, domain);
146} 153}
147 154
148 155
149int be_migrate_to_cpu(int target_cpu) 156/* deprecated functions. */
157
158int be_migrate_to_cluster(int cluster, int cluster_size)
150{ 159{
151 return be_migrate_thread_to_cpu(0, target_cpu); 160 return be_migrate_to_domain(cluster);
152} 161}
153 162
154int be_migrate_to_cluster(int cluster, int cluster_sz) 163int cluster_to_first_cpu(int cluster, int cluster_size)
155{ 164{
156 return be_migrate_thread_to_cluster(0, cluster, cluster_sz); 165 return domain_to_first_cpu(cluster);
157} 166}
158 167
159int be_migrate_to_partition(int partition) 168int partition_to_cpu(int partition)
160{ 169{
161 return be_migrate_thread_to_partition(0, partition); 170 return domain_to_first_cpu(partition);
162} 171}
diff --git a/src/task.c b/src/task.c
index 5f2fa26..35bad66 100644
--- a/src/task.c
+++ b/src/task.c
@@ -40,11 +40,11 @@ int __launch_rt_task(rt_fn_t rt_prog, void *rt_arg, rt_setup_fn_t setup,
40 return rt_task; 40 return rt_task;
41} 41}
42 42
43int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, 43int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
44 lt_t wcet, lt_t period, unsigned int priority, task_class_t class) 44 lt_t wcet, lt_t period, unsigned int priority, task_class_t class)
45{ 45{
46 struct rt_task params; 46 struct rt_task params;
47 params.cpu = cluster_to_first_cpu(cluster, cluster_size); 47 params.cpu = domain_to_first_cpu(cluster);
48 params.period = period; 48 params.period = period;
49 params.exec_cost = wcet; 49 params.exec_cost = wcet;
50 params.cls = class; 50 params.cls = class;
@@ -57,10 +57,10 @@ int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size,
57 (rt_setup_fn_t) set_rt_task_param, &params); 57 (rt_setup_fn_t) set_rt_task_param, &params);
58} 58}
59 59
60int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, 60int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster,
61 lt_t wcet, lt_t period, unsigned int prio) 61 lt_t wcet, lt_t period, unsigned int prio)
62{ 62{
63 return __create_rt_task(rt_prog, arg, cluster, cluster_size, wcet, period, 63 return __create_rt_task(rt_prog, arg, cluster, wcet, period,
64 prio, RT_CLASS_HARD); 64 prio, RT_CLASS_HARD);
65} 65}
66 66