Skip to content

Commit

Permalink
gec: fixed bug in SCOOP when there are several separate arguments and…
Browse files Browse the repository at this point in the history
… we already have a lock on one of them.
  • Loading branch information
ebezault committed Dec 30, 2024
2 parents 4b9586b + 7c04c50 commit c475cb9
Show file tree
Hide file tree
Showing 37 changed files with 688 additions and 24 deletions.
83 changes: 65 additions & 18 deletions tool/gec/backend/c/runtime/ge_scoop.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,44 @@ static GE_scoop_session* GE_new_scoop_session(GE_scoop_region* a_callee)
*/
static EIF_MUTEX_TYPE* GE_scoop_multisessions_open_mutex;

/*
* SCOOP condition to enter multiple SCOOP sessions.
*/
static GE_scoop_condition* GE_scoop_multisessions_condition;

/*
* Start opening multiple SCOOP sessions (for example in
* a feature with several separate arguments.)
*/
void GE_scoop_multisessions_open_start()
{
GE_mutex_lock((EIF_POINTER)GE_scoop_multisessions_open_mutex);
GE_scoop_multisessions_condition = 0;
}

/*
* Wait until all processors involved in `a_condition' are synchronized.
*/
static void GE_scoop_condition_wait(GE_scoop_condition* a_condition)
{
char l_to_be_freed = 0;

GE_scoop_condition_decrement(a_condition);
GE_mutex_lock(a_condition->mutex);
if (a_condition->wait_counter > 0) {
GE_condition_variable_wait((EIF_POINTER)a_condition->condition_variable, (EIF_POINTER)a_condition->mutex);
if (a_condition->trigger_counter > 0) {
a_condition->trigger_counter--;
}
if (a_condition->trigger_counter == 0) {
/* No more session to wake-up. */
l_to_be_freed = '\1';
}
}
GE_mutex_unlock(a_condition->mutex);
if (l_to_be_freed) {
GE_free_scoop_condition(a_condition);
}
}

/*
Expand All @@ -249,7 +280,13 @@ void GE_scoop_multisessions_open_start()
*/
void GE_scoop_multisessions_open_stop()
{
GE_scoop_condition* l_condition = GE_scoop_multisessions_condition;

GE_scoop_multisessions_condition = 0;
GE_mutex_unlock((EIF_POINTER)GE_scoop_multisessions_open_mutex);
if (l_condition) {
GE_scoop_condition_wait(l_condition);
}
}

/*
Expand Down Expand Up @@ -282,6 +319,32 @@ static void GE_scoop_session_add_condition(GE_scoop_region* a_caller, GE_scoop_s
}
}

/*
* Add a synchronization between the current processor and
* other processors involved in `a_condition'.
*/
static void GE_scoop_current_session_add_condition(GE_scoop_condition* a_condition)
{
if (a_condition->wait_counter > 1) {
if (!GE_scoop_multisessions_condition) {
GE_scoop_multisessions_condition = a_condition;
GE_mutex_lock((EIF_POINTER)a_condition->mutex);
a_condition->wait_counter++;
a_condition->trigger_counter++;
GE_mutex_unlock((EIF_POINTER)a_condition->mutex);
}
} else {
if (GE_scoop_multisessions_condition) {
GE_mutex_lock((EIF_POINTER)a_condition->mutex);
a_condition->wait_counter--;
a_condition->trigger_counter--;
GE_mutex_unlock((EIF_POINTER)a_condition->mutex);
}
GE_scoop_multisessions_condition = 0;
}
GE_scoop_condition_decrement(a_condition);
}

