Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
typon-concurrency
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
typon
typon-concurrency
Commits
f79f9af7
Commit
f79f9af7
authored
Aug 06, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable opt-in deferred reclamation of forks
parent
673cea98
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
60 additions
and
18 deletions
+60
-18
rt/include/typon/fork.hpp
rt/include/typon/fork.hpp
+43
-14
rt/include/typon/forked.hpp
rt/include/typon/forked.hpp
+4
-4
rt/include/typon/span.hpp
rt/include/typon/span.hpp
+13
-0
No files found.
rt/include/typon/fork.hpp
View file @
f79f9af7
...
...
@@ -63,14 +63,18 @@ namespace typon
{
return
span
->
_coroutine
;
}
auto
rank
=
coroutine
.
promise
().
_rank
;
if
(
auto
&
exception
=
coroutine
.
promise
().
_exception
)
{
span
->
set_exception
(
exception
,
coroutine
.
promise
().
_
rank
);
span
->
set_exception
(
exception
,
rank
);
}
auto
&
ref
=
coroutine
.
promise
().
_node
.
_ref
;
if
(
!
ref
.
exchange
(
false
,
std
::
memory_order_acq_rel
))
if
(
!
(
rank
&
1
))
{
coroutine
.
destroy
();
auto
&
ref
=
coroutine
.
promise
().
_node
.
_ref
;
if
(
!
ref
.
exchange
(
false
,
std
::
memory_order_acq_rel
))
{
coroutine
.
destroy
();
}
}
u64
n
=
span
->
_n
.
fetch_sub
(
1
,
std
::
memory_order_acq_rel
);
if
(
n
==
1
)
...
...
@@ -85,25 +89,45 @@ namespace typon
}
};
struct
awaitable
struct
awaitable
:
std
::
suspend_always
{
std
::
coroutine_handle
<
promise_type
>
_coroutine
;
awaitable
(
std
::
coroutine_handle
<
promise_type
>
coroutine
)
noexcept
:
_coroutine
(
coroutine
)
{}
template
<
typename
Promise
>
auto
await_suspend
(
std
::
coroutine_handle
<
Promise
>
continuation
)
noexcept
{
Span
*
span
=
&
(
continuation
.
promise
().
_span
);
_coroutine
.
promise
().
_span
=
span
;
_coroutine
.
promise
().
_rank
=
(
span
->
_thefts
<<
1
);
bool
await_ready
()
noexcept
std
::
coroutine_handle
<>
on_stack_handle
=
_coroutine
;
Scheduler
::
push
(
span
);
return
on_stack_handle
;
}
auto
await_resume
()
{
return
false
;
auto
thefts
=
_coroutine
.
promise
().
_span
->
_thefts
;
auto
rank
=
_coroutine
.
promise
().
_rank
;
return
Forked
<
T
>
(
_coroutine
,
(
thefts
==
(
rank
>>
1
)),
true
);
}
};
auto
operator
co_await
()
&&
{
return
awaitable
{
{},
_coroutine
};
}
struct
noloop_awaitable
:
std
::
suspend_always
{
std
::
coroutine_handle
<
promise_type
>
_coroutine
;
template
<
typename
Promise
>
auto
await_suspend
(
std
::
coroutine_handle
<
Promise
>
continuation
)
noexcept
{
Span
*
span
=
&
(
continuation
.
promise
().
_span
);
_coroutine
.
promise
().
_span
=
span
;
_coroutine
.
promise
().
_rank
=
span
->
_thefts
;
_coroutine
.
promise
().
_rank
=
(
span
->
_thefts
<<
1
)
+
1
;
std
::
coroutine_handle
<>
on_stack_handle
=
_coroutine
;
Scheduler
::
push
(
span
);
...
...
@@ -114,13 +138,18 @@ namespace typon
{
auto
thefts
=
_coroutine
.
promise
().
_span
->
_thefts
;
auto
rank
=
_coroutine
.
promise
().
_rank
;
return
Forked
<
T
>
(
_coroutine
,
(
thefts
==
rank
));
bool
ready
=
thefts
==
(
rank
>>
1
);
if
(
!
ready
)
{
_coroutine
.
promise
().
_span
->
_children
.
push_back
(
_coroutine
);
}
return
Forked
<
T
>
(
_coroutine
,
ready
,
false
);
}
};
auto
operator
co_await
()
&&
auto
noloop
()
&&
{
return
awaitable
{
_coroutine
};
return
noloop_awaitable
{
{},
_coroutine
};
}
};
...
...
rt/include/typon/forked.hpp
View file @
f79f9af7
...
...
@@ -111,7 +111,7 @@ namespace typon
Result
<
T
>
*
_result
=
nullptr
;
template
<
typename
Promise
>
Forked
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
)
Forked
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
,
bool
owning
)
{
if
(
ready
)
{
...
...
@@ -120,7 +120,7 @@ namespace typon
}
else
{
this
->
_node
=
&
(
coroutine
.
promise
().
_node
)
;
this
->
_node
=
owning
?
&
(
coroutine
.
promise
().
_node
)
:
nullptr
;
_result
=
&
(
coroutine
.
promise
());
}
}
...
...
@@ -197,11 +197,11 @@ namespace typon
ForkNode
*
_node
;
template
<
typename
Promise
>
Forked
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
)
Forked
(
std
::
coroutine_handle
<
Promise
>
coroutine
,
bool
ready
,
bool
owning
)
{
_ready
=
ready
;
_result
=
&
(
coroutine
.
promise
());
_node
=
&
(
coroutine
.
promise
().
_node
)
;
_node
=
(
owning
|
ready
)
?
&
(
coroutine
.
promise
().
_node
)
:
nullptr
;
if
(
ready
)
{
if
(
auto
&
exception
=
coroutine
.
promise
().
_exception
)
...
...
rt/include/typon/span.hpp
View file @
f79f9af7
...
...
@@ -7,6 +7,7 @@
#include <cstdint>
#include <exception>
#include <limits>
#include <vector>
#include <typon/defer.hpp>
#include <typon/theft_point.hpp>
...
...
@@ -31,6 +32,8 @@ namespace typon
std
::
atomic
<
Error
*>
_error
{
nullptr
};
std
::
vector
<
std
::
coroutine_handle
<>>
_children
;
std
::
atomic
<
u64
>
_n
=
UMAX
;
Span
(
std
::
coroutine_handle
<>
coroutine
)
noexcept
...
...
@@ -43,6 +46,16 @@ namespace typon
{
delete
error
;
}
clear_children
();
}
void
clear_children
()
noexcept
{
for
(
auto
&
child
:
_children
)
{
child
.
destroy
();
}
_children
.
clear
();
}
void
check_exception
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment