• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_UTILS_LOCKED_QUEUE_INL_H_
6 #define V8_UTILS_LOCKED_QUEUE_INL_H_
7 
8 #include "src/base/atomic-utils.h"
9 #include "src/utils/locked-queue.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 template <typename Record>
15 struct LockedQueue<Record>::Node : Malloced {
16   Node() : next(nullptr) {}
17   Record value;
18   base::AtomicValue<Node*> next;
19 };
20 
21 template <typename Record>
22 inline LockedQueue<Record>::LockedQueue() {
23   head_ = new Node();
24   CHECK_NOT_NULL(head_);
25   tail_ = head_;
26   size_ = 0;
27 }
28 
29 template <typename Record>
30 inline LockedQueue<Record>::~LockedQueue() {
31   // Destroy all remaining nodes. Note that we do not destroy the actual values.
32   Node* old_node = nullptr;
33   Node* cur_node = head_;
34   while (cur_node != nullptr) {
35     old_node = cur_node;
36     cur_node = cur_node->next.Value();
37     delete old_node;
38   }
39 }
40 
41 template <typename Record>
42 inline void LockedQueue<Record>::Enqueue(Record record) {
43   Node* n = new Node();
44   CHECK_NOT_NULL(n);
45   n->value = std::move(record);
46   {
47     base::MutexGuard guard(&tail_mutex_);
48     size_++;
49     tail_->next.SetValue(n);
50     tail_ = n;
51   }
52 }
53 
54 template <typename Record>
55 inline bool LockedQueue<Record>::Dequeue(Record* record) {
56   Node* old_head = nullptr;
57   {
58     base::MutexGuard guard(&head_mutex_);
59     old_head = head_;
60     Node* const next_node = head_->next.Value();
61     if (next_node == nullptr) return false;
62     *record = std::move(next_node->value);
63     head_ = next_node;
64     size_t old_size = size_.fetch_sub(1);
65     USE(old_size);
66     DCHECK_GT(old_size, 0);
67   }
68   delete old_head;
69   return true;
70 }
71 
72 template <typename Record>
73 inline bool LockedQueue<Record>::IsEmpty() const {
74   base::MutexGuard guard(&head_mutex_);
75   return head_->next.Value() == nullptr;
76 }
77 
78 template <typename Record>
79 inline bool LockedQueue<Record>::Peek(Record* record) const {
80   base::MutexGuard guard(&head_mutex_);
81   Node* const next_node = head_->next.Value();
82   if (next_node == nullptr) return false;
83   *record = next_node->value;
84   return true;
85 }
86 
87 template <typename Record>
88 inline size_t LockedQueue<Record>::size() const {
89   return size_;
90 }
91 
92 }  // namespace internal
93 }  // namespace v8
94 
95 #endif  // V8_UTILS_LOCKED_QUEUE_INL_H_
96