/*
* Create (or reuse an existing) SCOOP session to register calls from
* `a_caller' to be executed by `a_callee'.
Expand Down Expand Up @@ -322,7 +385,7 @@ GE_scoop_session* GE_scoop_session_open(GE_scoop_region* a_caller, GE_scoop_regi
if (l_session && !l_has_lock) {
GE_scoop_session_add_condition(a_caller, l_session, a_condition);
} else {
GE_scoop_condition_decrement(a_condition);
GE_scoop_current_session_add_condition(a_condition);
}
}
return l_session;
Expand Down Expand Up @@ -627,7 +690,6 @@ static void GE_scoop_call_execute(GE_context* a_context, GE_scoop_session* a_ses
GE_context l_old_context;
char l_is_synchronous = a_call->is_synchronous;
GE_rescue r;
char l_to_be_freed = 0;

l_caller = a_call->caller;
l_callee = a_session->callee;
Expand Down Expand Up @@ -677,22 +739,7 @@ static void GE_scoop_call_execute(GE_context* a_context, GE_scoop_session* a_ses
}
} else if (a_call->is_condition) {
GE_scoop_condition* l_condition = ((GE_scoop_condition_call*)a_call)->condition;
GE_scoop_condition_decrement(l_condition);
GE_mutex_lock(l_condition->mutex);
if (l_condition->wait_counter > 0) {
GE_condition_variable_wait((EIF_POINTER)l_condition->condition_variable, (EIF_POINTER)l_condition->mutex);
if (l_condition->trigger_counter > 0) {
l_condition->trigger_counter--;
}
if (l_condition->trigger_counter == 0) {
/* No more session to wake-up. */
l_to_be_freed = '\1';
}
}
GE_mutex_unlock(l_condition->mutex);
if (l_to_be_freed) {
GE_free_scoop_condition(l_condition);
}
GE_scoop_condition_wait(l_condition);
}
if (l_is_synchronous) {
GE_mutex_lock((EIF_POINTER)l_caller->sync_mutex);
Expand Down
4 changes: 2 additions & 2 deletions tool/gecop/validation/last_run_gec.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Running Test Cases

Test Summary for validation

# PASSED: 673 tests
# PASSED: 676 tests
# Failed: 0 test
# Aborted: 0 test
# Total: 673 tests
# Total: 676 tests
4 changes: 2 additions & 2 deletions tool/gecop/validation/last_run_gelint.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Running Test Cases

Test Summary for validation

# PASSED: 673 tests
# PASSED: 676 tests
# Failed: 0 test
# Aborted: 0 test
# Total: 673 tests
# Total: 676 tests
4 changes: 2 additions & 2 deletions tool/gecop/validation/last_run_ise.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Running Test Cases

Test Summary for validation

# Passed: 518 tests
# Passed: 521 tests
# FAILED: 155 tests
# Aborted: 0 test
# Total: 673 tests
# Total: 676 tests

Test Results:</br>
FAIL: \[[definition/difo1/test\_bar\_2](definition/difo1/test\_bar\_2)\] test\_failed</br>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Semantics M9EA

This [test](.) is exercising the semantics rule [M9EA](../Readme.md).

### Description

In this test, there is feature `DD.f` with two separate arguments, one of them, `b`, being part of the current SCOOP region. So the call is synchronous, but the feature has to make sure that it has the lock on the region of the second separate argument, `c`, to avoid deadlock. This means that no separate call to the region of `c` triggered from a different SCOOP region may occur while in the middle of the execution of `DD.f`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class AA

create

make

feature

make
local
c: separate CC
d: separate DD
do
create c.make
create d.make (c)
f (d)
end

f (d: separate DD)
do
d.g
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class BB

create

make

feature

make (a_c: separate CC)
do
c := a_c
end

c: separate CC

f (s: separate STRING)
do
print (create {STRING}.make_from_separate (s) + " calling BB.f%N")
g
{EXECUTION_ENVIRONMENT}.sleep (100_000_000)
end

g
local
b: separate BB
do
create b.make (c)
x (b)
end

x (a_b: separate BB)
do
a_b.y
end

y
do
z (c)
end

z (a_c: separate CC)
do
a_c.f ("BB")
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>

<project name="aa" default="help">

<description>
description: "Eiffel Ant file for 'aa'"
copyright: "Copyright (c) 2023, Eric Bezault and others"
license: "MIT License"
</description>

<inherit>
<parent location="${GOBO}/library/common/config/eiffel.eant">
<redefine target="init_system"/>
</parent>
</inherit>

<!-- Implementation -->

<target name="init_system" export="NONE">
<set name="system" value="aa"/>
<set name="system_dir" value="${aa.dir}"/>
</target>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class CC

create

make

feature

make
do
end

f (s: separate STRING)
do
print (create {STRING}.make_from_separate (s) + " calling CC.f%N")
{EXECUTION_ENVIRONMENT}.sleep (100_000_000)
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class DD

create

make

feature

make (a_c: separate CC)
do
c := a_c
end

c: separate CC

g
local
b: BB
do
create b.make (c)
f (b, c)
end

f (a_b: separate BB; a_c: separate CC)
do
a_b.f ("DD")
print ("DD middle f%N")
a_c.f ("DD")
print ("DD end f%N")
end

end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DD calling BB.f
DD middle f
DD calling CC.f
DD end f
BB calling CC.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
DD calling BB.f
DD middle f
DD calling CC.f
DD end f
BB calling CC.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system
xmlns="http://www.eiffel.com/developers/xml/configuration-1-20-0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-20-0 http://www.eiffel.com/developers/xml/configuration-1-20-0.xsd"
name="aa"
>
<description>
system: "aa"
copyright: "Copyright (c) 2023, Eric Bezault and others"
license: "MIT License"
</description>
<target name="aa">
<root class="AA" feature="make"/>
<file_rule>
<exclude>/\.svn$</exclude>
<exclude>/\.git$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true"/>
<setting name="console_application" value="true"/>
<capability>
<concurrency support="scoop"/>
</capability>
<variable name="GOBO_LIBRARY" value="../../../../../.."/>
<library name="free_elks" location="${GOBO_LIBRARY}/library/free_elks/library.ecf" readonly="true"/>
<cluster name="aa" location="./"/>
</target>
</system>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Semantics M9EA

This [test](.) is exercising the semantics rule [M9EA](../Readme.md).

### Description

In this test, there is feature `DD.f` with two separate arguments. The feature already has the lock on the SCOOP region of the first separate argument `b`. So the call is synchronous, but the feature has to make sure that it also has the lock on the region of the second separate argument, `c`, to avoid deadlock. This means that no separate call to the region of `c` triggered from a different SCOOP region may occur while in the middle of the execution of `DD.f`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class AA

create

make

feature

make
local
c: separate CC
d: separate DD
do
create c.make
create d.make (c)
f (d)
end

f (d: separate DD)
do
d.g
end

end
Loading

0 comments on commit c475cb9

Please sign in to comment.