Skip to content

Commit

Permalink
Updates in Kona
Browse files Browse the repository at this point in the history
  • Loading branch information
cor3ntin committed Nov 25, 2023
1 parent 446f7d3 commit 4c0c1fd
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 155 deletions.
273 changes: 160 additions & 113 deletions src/D2019.tex
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ \section{Example}
\begin{colorblock}
void f(int);
int main() {
std::jthread thread(std::thread_name("Worker"), std::thread_stack_size(512*1024), f, 42);
std::jthread thread(std::thread_name_hint("Worker"), std::thread_stack_size_hint(512*1024), f, 42);
return 0;
}
\end{colorblock}
Expand Down Expand Up @@ -414,13 +414,13 @@ \subsection{I cannot implement that on my platform?}
\begin{colorblock}
namespace std {

struct thread_name {
constexpr thread_name(std::string_view str) noexcept {};
constexpr thread_name(std::u8string_view str) noexcept {};
struct thread_name_hint {
constexpr explicit thread_name_hint(std::string_view str) noexcept {};
constexpr explicit thread_name_hint(std::u8string_view str) noexcept {};
};

struct thread_stack_size {
constexpr thread_stack_size(std::size_t) noexcept {}
struct thread_stack_size£_hint {
constexpr explicit thread_stack_size_hint(std::size_t) noexcept {}
};

\end{colorblock}
Expand Down Expand Up @@ -494,7 +494,7 @@ \subsection{Design}
This is made slightly easier by pack indexing (\paper{P2662R2}) \href{https://compiler-explorer.com/z/n8vYb7Tar}{[Compiler Explorer]}.


\tcode{thread_name} makes a copy of this argument and supports non-null terminated strings, and \tcode{u8} strings, as to
\tcode{thread_name_hint} makes a copy of this argument and supports non-null terminated strings, and \tcode{u8} strings, as to
portably support environments with utf-8 execution encodings (Linux), environments where Unicode encodings can be preserved (Windows),
and other environments.

Expand Down Expand Up @@ -545,6 +545,49 @@ \subsubsection{Can we add setters/getters later?}

This could be added later (and isn't ABI breaking).


\subsection{\tcode{constexpr} Constructors}

During R4 it was suggested to remove the constexpr on the constructor of thread attributes.
The idea was that an implementation could eagerly set the attribute on a pthread_attr_t.
However, pthread_attr_t is a collection of attributes rather than a single attribute so this
implementation strategy is not viable. Besides, on platforms were \tcode{pthread_attr_t} is
available the thread name size can't be more than a few bytes.
And on platforms where large thread names are theoretically possible (ie windows), a copy is
unavoidable. As such, removing \tcode{constexpr} would pessimize the windows case, and not
improve the posix case.

\subsection{Copyable attributes}

LEWG suggested making attributes non-copyable. While we do not know of a technical limitation
with that, we also do not see a motivation for doing so, nor can we imagine a case where using thread attributes
would lead to performance degradation.

\subsection{Copy in \tcode{thread_name_hint}}

\tcode{thread_name_hint} copies the constructor argument to avoid lifetime issues.
Making the constructors move-only or non-movable would not avoid the lifetime issues.


\subsection{\tcode{thread::name_hint} vs \tcode{thread_name_hint}}

LEWG had a mild suggestion of using \tcode{thread::name_hint} instead of \tcode{std::thread_name_hint}.
I do not have a strong opinion.

\begin{colorblock}
class thread {
class id;
class name_hint;
class stack_size_hint;
};

class jthread {
using id = thread::id;
using name_hint = thread::name_hint;
using stack_size_hint = thread::stack_size_hint;
};
\end{colorblock}

\section{Implementation}

A \href{https://github.com/cor3ntin/llvm-project/tree/corentin/thread_name_p2019}{prototype implementation} for libc++ (supporting only POSIX) threads has been created to validate the design.
Expand Down Expand Up @@ -617,99 +660,154 @@ \section{Wording}

\rSec1[thread.threads]{Threads}

\rSec2[thread.threads.general]{General}
%\rSec2[thread.threads.general]{General}
%
%\pnum
%\ref{thread.threads} describes components that can be used to create and manage threads.
%\begin{note}
% These threads are intended to map one-to-one with operating system threads.
%\end{note}
%
%\rSec2[thread.syn]{Header \tcode{<thread>} synopsis}
%
%\begin{codeblock}
%#include <compare> // see \ref{compare.syn}
%
%namespace std {
%\end{codeblock}
%\begin{addedblock}
%\begin{codeblock}
% % class thread_name_hint;
% % class thread_stack_size_hint;
%\end{codeblock}
%\end{addedblock}
%\begin{codeblock}
% // \ref{thread.thread.class}, class \tcode{thread}
% class thread;
%
% void swap(thread& x, thread& y) noexcept;
%
% // \ref{thread.jthread.class}, class \tcode{jthread}
% class jthread;
%
% // \ref{thread.thread.this}, namespace \tcode{this_thread}
% namespace this_thread {
% thread::id get_id() noexcept;
%
% void yield() noexcept;
% template<class Clock, class Duration>
% void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
% template<class Rep, class Period>
% void sleep_for(const chrono::duration<Rep, Period>& rel_time);
% }
%}
%\end{codeblock}
\begin{addedblock}
\rSec2[thread.thread.class]{Class \tcode{thread}}

\rSec3[thread.thread.class.general]{General}

\pnum
\ref{thread.threads} describes components that can be used to create and manage threads.
The class \tcode{thread} provides a mechanism to create a new thread of execution, to join with
a thread (i.e., wait for a thread to complete), and to perform other operations that manage and
query the state of a thread. A \tcode{thread} object uniquely represents a particular thread of
execution. That representation may be transferred to other \tcode{thread} objects in such a way
that no two \tcode{thread} objects simultaneously represent the same thread of execution. A
thread of execution is \term{detached} when no \tcode{thread} object represents that thread.
Objects of class \tcode{thread} can be in a state that does not represent a thread of
execution.
\begin{note}
These threads are intended to map one-to-one with operating system threads.
A \tcode{thread} object does not represent a thread of execution after
default construction, after being moved from, or after a successful call to \tcode{detach} or
\tcode{join}.
\end{note}

\rSec2[thread.syn]{Header \tcode{<thread>} synopsis}

\begin{codeblock}
#include <compare> // see \ref{compare.syn}

namespace std {
\end{codeblock}
\begin{addedblock}
\begin{codeblock}
class thread_name;
class thread_stack_size;
\end{codeblock}
\end{addedblock}
\begin{codeblock}
// \ref{thread.thread.class}, class \tcode{thread}
class thread;
class thread {
public:
class thread::id;
class id;
using native_handle_type = @\impdefnc@; // see~\ref{thread.req.native}

void swap(thread& x, thread& y) noexcept;
// construct/copy/destroy
thread() noexcept;
template<@\removed{class F,}@ class... Args> explicit thread(@\removed{F\&\& f,}@ Args&&... args);

// \ref{thread.jthread.class}, class \tcode{jthread}
class jthread;
~thread();
thread(const thread&) = delete;
thread(thread&&) noexcept;
thread& operator=(const thread&) = delete;
thread& operator=(thread&&) noexcept;

// \ref{thread.thread.this}, namespace \tcode{this_thread}
namespace this_thread {
thread::id get_id() noexcept;
// \ref{thread.thread.member}, members
void swap(thread&) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
native_handle_type native_handle(); // see~\ref{thread.req.native}

void yield() noexcept;
template<class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
}
// static members
static unsigned int hardware_concurrency() noexcept;
};
}
\end{codeblock}
\begin{addedblock}

\rSec2[thread.attributes]{Thread Attributes}

\rSec3[thread.attributes]{Thread Attributes}

Thread attributes can be used to define additional implementation-defined behaviors on a \tcode{thread} or \tcode{jthread} object.

%\recommended
%Implementations may provide additional platform-specific thread attributes derived from \tcode{thread_attribute} using reserved names.

\rSec3[thread.thread.name.class]{Class \tcode{thread_name}}
\rSec4[thread.thread.name.hint]{Class \tcode{thread::name_hint}}

\begin{codeblock}
class thread_name {
public:
constexpr thread_name(std::string_view name) noexcept;
constexpr thread_name(std::u8string_view name) noexcept;
private:
@\impdefnc@ __name[@\impdefnc@]; // \expos
namespace std {
class name_hint {
public:
constexpr explicit name_hint(std::string_view name) noexcept;
constexpr explicit name_hint(std::u8string_view name) noexcept;
private:
@\impdefnc@ __name[@\impdefnc@]; // \expos
};
}
\end{codeblock}

\recommended

The \tcode{thread_name} thread attribute, can be used
The \tcode{name_hint} thread attribute, can be used
to set the name of a thread such that the name could be used for debugging or platform-specific display mechanisms.
The name should not be stored in the \tcode{std::thread} or \tcode{std::jthread} object.

\begin{itemdecl}
constexpr thread_name(std::string_view name) noexcept;
constexpr thread_name(std::u8string_view name) noexcept;
constexpr name_hint(std::string_view name) noexcept;
constexpr name_hint(std::u8string_view name) noexcept;
\end{itemdecl}

\begin{itemdescr}
\effects Initializes \tcode{__name} with \tcode{name} in an implementation-defined manner.
\effects Initializes \tcode{__name} with \tcode{name} in an implementation-defined manner.

\recommended If \tcode{__name} is not large enough to store the value of \tcode{name},
the thread name might be truncated. If the implementation performs a text conversion
during the initialization of \tcode{__name} and if \tcode{name} is a valid code unit sequence
in the encoding associated with its type, \tcode{__name} should be a valid code unit sequence in its
associated encoding.
\recommended If \tcode{__name} is not large enough to store the value of \tcode{name},
the thread name might be truncated. If the implementation performs a text conversion
during the initialization of \tcode{__name} and if \tcode{name} is a valid code unit sequence
in the encoding associated with its type, \tcode{__name} should be a valid code unit sequence in its
associated encoding.
\end{itemdescr}

\rSec3[thread.thread.stack.size.class]{Class \tcode{thread_stack_size}}
\rSec4[thread.thread.stack.hint]{Class \tcode{thread::stack_size_hint}}

\begin{codeblock}
class thread_stack_size {
public:
constexpr thread_stack_size(std::size_t size) noexcept;
private:
constexpr std::size_t __size; // \expos
namespace std {
class thread::stack_size_hint {
public:
constexpr stack_size_hint(std::size_t size) noexcept;
private:
constexpr std::size_t __size; // \expos
};
}
\end{codeblock}

\recommended
Expand All @@ -720,66 +818,15 @@ \section{Wording}


\begin{itemdecl}
constexpr thread_stack_size(std::size_t size) noexcept;
constexpr stack_size_hint(std::size_t size) noexcept;
\end{itemdecl}

\begin{itemdescr}
\effects Initializes \tcode{__size} with \tcode{size} in an implementation-defined manner.
\effects Initializes \tcode{__size} with \tcode{size} in an implementation-defined manner.
\end{itemdescr}

\end{addedblock}

\rSec2[thread.thread.class]{Class \tcode{thread}}

\rSec3[thread.thread.class.general]{General}

\pnum
The class \tcode{thread} provides a mechanism to create a new thread of execution, to join with
a thread (i.e., wait for a thread to complete), and to perform other operations that manage and
query the state of a thread. A \tcode{thread} object uniquely represents a particular thread of
execution. That representation may be transferred to other \tcode{thread} objects in such a way
that no two \tcode{thread} objects simultaneously represent the same thread of execution. A
thread of execution is \term{detached} when no \tcode{thread} object represents that thread.
Objects of class \tcode{thread} can be in a state that does not represent a thread of
execution.
\begin{note}
A \tcode{thread} object does not represent a thread of execution after
default construction, after being moved from, or after a successful call to \tcode{detach} or
\tcode{join}.
\end{note}

\begin{codeblock}
namespace std {
class thread {
public:
class thread::id;
class id;
using native_handle_type = @\impdefnc@; // see~\ref{thread.req.native}

// construct/copy/destroy
thread() noexcept;
template<@\removed{class F,}@ class... Args> explicit thread(@\removed{F\&\& f,}@ Args&&... args);

~thread();
thread(const thread&) = delete;
thread(thread&&) noexcept;
thread& operator=(const thread&) = delete;
thread& operator=(thread&&) noexcept;

// \ref{thread.thread.member}, members
void swap(thread&) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
native_handle_type native_handle(); // see~\ref{thread.req.native}

// static members
static unsigned int hardware_concurrency() noexcept;
};
}
\end{codeblock}


\rSec3[thread.thread.constr]{Constructors}

Expand Down
Loading

0 comments on commit 4c0c1fd

Please sign in to comment.