Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
typon
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
cython-plus
typon
Commits
7995afe4
Commit
7995afe4
authored
Jun 03, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
deque.hpp: Report resize requests in pop and steal
parent
af87826f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
37 additions
and
40 deletions
+37
-40
rt/include/typon/fundamental/deque.hpp
rt/include/typon/fundamental/deque.hpp
+37
-40
No files found.
rt/include/typon/fundamental/deque.hpp
View file @
7995afe4
...
@@ -23,20 +23,16 @@ namespace typon::fdt::lock_free
...
@@ -23,20 +23,16 @@ namespace typon::fdt::lock_free
using
u8
=
typename
ring_buffer
<
T
>::
u8
;
using
u8
=
typename
ring_buffer
<
T
>::
u8
;
using
u64
=
typename
ring_buffer
<
T
>::
u64
;
using
u64
=
typename
ring_buffer
<
T
>::
u64
;
static
constexpr
typename
pop_type
::
template
state
<
1
>
Abort
{
};
static
constexpr
unsigned
char
Abort
{
1
};
static
constexpr
typename
pop_type
::
template
state
<
2
>
Prune
{
};
static
constexpr
unsigned
char
Resize
{
2
};
using
enum
std
::
memory_order
;
using
enum
std
::
memory_order
;
const
u8
_bits
;
std
::
atomic
<
u64
>
_top
{
1
};
std
::
atomic
<
u64
>
_top
{
1
};
std
::
atomic
<
u64
>
_bottom
{
1
};
std
::
atomic
<
u64
>
_bottom
{
1
};
std
::
atomic
<
array_type
*>
_array
;
std
::
atomic
<
array_type
*>
_array
;
deque
(
u8
bits
=
3
)
noexcept
deque
(
u8
bits
=
3
)
noexcept
:
_array
(
new
array_type
(
bits
))
{}
:
_bits
(
bits
)
,
_array
(
new
array_type
(
bits
))
{}
~
deque
()
~
deque
()
{
{
...
@@ -47,7 +43,7 @@ namespace typon::fdt::lock_free
...
@@ -47,7 +43,7 @@ namespace typon::fdt::lock_free
{
{
u64
bottom
=
_bottom
.
load
(
relaxed
);
u64
bottom
=
_bottom
.
load
(
relaxed
);
u64
top
=
_top
.
load
(
acquire
);
u64
top
=
_top
.
load
(
acquire
);
a
rray_type
*
array
=
_array
.
load
(
relaxed
);
a
uto
array
=
_array
.
load
(
relaxed
);
if
(
bottom
-
top
>
array
->
capacity
()
-
1
)
if
(
bottom
-
top
>
array
->
capacity
()
-
1
)
{
{
array
=
array
->
grow
(
top
,
bottom
);
array
=
array
->
grow
(
top
,
bottom
);
...
@@ -58,68 +54,69 @@ namespace typon::fdt::lock_free
...
@@ -58,68 +54,69 @@ namespace typon::fdt::lock_free
_bottom
.
store
(
bottom
+
1
,
relaxed
);
_bottom
.
store
(
bottom
+
1
,
relaxed
);
}
}
pop_type
pop
()
noexcept
optional
<
T
>
pop
()
noexcept
{
{
u64
bottom
=
_bottom
.
load
(
relaxed
)
-
1
;
u64
bottom
=
_bottom
.
load
(
relaxed
)
-
1
;
a
rray_type
*
array
=
_array
.
load
(
relaxed
);
a
uto
array
=
_array
.
load
(
relaxed
);
_bottom
.
store
(
bottom
,
relaxed
);
_bottom
.
store
(
bottom
,
relaxed
);
std
::
atomic_thread_fence
(
seq_cst
);
std
::
atomic_thread_fence
(
seq_cst
);
u64
top
=
_top
.
load
(
relaxed
);
u64
top
=
_top
.
load
(
relaxed
);
pop_type
x
{};
if
(
top
<=
bottom
)
if
(
top
<=
bottom
)
{
{
x
=
array
->
get
(
bottom
);
if
(
top
==
bottom
)
if
(
top
==
bottom
)
{
{
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
{
{
x
=
{};
_bottom
.
store
(
bottom
+
1
,
relaxed
);
return
array
->
_next
?
optional
<
T
>
(
Resize
)
:
optional
<
T
>
();
}
}
_bottom
.
store
(
bottom
+
1
,
relaxed
);
_bottom
.
store
(
bottom
+
1
,
relaxed
);
}
}
T
x
=
array
->
get
(
bottom
);
if
(
array
->
_next
&&
array
->
capacity
()
>
(
bottom
-
top
)
*
4
)
{
return
{
x
,
Resize
};
}
return
{
x
};
}
}
else
_bottom
.
store
(
bottom
+
1
,
relaxed
);
{
return
array
->
_next
?
optional
<
T
>
(
Resize
)
:
optional
<
T
>
();
_bottom
.
store
(
bottom
+
1
,
relaxed
);
}
u64
capacity
=
array
->
capacity
();
if
(
capacity
>
u64
(
1
)
<<
_bits
&&
capacity
>
(
bottom
-
top
)
*
4
)
{
x
.
set_state
(
Prune
);
}
return
x
;
}
array_type
*
shrink
()
noexcept
{
u64
bottom
=
_bottom
.
load
(
relaxed
);
array_type
*
array
=
_array
.
load
(
relaxed
);
u64
top
=
_top
.
load
(
relaxed
);
array_type
*
next
=
array
->
shrink
(
top
,
bottom
);
if
(
next
)
{
_array
.
store
(
next
,
relaxed
);
return
array
;
}
return
nullptr
;
}
}
pop_type
steal
()
noexcept
optional
<
T
>
steal
()
noexcept
{
{
u64
top
=
_top
.
load
(
acquire
);
u64
top
=
_top
.
load
(
acquire
);
std
::
atomic_thread_fence
(
seq_cst
);
std
::
atomic_thread_fence
(
seq_cst
);
u64
bottom
=
_bottom
.
load
(
acquire
);
u64
bottom
=
_bottom
.
load
(
acquire
);
// Use acquire instead of consume (semantics under revision).
auto
array
=
_array
.
load
(
acquire
);
if
(
top
<
bottom
)
if
(
top
<
bottom
)
{
{
array_type
*
array
=
_array
.
load
(
consume
);
T
x
=
array
->
get
(
top
);
T
x
=
array
->
get
(
top
);
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
if
(
!
_top
.
compare_exchange_strong
(
top
,
top
+
1
,
seq_cst
,
relaxed
))
{
{
return
{
Abort
};
return
{
Abort
};
}
}
if
(
array
->
_next
&&
array
->
capacity
()
>
(
bottom
-
top
)
*
4
)
{
return
{
x
,
Resize
};
}
return
{
x
};
return
{
x
};
}
}
return
{};
return
array
->
_next
?
optional
<
T
>
(
Resize
)
:
optional
<
T
>
();
}
array_type
*
shrink
()
noexcept
{
u64
bottom
=
_bottom
.
load
(
relaxed
);
u64
top
=
_top
.
load
(
relaxed
);
auto
array
=
_array
.
load
(
relaxed
);
if
(
auto
next
=
array
->
shrink
(
top
,
bottom
))
{
_array
.
store
(
next
,
relaxed
);
return
array
;
}
return
nullptr
;
}
}
};
};
...
...
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