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
Xavier Thompson
typon-concurrency
Commits
c57ef80c
Commit
c57ef80c
authored
May 06, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move optional to fundamental and adapt / arrange deque
parent
da6a6cde
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
98 additions
and
68 deletions
+98
-68
rt/include/typon/deque.hpp
rt/include/typon/deque.hpp
+27
-65
rt/include/typon/fork.hpp
rt/include/typon/fork.hpp
+1
-1
rt/include/typon/fundamental/optional.hpp
rt/include/typon/fundamental/optional.hpp
+67
-0
rt/include/typon/scheduler.hpp
rt/include/typon/scheduler.hpp
+3
-2
No files found.
rt/include/typon/deque.hpp
View file @
c57ef80c
...
...
@@ -4,13 +4,17 @@
#include <atomic>
#include <cstdint>
#include <memory>
#include <type_traits>
#include <utility>
#include <typon/fundamental/optional.hpp>
namespace
typon
{
template
<
typename
T
>
requires
std
::
is_trivially_copyable_v
<
T
>
struct
RingBuffer
{
using
u8
=
std
::
uint_least8_t
;
...
...
@@ -75,57 +79,16 @@ namespace typon
};
template
<
typename
T
>
struct
Optional
{
enum
State
:
unsigned
char
{
empty
=
0
,
abort
=
1
,
engaged
=
2
};
State
_state
;
union
{
T
_value
;
};
Optional
(
State
state
=
empty
)
noexcept
:
_state
(
state
)
{}
Optional
(
T
value
)
noexcept
:
_state
(
engaged
),
_value
(
value
)
{}
~
Optional
()
{
if
(
_state
==
engaged
)
{
std
::
destroy_at
(
std
::
addressof
(
_value
));
}
}
operator
bool
()
noexcept
{
return
_state
==
engaged
;
}
State
state
()
noexcept
{
return
_state
;
}
T
*
operator
->
()
noexcept
{
return
std
::
addressof
(
_value
);
}
T
&
operator
*
()
noexcept
{
return
_value
;
}
};
template
<
typename
T
>
struct
Deque
{
using
u8
=
typename
RingBuffer
<
T
>::
u8
;
using
u64
=
typename
RingBuffer
<
T
>::
u64
;
using
Array
=
RingBuffer
<
T
>
;
using
Pop
=
fdt
::
optional
<
T
,
2
>
;
static
constexpr
typename
Pop
::
template
state
<
0
>
Empty
{};
static
constexpr
typename
Pop
::
template
state
<
1
>
Abort
{};
using
enum
std
::
memory_order
;
...
...
@@ -157,49 +120,48 @@ namespace typon
_bottom
.
store
(
bottom
+
1
,
relaxed
);
}
Optional
<
T
>
pop
()
noexcept
Pop
pop
()
noexcept
{
u64
bottom
=
_bottom
.
load
(
relaxed
)
-
1
;
Array
*
array
=
_array
.
load
(
relaxed
);
_bottom
.
store
(
bottom
,
relaxed
);
std
::
atomic_thread_fence
(
seq_cst
);
u64
top
=
_top
.
load
(
relaxed
);
Optional
<
T
>
x
{};
if
(
top
<=
bottom
)
if
(
top
>
bottom
)
{
x
=
array
->
get
(
bottom
);
if
(
top
==
bottom
)
{
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
{
x
=
{};
}
_bottom
.
store
(
bottom
+
1
,
relaxed
);
}
_bottom
.
store
(
top
,
relaxed
);
return
{
Empty
};
}
T
x
=
array
->
get
(
bottom
);
if
(
top
<
bottom
)
{
return
{
x
};
}
else
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
{
_bottom
.
store
(
bottom
+
1
,
relaxed
);
_bottom
.
store
(
top
+
1
,
relaxed
);
return
{
Empty
};
}
return
x
;
_bottom
.
store
(
top
+
1
,
relaxed
);
return
{
x
};
}
Optional
<
T
>
steal
()
noexcept
Pop
steal
()
noexcept
{
u64
top
=
_top
.
load
(
acquire
);
std
::
atomic_thread_fence
(
seq_cst
);
u64
bottom
=
_bottom
.
load
(
acquire
);
Optional
<
T
>
x
{};
if
(
top
<
bottom
)
{
Array
*
array
=
_array
.
load
(
consume
);
x
=
array
->
get
(
top
);
T
x
=
array
->
get
(
top
);
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
{
return
{
Optional
<
T
>::
abort
};
return
{
Abort
};
}
return
{
x
};
}
return
x
;
return
{
Empty
}
;
}
};
...
...
rt/include/typon/fork.hpp
View file @
c57ef80c
...
...
@@ -51,7 +51,7 @@ namespace typon
{
std
::
coroutine_handle
<>
await_suspend
(
std
::
coroutine_handle
<
promise_type
>
coroutine
)
noexcept
{
if
(
Optional
continuation
=
Scheduler
::
pop
())
if
(
auto
continuation
=
Scheduler
::
pop
())
{
return
*
continuation
;
}
...
...
rt/include/typon/fundamental/optional.hpp
0 → 100644
View file @
c57ef80c
#ifndef TYPON_FUNDAMENTAL_OPTIONAL_HPP_INCLUDED
#define TYPON_FUNDAMENTAL_OPTIONAL_HPP_INCLUDED
#include <type_traits>
namespace
typon
::
fdt
{
template
<
typename
T
,
unsigned
char
N
>
requires
std
::
is_trivially_copyable_v
<
T
>
struct
optional
{
static_assert
(
N
>
0
,
"N must be greater than 0"
);
template
<
unsigned
char
I
>
requires
(
I
<=
N
)
using
state
=
std
::
integral_constant
<
unsigned
char
,
I
>
;
unsigned
char
_state
;
union
{
T
_value
;
};
optional
()
noexcept
:
_state
(
0
)
{}
template
<
unsigned
char
I
>
requires
(
I
<
N
)
optional
(
state
<
I
>
state
)
noexcept
:
_state
(
state
)
{}
optional
(
T
value
)
noexcept
:
_state
(
N
),
_value
(
value
)
{}
~
optional
()
{
if
(
_state
==
N
)
{
std
::
destroy_at
(
std
::
addressof
(
_value
));
}
}
operator
bool
()
noexcept
{
return
_state
==
N
;
}
template
<
unsigned
char
I
>
bool
match
(
state
<
I
>
state
)
noexcept
{
return
state
()
==
_state
;
}
T
*
operator
->
()
noexcept
{
return
std
::
addressof
(
_value
);
}
T
&
operator
*
()
noexcept
{
return
_value
;
}
};
}
#endif // TYPON_FUNDAMENTAL_OPTIONAL_HPP_INCLUDED
rt/include/typon/scheduler.hpp
View file @
c57ef80c
...
...
@@ -8,6 +8,7 @@
#include <vector>
#include <typon/fundamental/event_count.hpp>
#include <typon/fundamental/optional.hpp>
#include <typon/fundamental/random.hpp>
#include <typon/continuation.hpp>
...
...
@@ -20,8 +21,8 @@ namespace typon
struct
Scheduler
{
using
uint
=
unsigned
int
;
using
Task
=
Optional
<
continuation_handle
>
;
using
Deque
=
Deque
<
continuation_handle
>
;
using
Task
=
typename
Deque
::
Pop
;
static
inline
thread_local
uint
thread_id
;
...
...
@@ -151,7 +152,7 @@ namespace typon
}
auto
key
=
_notifyer
.
prepare_wait
();
task
=
_deque
.
back
().
steal
();
if
(
task
.
state
()
!=
Task
::
empty
)
if
(
!
task
.
match
(
Deque
::
Empty
)
)
{
_notifyer
.
cancel_wait
();
if
(
task
)
...
...
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