• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <cstddef>
17 #include <limits>
18 
19 #include "pw_thread/attrs.h"
20 #include "pw_thread/stack.h"
21 #include "pw_thread_backend/context.h"
22 
23 namespace pw {
24 
25 inline constexpr size_t kExternallyAllocatedThreadStack =
26     std::numeric_limits<size_t>::max();
27 
28 /// Represents the resources required for one thread. May include OS data
29 /// structures, the thread stack, or be empty, depending on the platform.
30 ///
31 /// `ThreadContext` may be reused or deleted if the associated thread is
32 /// joined.
33 ///
34 /// `ThreadContext` takes an optional stack size template parameter. If a stack
35 /// size is provided, the context allocates a stack internally, if supported by
36 /// the backend. If no stack is is provided (`ThreadContext<>`), the
37 /// `ThreadContext` must be paired with a `pw::ThreadStack`.
38 template <size_t kStackSizeBytes = kExternallyAllocatedThreadStack>
39 class ThreadContext {
40  public:
41   constexpr ThreadContext() = default;
42 
43   ThreadContext(const ThreadContext&) = delete;
44   ThreadContext& operator=(const ThreadContext&) = delete;
45 
native()46   constexpr thread::backend::NativeContextWithStack<kStackSizeBytes>& native() {
47     return native_context_;
48   }
49 
50  private:
51   thread::backend::NativeContextWithStack<kStackSizeBytes> native_context_;
52 };
53 
54 // ThreadContext with externally allocated stack.
55 template <>
56 class ThreadContext<kExternallyAllocatedThreadStack> {
57  public:
58   constexpr ThreadContext() = default;
59 
60   ThreadContext(const ThreadContext&) = delete;
61   ThreadContext& operator=(const ThreadContext&) = delete;
62 
native()63   constexpr thread::backend::NativeContext& native() { return native_context_; }
64 
65  private:
66   thread::backend::NativeContext native_context_;
67 };
68 
69 /// Declares a `ThreadContext` that is associated with a specific set of thread
70 /// attributes. The `ThreadContext` may be reused if the associated thread is
71 /// joined, but all threads use the same `ThreadAttrs`.
72 template <const ThreadAttrs& kAttributes>
73 class ThreadContextFor {
74  public:
75   constexpr ThreadContextFor() = default;
76 
77   ThreadContextFor(const ThreadContextFor&) = delete;
78   ThreadContextFor& operator=(const ThreadContextFor&) = delete;
79 
native()80   constexpr auto& native() { return context_.native(); }
81 
82  private:
83   ThreadContext<kAttributes.has_external_stack()
84                     ? kExternallyAllocatedThreadStack
85                     : kAttributes.stack_size_bytes()>
86       context_;
87 };
88 
89 /// Alias for ThreadContext with the backend's default stack size.
90 using DefaultThreadContext =
91     ThreadContext<thread::backend::kDefaultStackSizeBytes>;
92 
93 }  // namespace pw
94