blob: d1127ce9ea9bc80a852d934dcaa7328cee91e8ae [file] [log] [blame]
Craig Tiller20afa3d2016-10-17 14:52:14 -07001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller2f1d8702016-10-18 16:09:26 -070034#ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
35#define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
Craig Tiller20afa3d2016-10-17 14:52:14 -070036
37#include <grpc/grpc.h>
38
39#include "src/core/lib/iomgr/exec_ctx.h"
40
Craig Tiller3798e602016-10-21 14:39:27 -070041/** \file Tracks resource usage against a pool.
42
43 The current implementation tracks only memory usage, but in the future
44 this may be extended to (for example) threads and file descriptors.
45
46 A grpc_resource_quota represents the pooled resources, and
47 grpc_resource_user instances attach to the quota and consume those
48 resources. They also offer a vector for reclamation: if we become
49 resource constrained, grpc_resource_user instances are asked (in turn) to
50 free up whatever they can so that the system as a whole can make progress.
51
Craig Tiller8abc7962016-10-26 21:31:29 -070052 There are three kinds of reclamation that take place, in order of increasing
53 invasiveness:
Craig Tiller3798e602016-10-21 14:39:27 -070054 - an internal reclamation, where cached resource at the resource user level
55 is returned to the quota
56 - a benign reclamation phase, whereby resources that are in use but are not
57 helping anything make progress are reclaimed
58 - a destructive reclamation, whereby resources that are helping something
59 make progress may be enacted so that at least one part of the system can
60 complete.
61
Craig Tiller8abc7962016-10-26 21:31:29 -070062 Only one reclamation will be outstanding for a given quota at a given time.
63 On each reclamation attempt, the kinds of reclamation are tried in order of
64 increasing invasiveness, stopping at the first one that succeeds. Thus, on a
65 given reclamation attempt, if internal and benign reclamation both fail, it
66 will wind up doing a destructive reclamation. However, the next reclamation
67 attempt may then be able to get what it needs via internal or benign
68 reclamation, due to resources that may have been freed up by the destructive
69 reclamation in the previous attempt.
Craig Tiller3798e602016-10-21 14:39:27 -070070
71 Future work will be to expose the current resource pressure so that back
72 pressure can be applied to avoid reclamation phases starting.
73
74 Resource users own references to resource quotas, and resource quotas
75 maintain lists of users (which users arrange to leave before they are
76 destroyed) */
77
Craig Tiller20afa3d2016-10-17 14:52:14 -070078extern int grpc_resource_quota_trace;
79
Craig Tillera59c16c2016-10-31 07:25:01 -070080grpc_resource_quota *grpc_resource_quota_ref_internal(
Craig Tiller20afa3d2016-10-17 14:52:14 -070081 grpc_resource_quota *resource_quota);
Craig Tillera59c16c2016-10-31 07:25:01 -070082void grpc_resource_quota_unref_internal(grpc_exec_ctx *exec_ctx,
Craig Tiller20afa3d2016-10-17 14:52:14 -070083 grpc_resource_quota *resource_quota);
84grpc_resource_quota *grpc_resource_quota_from_channel_args(
85 const grpc_channel_args *channel_args);
86
Craig Tiller20afa3d2016-10-17 14:52:14 -070087typedef struct grpc_resource_user grpc_resource_user;
88
Craig Tillera947f1c2016-11-04 13:53:17 -070089grpc_resource_user *grpc_resource_user_create(
90 grpc_resource_quota *resource_quota, const char *name);
Dan Born9c627c22017-01-17 13:01:38 -080091
92/* Returns a borrowed reference to the underlying resource quota for this
93 resource user. */
Dan Borne955c1f2016-12-20 13:48:11 -080094grpc_resource_quota *grpc_resource_user_quota(
95 grpc_resource_user *resource_user);
Dan Born9c627c22017-01-17 13:01:38 -080096
Craig Tillera947f1c2016-11-04 13:53:17 -070097void grpc_resource_user_ref(grpc_resource_user *resource_user);
98void grpc_resource_user_unref(grpc_exec_ctx *exec_ctx,
99 grpc_resource_user *resource_user);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700100void grpc_resource_user_shutdown(grpc_exec_ctx *exec_ctx,
Craig Tillera947f1c2016-11-04 13:53:17 -0700101 grpc_resource_user *resource_user);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700102
Craig Tiller6b5d6822016-10-25 16:13:26 -0700103/* Allocate from the resource user (and its quota).
Craig Tiller3798e602016-10-21 14:39:27 -0700104 If optional_on_done is NULL, then allocate immediately. This may push the
105 quota over-limit, at which point reclamation will kick in.
106 If optional_on_done is non-NULL, it will be scheduled when the allocation has
107 been granted by the quota. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700108void grpc_resource_user_alloc(grpc_exec_ctx *exec_ctx,
109 grpc_resource_user *resource_user, size_t size,
110 grpc_closure *optional_on_done);
Craig Tiller3798e602016-10-21 14:39:27 -0700111/* Release memory back to the quota */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700112void grpc_resource_user_free(grpc_exec_ctx *exec_ctx,
113 grpc_resource_user *resource_user, size_t size);
Craig Tiller3798e602016-10-21 14:39:27 -0700114/* Post a memory reclaimer to the resource user. Only one benign and one
115 destructive reclaimer can be posted at once. When executed, the reclaimer
116 MUST call grpc_resource_user_finish_reclamation before it completes, to
117 return control to the resource quota. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700118void grpc_resource_user_post_reclaimer(grpc_exec_ctx *exec_ctx,
119 grpc_resource_user *resource_user,
120 bool destructive, grpc_closure *closure);
Craig Tiller3798e602016-10-21 14:39:27 -0700121/* Finish a reclamation step */
122void grpc_resource_user_finish_reclamation(grpc_exec_ctx *exec_ctx,
123 grpc_resource_user *resource_user);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700124
Craig Tiller3798e602016-10-21 14:39:27 -0700125/* Helper to allocate slices from a resource user */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700126typedef struct grpc_resource_user_slice_allocator {
Craig Tiller6b5d6822016-10-25 16:13:26 -0700127 /* Closure for when a resource user allocation completes */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700128 grpc_closure on_allocated;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700129 /* Closure to call when slices have been allocated */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700130 grpc_closure on_done;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700131 /* Length of slices to allocate on the current request */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700132 size_t length;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700133 /* Number of slices to allocate on the current request */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700134 size_t count;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700135 /* Destination for slices to allocate on the current request */
Craig Tillerd41a4a72016-10-26 16:16:06 -0700136 grpc_slice_buffer *dest;
Craig Tiller6b5d6822016-10-25 16:13:26 -0700137 /* Parent resource user */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700138 grpc_resource_user *resource_user;
139} grpc_resource_user_slice_allocator;
140
Craig Tiller6b5d6822016-10-25 16:13:26 -0700141/* Initialize a slice allocator.
142 When an allocation is completed, calls \a cb with arg \p. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700143void grpc_resource_user_slice_allocator_init(
144 grpc_resource_user_slice_allocator *slice_allocator,
145 grpc_resource_user *resource_user, grpc_iomgr_cb_func cb, void *p);
146
Craig Tiller6b5d6822016-10-25 16:13:26 -0700147/* Allocate \a count slices of length \a length into \a dest. Only one request
148 can be outstanding at a time. */
Craig Tiller20afa3d2016-10-17 14:52:14 -0700149void grpc_resource_user_alloc_slices(
150 grpc_exec_ctx *exec_ctx,
151 grpc_resource_user_slice_allocator *slice_allocator, size_t length,
Craig Tillerd41a4a72016-10-26 16:16:06 -0700152 size_t count, grpc_slice_buffer *dest);
Craig Tiller20afa3d2016-10-17 14:52:14 -0700153
murgatroid9969259d42016-10-31 14:34:10 -0700154/* Allocate one slice of length \a size synchronously. */
Craig Tiller32df4672016-11-04 08:21:56 -0700155grpc_slice grpc_resource_user_slice_malloc(grpc_exec_ctx *exec_ctx,
156 grpc_resource_user *resource_user,
157 size_t size);
murgatroid9969259d42016-10-31 14:34:10 -0700158
Craig Tiller2f1d8702016-10-18 16:09:26 -0700159#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */