summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2014-07-07 17:20:52 +0200
committerVincent Guittot <vincent.guittot@linaro.org>2014-08-01 15:31:19 +0200
commit6a4634d507efbbc35776075f2281835419d09f89 (patch)
tree7f162304ae9b9ec7901d7730b27fd276820f1ac6
parent09e70d8c76f2e52509954b626baaac9fd6d6754c (diff)
resource: new sync resource
new resources that ensure an atomic : signal and wait sequence With 2 tasks that wake up each, we can have the situation that the wakee preempts the waker before the later waits on condition. This leads to a situation where both tasks are waiting to be woken up by the other one Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
-rw-r--r--doc/taskset.json99
-rw-r--r--src/rt-app.c6
-rw-r--r--src/rt-app_parse_config.c1
-rw-r--r--src/rt-app_types.h3
-rw-r--r--src/rt-app_utils.c5
5 files changed, 65 insertions, 49 deletions
diff --git a/doc/taskset.json b/doc/taskset.json
index 25b39e0..8f5d6e6 100644
--- a/doc/taskset.json
+++ b/doc/taskset.json
@@ -1,68 +1,71 @@
{
/*"resources" : 4,*/
"resources" : {
- "m0" : { "type" : "mutex" },
- "sync_mutex" : { "type" : "mutex" },
- "wait" : { "type" : "wait" },
- "trig" : { "type" : "signal", "target" : "wait" },
- "m1" : { "type" : "mutex" },
- "wake" : { "type" : "wait" },
- "broad" : { "type" : "broadcast", "target" : "wake" },
- "m2" : { "type" : "mutex" },
- "s1" : { "type" : "sleep" },
- "s2" : { "type" : "sleep" },
- "r1" : { "type" : "run" },
- "r2" : { "type" : "run" },
+ "trig1_mutex" : { "type" : "mutex" },
+ "wait1" : { "type" : "wait" },
+ "trig1" : { "type" : "signal", "target" : "wait1" },
+ "trig2_mutex" : { "type" : "mutex" },
+ "wait2" : { "type" : "wait" },
+ "trig2" : { "type" : "signal", "target" : "wait2" },
+ "trig3_mutex" : { "type" : "mutex" },
+ "wait3" : { "type" : "wait" },
+ "trig3" : { "type" : "signal", "target" : "wait3" },
+ "sync3" : { "type" : "sync", "target" : "wait3" },
+ "trig4_mutex" : { "type" : "mutex" },
+ "wait4" : { "type" : "wait" },
+ "trig4" : { "type" : "signal", "target" : "wait4" },
+ "r0" : { "type" : "run" },
},
"tasks" : {
- "thread0" : {
- "exec" : 1000,
- "period" : 20000,
- "deadline" : 8000,
- "cpus" : [0],
- "lock_order" : ["r1", "m0", "trig"],
+ "AudioOut" : {
+ "exec" : 5000,
+ "period" : 24000,
+ "deadline" : 24000,
+ "priority" : -19,
+ "cpus": [0],
+ "lock_order" : ["r0", "trig1"],
"resources" : {
- "r1" : { "duration" : 200 },
- "m0" : { "duration" : 500 },
- "trig" : { "duration" : 0, "access": ["sync_mutex"] },
+ "r0" : { "duration" : 275 },
+ "trig1" : { "duration" : 0 },
}
},
- "thread1" : {
- "exec" : 5000,
- "period" : 20000,
+ "AudioTrack" : {
+ "exec" : 300,
+ "period" : 24000,
+ "deadline" : 24000,
+ "priority" : -16,
"sleep" : false,
- "lock_order" : ["wait", "m0", "broad", "r1", "broad"],
+ "lock_order" : ["wait1", "r0", "trig2"],
"resources" : {
- "wait" : { "duration" : 0, "access": ["sync_mutex"] },
- "m0" : { "duration" : 1000 },
- "broad" : { "duration" : 0},
- "r1" : { "duration" : 1000 },
+ "wait1" : { "duration" : 0, "access": ["trig1_mutex"] },
+ "r0" : { "duration" : 300 },
+ "trig2" : { "duration" : 0 },
}
},
- "thread2" : {
- "loop" : 100,
- "exec" : 1000,
- "period" : 20000,
+ "mp3.decoder" : {
+ "exec" : 1150,
+ "period" : 24000,
+ "deadline" : 24000,
+ "priority" : -2,
"sleep" : false,
- "lock_order" : ["wake", "m2", "wake", "m2"],
+ "lock_order" : ["wait2", "r0", "sync3"],
"resources" : {
- "wake" : { "duration" : 0, "access": ["m1"] },
- "m2" : { "duration" : 200 },
+ "wait2" : { "duration" : 0, "access": ["trig2_mutex"] },
+ "r0" : { "duration" : 1000 },
+ "sync3" : { "duration" : 0, "access": ["trig3_mutex"] },
}
},
- "thread3" : {
- "exec" : 1000,
- "period" : 20000,
- "deadline" : 15000,
- "delay" : 15000,
- "sleep" : true,
- "lock_order" : ["r1", "s1", "r1", "s2", "r2" ],
+ "OMXCall" : {
+ "exec" : 300,
+ "period" : 24000,
+ "deadline" : 24000,
+ "priority" : -2,
+ "sleep" : false,
+ "lock_order" : ["wait3", "r0", "trig3"],
"resources" : {
- "wake" : { "duration" : 0, "access": ["m1"] },
- "r1" : { "duration" : 200 },
- "s1" : { "duration" : 2000 },
- "r2" : { "duration" : 200 },
- "s2" : { "duration" : 1000 },
+ "wait3" : { "duration" : 0, "access": ["trig3_mutex"] },
+ "r0" : { "duration" : 300 },
+ "trig3" : { "duration" : 0, "access": ["trig3_mutex"] },
}
},
},
diff --git a/src/rt-app.c b/src/rt-app.c
index c8d509e..682750d 100644
--- a/src/rt-app.c
+++ b/src/rt-app.c
@@ -132,6 +132,11 @@ int get_resource(rtapp_resource_access_list_t *lock, struct timespec *usage)
case rtapp_signal:
pthread_cond_signal(lock->res->res.signal.target);
break;
+ case rtapp_sig_and_wait:
+ pthread_cond_signal(lock->res->res.signal.target);
+ prev = lock->prev;
+ pthread_cond_wait(lock->res->res.signal.target, &(prev->res->res.mtx.obj));
+ break;
case rtapp_broadcast:
pthread_cond_broadcast(lock->res->res.signal.target);
break;
@@ -219,6 +224,7 @@ shutdown(int sig)
for (i = 0; i < opts.nresources; i++) {
switch (opts.resources[i].type) {
+ case rtapp_sig_and_wait:
case rtapp_signal:
case rtapp_broadcast:
pthread_cond_broadcast(opts.resources[i].res.signal.target);
diff --git a/src/rt-app_parse_config.c b/src/rt-app_parse_config.c
index 4fdb2a6..41b6941 100644
--- a/src/rt-app_parse_config.c
+++ b/src/rt-app_parse_config.c
@@ -232,6 +232,7 @@ parse_resource_data(char *name, struct json_object *obj, int idx,
break;
case rtapp_signal:
case rtapp_broadcast:
+ case rtapp_sig_and_wait:
target = get_string_value_from(obj, "target", FALSE, NULL);
init_signal_resource(data, opts, target);
break;
diff --git a/src/rt-app_types.h b/src/rt-app_types.h
index a14bd5b..d7587ae 100644
--- a/src/rt-app_types.h
+++ b/src/rt-app_types.h
@@ -62,7 +62,8 @@ typedef enum resource_t
rtapp_signal,
rtapp_broadcast,
rtapp_sleep,
- rtapp_run
+ rtapp_run,
+ rtapp_sig_and_wait,
} resource_t;
struct _rtapp_mutex {
diff --git a/src/rt-app_utils.c b/src/rt-app_utils.c
index 354cdb5..0b1ef48 100644
--- a/src/rt-app_utils.c
+++ b/src/rt-app_utils.c
@@ -228,6 +228,8 @@ string_to_resource(const char *name, resource_t *resource)
*resource = rtapp_wait;
else if (strcmp(name, "broadcast") == 0)
*resource = rtapp_broadcast;
+ else if (strcmp(name, "sync") == 0)
+ *resource = rtapp_sig_and_wait;
else if (strcmp(name, "sleep") == 0)
*resource = rtapp_sleep;
else if (strcmp(name, "run") == 0)
@@ -253,6 +255,9 @@ resource_to_string(resource_t resource, char *resource_name)
case rtapp_broadcast:
strcpy(resource_name, "broadcast");
break;
+ case rtapp_sig_and_wait:
+ strcpy(resource_name, "sync");
+ break;
case rtapp_sleep:
strcpy(resource_name, "sleep");
break;