xref: /aosp_15_r20/external/pigweed/pw_sync_threadx/public/pw_sync_threadx/counting_semaphore_inline.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2020 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 <algorithm>
17 
18 #include "pw_assert/assert.h"
19 #include "pw_chrono/system_clock.h"
20 #include "pw_interrupt/context.h"
21 #include "pw_sync/counting_semaphore.h"
22 #include "tx_api.h"
23 
24 namespace pw::sync {
25 namespace backend {
26 
27 inline constexpr char kCountingSemaphoreName[] = "pw::CountingSemaphore";
28 
29 }  // namespace backend
30 
CountingSemaphore()31 inline CountingSemaphore::CountingSemaphore() : native_type_() {
32   PW_ASSERT(
33       tx_semaphore_create(&native_type_,
34                           const_cast<char*>(backend::kCountingSemaphoreName),
35                           0) == TX_SUCCESS);
36 }
37 
~CountingSemaphore()38 inline CountingSemaphore::~CountingSemaphore() {
39   PW_ASSERT(tx_semaphore_delete(&native_type_) == TX_SUCCESS);
40 }
41 
release(ptrdiff_t update)42 inline void CountingSemaphore::release(ptrdiff_t update) {
43   for (; update > 0; --update) {
44     PW_ASSERT(tx_semaphore_put(&native_type_) == TX_SUCCESS);
45   }
46 }
47 
acquire()48 inline void CountingSemaphore::acquire() {
49   // Enforce the pw::sync::CountingSemaphore IRQ contract.
50   PW_DASSERT(!interrupt::InInterruptContext());
51   PW_ASSERT(tx_semaphore_get(&native_type_, TX_WAIT_FOREVER) == TX_SUCCESS);
52 }
53 
try_acquire()54 inline bool CountingSemaphore::try_acquire() noexcept {
55   const UINT result = tx_semaphore_get(&native_type_, TX_NO_WAIT);
56   if (result == TX_NO_INSTANCE) {
57     return false;
58   }
59   PW_ASSERT(result == TX_SUCCESS);
60   return true;
61 }
62 
try_acquire_until(chrono::SystemClock::time_point deadline)63 inline bool CountingSemaphore::try_acquire_until(
64     chrono::SystemClock::time_point deadline) {
65   // Note that if this deadline is in the future, it will get rounded up by
66   // one whole tick due to how try_acquire_for is implemented.
67   return try_acquire_for(deadline - chrono::SystemClock::now());
68 }
69 
70 inline CountingSemaphore::native_handle_type
native_handle()71 CountingSemaphore::native_handle() {
72   return native_type_;
73 }
74 
75 }  // namespace pw::sync
76