diff options
author | Vincent Guittot <vincent.guittot@linaro.org> | 2014-07-07 17:20:52 +0200 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2014-08-01 15:31:19 +0200 |
commit | 6a4634d507efbbc35776075f2281835419d09f89 (patch) | |
tree | 7f162304ae9b9ec7901d7730b27fd276820f1ac6 | |
parent | 09e70d8c76f2e52509954b626baaac9fd6d6754c (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.json | 99 | ||||
-rw-r--r-- | src/rt-app.c | 6 | ||||
-rw-r--r-- | src/rt-app_parse_config.c | 1 | ||||
-rw-r--r-- | src/rt-app_types.h | 3 | ||||
-rw-r--r-- | src/rt-app_utils.c | 5 |
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; |