/src/rocksdb/util/concurrent_task_limiter_impl.cc
Line | Count | Source |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under both the GPLv2 (found in the |
3 | | // COPYING file in the root directory) and Apache 2.0 License |
4 | | // (found in the LICENSE.Apache file in the root directory). |
5 | | // |
6 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
7 | | // Use of this source code is governed by a BSD-style license that can be |
8 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
9 | | |
10 | | #include "util/concurrent_task_limiter_impl.h" |
11 | | |
12 | | #include "rocksdb/concurrent_task_limiter.h" |
13 | | |
14 | | namespace ROCKSDB_NAMESPACE { |
15 | | |
16 | | ConcurrentTaskLimiterImpl::ConcurrentTaskLimiterImpl( |
17 | | const std::string& name, int32_t max_outstanding_task) |
18 | 0 | : name_(name), |
19 | 0 | max_outstanding_tasks_{max_outstanding_task}, |
20 | 0 | outstanding_tasks_{0} {} |
21 | | |
22 | 0 | ConcurrentTaskLimiterImpl::~ConcurrentTaskLimiterImpl() { |
23 | 0 | assert(outstanding_tasks_ == 0); |
24 | 0 | } |
25 | | |
26 | 0 | const std::string& ConcurrentTaskLimiterImpl::GetName() const { return name_; } |
27 | | |
28 | 0 | void ConcurrentTaskLimiterImpl::SetMaxOutstandingTask(int32_t limit) { |
29 | 0 | max_outstanding_tasks_.store(limit, std::memory_order_relaxed); |
30 | 0 | } |
31 | | |
32 | 0 | void ConcurrentTaskLimiterImpl::ResetMaxOutstandingTask() { |
33 | 0 | max_outstanding_tasks_.store(-1, std::memory_order_relaxed); |
34 | 0 | } |
35 | | |
36 | 0 | int32_t ConcurrentTaskLimiterImpl::GetOutstandingTask() const { |
37 | 0 | return outstanding_tasks_.load(std::memory_order_relaxed); |
38 | 0 | } |
39 | | |
40 | | std::unique_ptr<TaskLimiterToken> ConcurrentTaskLimiterImpl::GetToken( |
41 | 0 | bool force) { |
42 | 0 | int32_t limit = max_outstanding_tasks_.load(std::memory_order_relaxed); |
43 | 0 | int32_t tasks = outstanding_tasks_.load(std::memory_order_relaxed); |
44 | | // force = true, bypass the throttle. |
45 | | // limit < 0 means unlimited tasks. |
46 | 0 | while (force || limit < 0 || tasks < limit) { |
47 | 0 | if (outstanding_tasks_.compare_exchange_weak(tasks, tasks + 1)) { |
48 | 0 | return std::unique_ptr<TaskLimiterToken>(new TaskLimiterToken(this)); |
49 | 0 | } |
50 | 0 | } |
51 | 0 | return nullptr; |
52 | 0 | } |
53 | | |
54 | | ConcurrentTaskLimiter* NewConcurrentTaskLimiter(const std::string& name, |
55 | 0 | int32_t limit) { |
56 | 0 | return new ConcurrentTaskLimiterImpl(name, limit); |
57 | 0 | } |
58 | | |
59 | 0 | TaskLimiterToken::~TaskLimiterToken() { |
60 | 0 | --limiter_->outstanding_tasks_; |
61 | | assert(limiter_->outstanding_tasks_ >= 0); |
62 | 0 | } |
63 | | |
64 | | } // namespace ROCKSDB_NAMESPACE |