resource_quota.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. *
  3. * Copyright 2016 gRPC authors.
  4. *
  5. * 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
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * 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.
  16. *
  17. */
  18. #ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
  19. #define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
  20. #include <grpc/support/port_platform.h>
  21. #include <grpc/grpc.h>
  22. #include "src/core/lib/debug/trace.h"
  23. #include "src/core/lib/iomgr/exec_ctx.h"
  24. /** \file Tracks resource usage against a pool.
  25. The current implementation tracks only memory usage, but in the future
  26. this may be extended to (for example) threads and file descriptors.
  27. A grpc_resource_quota represents the pooled resources, and
  28. grpc_resource_user instances attach to the quota and consume those
  29. resources. They also offer a vector for reclamation: if we become
  30. resource constrained, grpc_resource_user instances are asked (in turn) to
  31. free up whatever they can so that the system as a whole can make progress.
  32. There are three kinds of reclamation that take place, in order of increasing
  33. invasiveness:
  34. - an internal reclamation, where cached resource at the resource user level
  35. is returned to the quota
  36. - a benign reclamation phase, whereby resources that are in use but are not
  37. helping anything make progress are reclaimed
  38. - a destructive reclamation, whereby resources that are helping something
  39. make progress may be enacted so that at least one part of the system can
  40. complete.
  41. Only one reclamation will be outstanding for a given quota at a given time.
  42. On each reclamation attempt, the kinds of reclamation are tried in order of
  43. increasing invasiveness, stopping at the first one that succeeds. Thus, on a
  44. given reclamation attempt, if internal and benign reclamation both fail, it
  45. will wind up doing a destructive reclamation. However, the next reclamation
  46. attempt may then be able to get what it needs via internal or benign
  47. reclamation, due to resources that may have been freed up by the destructive
  48. reclamation in the previous attempt.
  49. Future work will be to expose the current resource pressure so that back
  50. pressure can be applied to avoid reclamation phases starting.
  51. Resource users own references to resource quotas, and resource quotas
  52. maintain lists of users (which users arrange to leave before they are
  53. destroyed) */
  54. extern grpc_core::TraceFlag grpc_resource_quota_trace;
  55. grpc_resource_quota* grpc_resource_quota_ref_internal(
  56. grpc_resource_quota* resource_quota);
  57. void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota);
  58. grpc_resource_quota* grpc_resource_quota_from_channel_args(
  59. const grpc_channel_args* channel_args);
  60. /* Return a number indicating current memory pressure:
  61. 0.0 ==> no memory usage
  62. 1.0 ==> maximum memory usage */
  63. double grpc_resource_quota_get_memory_pressure(
  64. grpc_resource_quota* resource_quota);
  65. size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota);
  66. typedef struct grpc_resource_user grpc_resource_user;
  67. grpc_resource_user* grpc_resource_user_create(
  68. grpc_resource_quota* resource_quota, const char* name);
  69. /* Returns a borrowed reference to the underlying resource quota for this
  70. resource user. */
  71. grpc_resource_quota* grpc_resource_user_quota(
  72. grpc_resource_user* resource_user);
  73. void grpc_resource_user_ref(grpc_resource_user* resource_user);
  74. void grpc_resource_user_unref(grpc_resource_user* resource_user);
  75. void grpc_resource_user_shutdown(grpc_resource_user* resource_user);
  76. /* Allocate from the resource user (and its quota).
  77. If optional_on_done is NULL, then allocate immediately. This may push the
  78. quota over-limit, at which point reclamation will kick in.
  79. If optional_on_done is non-NULL, it will be scheduled when the allocation has
  80. been granted by the quota. */
  81. void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
  82. grpc_closure* optional_on_done);
  83. /* Release memory back to the quota */
  84. void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size);
  85. /* Post a memory reclaimer to the resource user. Only one benign and one
  86. destructive reclaimer can be posted at once. When executed, the reclaimer
  87. MUST call grpc_resource_user_finish_reclamation before it completes, to
  88. return control to the resource quota. */
  89. void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user,
  90. bool destructive, grpc_closure* closure);
  91. /* Finish a reclamation step */
  92. void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user);
  93. /* Helper to allocate slices from a resource user */
  94. typedef struct grpc_resource_user_slice_allocator {
  95. /* Closure for when a resource user allocation completes */
  96. grpc_closure on_allocated;
  97. /* Closure to call when slices have been allocated */
  98. grpc_closure on_done;
  99. /* Length of slices to allocate on the current request */
  100. size_t length;
  101. /* Number of slices to allocate on the current request */
  102. size_t count;
  103. /* Destination for slices to allocate on the current request */
  104. grpc_slice_buffer* dest;
  105. /* Parent resource user */
  106. grpc_resource_user* resource_user;
  107. } grpc_resource_user_slice_allocator;
  108. /* Initialize a slice allocator.
  109. When an allocation is completed, calls \a cb with arg \p. */
  110. void grpc_resource_user_slice_allocator_init(
  111. grpc_resource_user_slice_allocator* slice_allocator,
  112. grpc_resource_user* resource_user, grpc_iomgr_cb_func cb, void* p);
  113. /* Allocate \a count slices of length \a length into \a dest. Only one request
  114. can be outstanding at a time. */
  115. void grpc_resource_user_alloc_slices(
  116. grpc_resource_user_slice_allocator* slice_allocator, size_t length,
  117. size_t count, grpc_slice_buffer* dest);
  118. #endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */