blob: 787370307a88581a42e5f7800b15022e18e58ce4 [file] [log] [blame]
Craig Tiller20afa3d2016-10-17 14:52:14 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2016 gRPC authors.
Craig Tiller20afa3d2016-10-17 14:52:14 -07004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Craig Tiller20afa3d2016-10-17 14:52:14 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Craig Tiller20afa3d2016-10-17 14:52:14 -070010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Craig Tiller20afa3d2016-10-17 14:52:14 -070016 *
17 */
18
Craig Tiller2f1d8702016-10-18 16:09:26 -070019#ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
20#define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
Craig Tiller20afa3d2016-10-17 14:52:14 -070021
22#include <grpc/grpc.h>
23
Craig Tiller84f75d42017-05-03 13:06:35 -070024#include "src/core/lib/debug/trace.h"
Craig Tiller20afa3d2016-10-17 14:52:14 -070025#include "src/core/lib/iomgr/exec_ctx.h"
26
Craig Tiller3798e602016-10-21 14:39:27 -070027/** \file Tracks resource usage against a pool.
28
29 The current implementation tracks only memory usage, but in the future
30 this may be extended to (for example) threads and file descriptors.
31
32 A grpc_resource_quota represents the pooled resources, and
33 grpc_resource_user instances attach to the quota and consume those
34 resources. They also offer a vector for reclamation: if we become
35 resource constrained, grpc_resource_user instances are asked (in turn) to
36 free up whatever they can so that the system as a whole can make progress.
37
Craig Tiller8abc7962016-10-26 21:31:29 -070038 There are three kinds of reclamation that take place, in order of increasing
39 invasiveness:
Craig Tiller3798e602016-10-21 14:39:27 -070040 - an internal reclamation, where cached resource at the resource user level
41 is returned to the quota
42 - a benign reclamation phase, whereby resources that are in use but are not
43 helping anything make progress are reclaimed
44 - a destructive reclamation, whereby resources that are helping something
45 make progress may be enacted so that at least one part of the system can
46 complete.
47
Craig Tiller8abc7962016-10-26 21:31:29 -070048 Only one reclamation will be outstanding for a given quota at a given time.
49 On each reclamation attempt, the kinds of reclamation are tried in order of
50 increasing invasiveness, stopping at the first one that succeeds. Thus, on a
51 given reclamation attempt, if internal and benign reclamation both fail, it
52 will wind up doing a destructive reclamation. However, the next reclamation
53 attempt may then be able to get what it needs via internal or benign
54 reclamation, due to resources that may have been freed up by the destructive
55 reclamation in the previous attempt.
Craig Tiller3798e602016-10-21 14:39:27 -070056
57 Future work will be to expose the current resource pressure so that back
58 pressure can be applied to avoid reclamation phases starting.
59
60 Resource users own references to resource quotas, and resource quotas
61 maintain lists of users (which users arrange to leave before they are
62 destroyed) */
63
Craig Tiller694580f2017-10-18 14:48:14 -070064extern grpc_core::TraceFlag grpc_resource_quota_trace;
Craig Tiller20afa3d2016-10-17 14:52:14 -070065
Craig Tillerbaa14a92017-11-03 09:09:36 -070066grpc_resource_quota* grpc_resource_quota_ref_internal(
67 grpc_resource_quota* resource_quota);
68void grpc_resource_quota_unref_internal(grpc_exec_ctx* exec_ctx,
69 grpc_resource_quota* resource_quota);
70grpc_resource_quota* grpc_resource_quota_from_channel_args(
71 const grpc_channel_args* channel_args);
Craig Tiller20afa3d2016-10-17 14:52:14 -070072
Craig Tillerb38bfc02016-10-24 13:21:39 -070073/* Return a number indicating current memory pressure:
74 0.0 ==> no memory usage
75 1.0 ==> maximum memory usage */
76double grpc_resource_quota_get_memory_pressure(
Craig Tillerbaa14a92017-11-03 09:09:36 -070077 grpc_resource_quota* resource_quota);
Craig Tillerb38bfc02016-10-24 13:21:39 -070078
Craig Tillerbaa14a92017-11-03 09:09:36 -070079size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota);
Craig Tillerd9a776d2017-03-30 12:37:11 -070080
Craig Tiller20afa3d2016-10-17 14:52:14 -070081typedef struct grpc_resource_user grpc_resource_user;
82
Craig Tillerbaa14a92017-11-03 09:09:36 -070083grpc_resource_user* grpc_resource_user_create(
84 grpc_resource_quota* resource_quota, const char* name);
Dan Born9c627c22017-01-17 13:01:38 -080085
86/* Returns a borrowed reference to the underlying resource quota for this
87 resource user. */
Craig Tillerbaa14a92017-11-03 09:09:36 -070088grpc_resource_quota* grpc_resource_user_quota(
89 grpc_resource_user* resource_user);
Dan Born9c627c22017-01-17 13:01:38 -080090
Craig Tillerbaa14a92017-11-03 09:09:36 -070091void grpc_resource_user_ref(grpc_resource_user* resource_user);
92void grpc_resource_user_unref(grpc_exec_ctx* exec_ctx,
93 grpc_resource_user* resource_user);
94void grpc_resource_user_shutdown(grpc_exec_ctx* exec_ctx,
95 grpc_resource_user* resource_user);
Craig Tiller20afa3d2016-10-17 14:52:14 -070096
Craig Tiller6b5d6822016-10-25 16:13:26 -070097/* Allocate from the resource user (and its quota).
Craig Tiller3798e602016-10-21 14:39:27 -070098 If optional_on_done is NULL, then allocate immediately. This may push the
99 quota over-limit, at which point reclamation will kick in.
100 If optional_on_done is non-NULL, it will be scheduled when the allocation has
101 been granted by the quota. */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700102void grpc_resource_user_alloc(grpc_exec_ctx* exec_ctx,
103 grpc_resource_user* resource_user, size_t size,
104 grpc_closure* optional_on_done);
Craig Tiller3798e602016-10-21 14:39:27 -0700105/* Release memory back to the quota */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700106void grpc_resource_user_free(grpc_exec_ctx* exec_ctx,
107 grpc_resource_user* resource_user, size_t size);
Craig Tiller3798e602016-10-21 14:39:27 -0700108/* Post a memory reclaimer to the resource user. Only one benign and one
109 destructive reclaimer can be posted at once. When executed, the reclaimer
110 MUST call grpc_resource_user_finish_reclamation before it completes, to
111 return control to the resource quota. */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700112void grpc_resource_user_post_reclaimer(grpc_exec_ctx* exec_ctx,
113 grpc_resource_user* resource_user,
114 bool destructive, grpc_closure* closure);
Craig Tiller3798e602016-10-21 14:39:27 -0700115/* Finish a reclamation step */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700116void grpc_resource_user_finish_reclamation(grpc_exec_ctx* exec_ctx,
117 grpc_resource_user* resource_user);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700118
Craig Tiller3798e602016-10-21 14:39:27 -0700119/* Helper to allocate slices from a resource user */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700120typedef struct grpc_resource_user_slice_allocator {
Craig Tiller6b5d6822016-10-25 16:13:26 -0700121 /* Closure for when a resource user allocation completes */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700122 grpc_closure on_allocated;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700123 /* Closure to call when slices have been allocated */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700124 grpc_closure on_done;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700125 /* Length of slices to allocate on the current request */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700126 size_t length;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700127 /* Number of slices to allocate on the current request */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700128 size_t count;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700129 /* Destination for slices to allocate on the current request */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700130 grpc_slice_buffer* dest;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700131 /* Parent resource user */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700132 grpc_resource_user* resource_user;
Craig Tiller20afa3d2016-10-17 14:52:14 -0700133} grpc_resource_user_slice_allocator;
134
Craig Tiller6b5d6822016-10-25 16:13:26 -0700135/* Initialize a slice allocator.
136 When an allocation is completed, calls \a cb with arg \p. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700137void grpc_resource_user_slice_allocator_init(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700138 grpc_resource_user_slice_allocator* slice_allocator,
139 grpc_resource_user* resource_user, grpc_iomgr_cb_func cb, void* p);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700140
Craig Tiller6b5d6822016-10-25 16:13:26 -0700141/* Allocate \a count slices of length \a length into \a dest. Only one request
142 can be outstanding at a time. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700143void grpc_resource_user_alloc_slices(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700144 grpc_exec_ctx* exec_ctx,
145 grpc_resource_user_slice_allocator* slice_allocator, size_t length,
146 size_t count, grpc_slice_buffer* dest);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700147
murgatroid9969259d42016-10-31 14:34:10 -0700148/* Allocate one slice of length \a size synchronously. */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700149grpc_slice grpc_resource_user_slice_malloc(grpc_exec_ctx* exec_ctx,
150 grpc_resource_user* resource_user,
Craig Tiller32df4672016-11-04 08:21:56 -0700151 size_t size);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700152
Yash Tibrewal12fc6d42017-10-09 16:43:34 -0700153#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */