mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 16:26:10 +03:00
103 lines
3.1 KiB
C
103 lines
3.1 KiB
C
|
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#ifndef BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
|
||
|
#define BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
|
||
|
|
||
|
#include <map>
|
||
|
#include <vector>
|
||
|
|
||
|
#include "base/base_export.h"
|
||
|
#include "base/logging.h"
|
||
|
#include "base/macros.h"
|
||
|
#include "base/task/sequence_manager/intrusive_heap.h"
|
||
|
#include "base/task/sequence_manager/task_queue_impl.h"
|
||
|
#include "base/task/sequence_manager/work_queue.h"
|
||
|
#include "base/trace_event/trace_event_argument.h"
|
||
|
|
||
|
namespace base {
|
||
|
namespace sequence_manager {
|
||
|
namespace internal {
|
||
|
|
||
|
// There is a WorkQueueSet for each scheduler priority and each WorkQueueSet
|
||
|
// uses a EnqueueOrderToWorkQueueMap to keep track of which queue in the set has
|
||
|
// the oldest task (i.e. the one that should be run next if the
|
||
|
// TaskQueueSelector chooses to run a task a given priority). The reason this
|
||
|
// works is because std::map is a tree based associative container and all the
|
||
|
// values are kept in sorted order.
|
||
|
class BASE_EXPORT WorkQueueSets {
|
||
|
public:
|
||
|
WorkQueueSets(size_t num_sets, const char* name);
|
||
|
~WorkQueueSets();
|
||
|
|
||
|
// O(log num queues)
|
||
|
void AddQueue(WorkQueue* queue, size_t set_index);
|
||
|
|
||
|
// O(log num queues)
|
||
|
void RemoveQueue(WorkQueue* work_queue);
|
||
|
|
||
|
// O(log num queues)
|
||
|
void ChangeSetIndex(WorkQueue* queue, size_t set_index);
|
||
|
|
||
|
// O(log num queues)
|
||
|
void OnFrontTaskChanged(WorkQueue* queue);
|
||
|
|
||
|
// O(log num queues)
|
||
|
void OnTaskPushedToEmptyQueue(WorkQueue* work_queue);
|
||
|
|
||
|
// If empty it's O(1) amortized, otherwise it's O(log num queues)
|
||
|
// Assumes |work_queue| contains the lowest enqueue order in the set.
|
||
|
void OnPopQueue(WorkQueue* work_queue);
|
||
|
|
||
|
// O(log num queues)
|
||
|
void OnQueueBlocked(WorkQueue* work_queue);
|
||
|
|
||
|
// O(1)
|
||
|
bool GetOldestQueueInSet(size_t set_index, WorkQueue** out_work_queue) const;
|
||
|
|
||
|
// O(1)
|
||
|
bool GetOldestQueueAndEnqueueOrderInSet(
|
||
|
size_t set_index,
|
||
|
WorkQueue** out_work_queue,
|
||
|
EnqueueOrder* out_enqueue_order) const;
|
||
|
|
||
|
// O(1)
|
||
|
bool IsSetEmpty(size_t set_index) const;
|
||
|
|
||
|
#if DCHECK_IS_ON() || !defined(NDEBUG)
|
||
|
// Note this iterates over everything in |work_queue_heaps_|.
|
||
|
// It's intended for use with DCHECKS and for testing
|
||
|
bool ContainsWorkQueueForTest(const WorkQueue* queue) const;
|
||
|
#endif
|
||
|
|
||
|
const char* GetName() const { return name_; }
|
||
|
|
||
|
private:
|
||
|
struct OldestTaskEnqueueOrder {
|
||
|
EnqueueOrder key;
|
||
|
WorkQueue* value;
|
||
|
|
||
|
bool operator<=(const OldestTaskEnqueueOrder& other) const {
|
||
|
return key <= other.key;
|
||
|
}
|
||
|
|
||
|
void SetHeapHandle(HeapHandle handle) { value->set_heap_handle(handle); }
|
||
|
|
||
|
void ClearHeapHandle() { value->set_heap_handle(HeapHandle()); }
|
||
|
};
|
||
|
|
||
|
// For each set |work_queue_heaps_| has a queue of WorkQueue ordered by the
|
||
|
// oldest task in each WorkQueue.
|
||
|
std::vector<IntrusiveHeap<OldestTaskEnqueueOrder>> work_queue_heaps_;
|
||
|
const char* const name_;
|
||
|
|
||
|
DISALLOW_COPY_AND_ASSIGN(WorkQueueSets);
|
||
|
};
|
||
|
|
||
|
} // namespace internal
|
||
|
} // namespace sequence_manager
|
||
|
} // namespace base
|
||
|
|
||
|
#endif // BASE_TASK_SEQUENCE_MANAGER_WORK_QUEUE_SETS_H_
|