chromium/services/network/slop_bucket.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "services/network/slop_bucket.h"

#include <limits.h>
#include <string.h>

#include <algorithm>
#include <ostream>

#include "base/containers/heap_array.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "base/synchronization/atomic_flag.h"
#include "base/system/sys_info.h"
#include "base/thread_annotations.h"
#include "base/types/pass_key.h"
#include "net/base/io_buffer.h"
#include "net/base/request_priority.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"

namespace network {

BASE_FEATURE();

namespace {

// The default for "require_priority". SlopBucket will not be used for requests
// with priority lower than this.
constexpr net::RequestPriority kDefaultRequirePriority =;

// The default for "chunk_size". All chunks that SlopBucket allocates will be of
// this size. Bigger values are more efficient, but waste more memory.
constexpr int kDefaultChunkSize =;

// The default for "min_buffer_size". A read smaller than this size will not be
// attempted. Instead, a new chunk will be allocated, or, if that is not
// possible, the bucket will be considered full. Must be less than
// `kDefaultChunkSize`.
constexpr int kDefaultMinBufferSize =;

// The default for "max_chunks_per_request". A single URLRequest will allocate
// this many chunks of buffering at most. The default is equivlant to 4MB. Must
// be greater than 0.
constexpr int kDefaultMaxChunksPerRequest =;

// The default for "max_chunks_total". This will cap the memory used by all
// SlopBuckets in the process. The default is equivalent to 16MB. Must be
// greater than `kDefaultMaxChunksPerRequest`.
constexpr int kDefaultMaxChunksTotal =;

// The default for "memory_pressure_disable_level". When a memory pressure
// notification of this level or higher arrives, SlopBucket will disable itself.
constexpr base::MemoryPressureListener::MemoryPressureLevel
    kDefaultMemoryPressureDisableLevel =;

// Mapping of name and value for net::RequestPriority enum.
constexpr base::FeatureParam<net::RequestPriority>::Option
    kRequestPriorityOptions[] =;

// "require_priority" parameter.
constexpr base::FeatureParam<net::RequestPriority> kRequirePriorityParam(
    &kSlopBucket,
    "require_priority",
    net::MEDIUM,
    &kRequestPriorityOptions);

// "chunk_size" parameter.
constexpr base::FeatureParam<int> kChunkSizeParam(&kSlopBucket,
                                                  "chunk_size",
                                                  kDefaultChunkSize);

// "min_buffer_size" parameter.
constexpr base::FeatureParam<int> kMinBufferSizeParam(&kSlopBucket,
                                                      "min_buffer_size",
                                                      kDefaultMinBufferSize);

// "max_chunks_per_request" parameter.
constexpr base::FeatureParam<int> kMaxChunksPerRequestParam(
    &kSlopBucket,
    "max_chunks_per_request",
    kDefaultMaxChunksPerRequest);

// "max_chunks_total" parameter.
constexpr base::FeatureParam<int> kMaxChunksTotalParam(&kSlopBucket,
                                                       "max_chunks_total",
                                                       kDefaultMaxChunksTotal);

// Mapping of name and value for
// base::MemoryPressureListener::MemoryPressureLevel enum.
constexpr base::FeatureParam<
    base::MemoryPressureListener::MemoryPressureLevel>::Option
    kMemoryPressureLevelOptions[] =;

// "memory_pressure_disable_level" parameter.
constexpr base::FeatureParam<base::MemoryPressureListener::MemoryPressureLevel>
    kMemoryPressureDisableLevelParam(
        &kSlopBucket,
        "memory_pressure_disable_level",
        base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
        &kMemoryPressureLevelOptions);

}  // namespace

// This class encapsulates the runtime configuration of SlopBucket. When
// constructed, it reads and validates the configuration. SlopBucket can be
// configured with an command-like flag like
// `--enable-features=SlopBucket/max_chunks_per_request/2`.
class SlopBucket::Configuration {};

// SlopBucketManager tracks global state for SlopBuckets. It is thread-hostile.
// TODO(ricea): Make this be owned by the NetworkService so that it can function
// correctly if there are multiple NetworkServices on different threads.
class SlopBucket::Manager {};

class SlopBucket::ChunkIOBuffer final : public net::IOBuffer {};

// static
std::unique_ptr<SlopBucket> SlopBucket::RequestSlopBucket(
    net::URLRequest* for_request) {}

SlopBucket::SlopBucket(PassKey, net::URLRequest* request) :{}

SlopBucket::~SlopBucket() {}

std::optional<int> SlopBucket::AttemptRead() {}

void SlopBucket::OnReadCompleted(int bytes_read) {}

size_t SlopBucket::Consume(void* buffer, size_t max) {}

size_t SlopBucket::ConsumeSlowPath(void* buffer, size_t max) {}

bool SlopBucket::TryToAllocateChunk() {}

}  // namespace network