grpc 1.23.1 → 1.24.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +757 -477
  3. data/include/grpc/grpc.h +3 -1
  4. data/include/grpc/grpc_security.h +20 -4
  5. data/include/grpc/impl/codegen/grpc_types.h +6 -5
  6. data/include/grpc/impl/codegen/port_platform.h +25 -0
  7. data/src/core/ext/filters/client_channel/backend_metric.cc +78 -0
  8. data/src/core/ext/filters/client_channel/backend_metric.h +36 -0
  9. data/src/core/ext/filters/client_channel/channel_connectivity.cc +16 -2
  10. data/src/core/ext/filters/client_channel/client_channel.cc +325 -267
  11. data/src/core/ext/filters/client_channel/client_channel_factory.h +0 -4
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +23 -32
  13. data/src/core/ext/filters/client_channel/http_proxy.cc +7 -3
  14. data/src/core/ext/filters/client_channel/lb_policy.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy.h +58 -34
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +46 -50
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +9 -2
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +35 -17
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +130 -215
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +34 -21
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +1120 -802
  22. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +8 -2
  23. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +33 -12
  24. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc +151 -40
  25. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h +184 -26
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +389 -245
  27. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +98 -60
  28. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +6 -1
  29. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +89 -0
  30. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +3 -8
  31. data/src/core/ext/filters/client_channel/server_address.cc +1 -3
  32. data/src/core/ext/filters/client_channel/server_address.h +1 -1
  33. data/src/core/ext/filters/client_channel/subchannel.h +2 -1
  34. data/src/core/ext/filters/client_idle/client_idle_filter.cc +207 -29
  35. data/src/core/ext/filters/http/client/http_client_filter.cc +10 -8
  36. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  37. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +10 -7
  38. data/src/core/ext/filters/http/server/http_server_filter.cc +52 -26
  39. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +23 -20
  40. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +24 -21
  41. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +1 -1
  42. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +37 -24
  43. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  44. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +237 -191
  45. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +29 -27
  46. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +1 -1
  47. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +19 -4
  48. data/src/core/ext/transport/chttp2/transport/hpack_table.h +13 -4
  49. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +2 -1
  50. data/src/core/ext/transport/chttp2/transport/internal.h +0 -2
  51. data/src/core/ext/transport/chttp2/transport/parsing.cc +99 -71
  52. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c +222 -0
  53. data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h +818 -0
  54. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c +314 -0
  55. data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h +1142 -0
  56. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c +53 -0
  57. data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h +158 -0
  58. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.c +34 -0
  59. data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.h +69 -0
  60. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c +49 -0
  61. data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h +240 -0
  62. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c +110 -0
  63. data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +324 -0
  64. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c +235 -0
  65. data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +661 -0
  66. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c +84 -0
  67. data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h +274 -0
  68. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c +175 -0
  69. data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h +572 -0
  70. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c +150 -0
  71. data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +596 -0
  72. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.c +35 -0
  73. data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.h +80 -0
  74. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c +95 -0
  75. data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h +308 -0
  76. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c +128 -0
  77. data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +392 -0
  78. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c +91 -0
  79. data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h +236 -0
  80. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c +88 -0
  81. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h +258 -0
  82. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c +111 -0
  83. data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h +324 -0
  84. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c +23 -0
  85. data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h +50 -0
  86. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c +52 -0
  87. data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h +130 -0
  88. data/src/core/ext/upb-generated/envoy/type/percent.upb.c +39 -0
  89. data/src/core/ext/upb-generated/envoy/type/percent.upb.h +87 -0
  90. data/src/core/ext/upb-generated/envoy/type/range.upb.c +39 -0
  91. data/src/core/ext/upb-generated/envoy/type/range.upb.h +85 -0
  92. data/src/core/ext/upb-generated/gogoproto/gogo.upb.c +17 -0
  93. data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +30 -0
  94. data/src/core/ext/upb-generated/google/api/annotations.upb.c +18 -0
  95. data/src/core/ext/upb-generated/google/api/annotations.upb.h +30 -0
  96. data/src/core/ext/upb-generated/google/api/http.upb.c +66 -0
  97. data/src/core/ext/upb-generated/google/api/http.upb.h +190 -0
  98. data/src/core/ext/upb-generated/google/protobuf/any.upb.c +27 -0
  99. data/src/core/ext/upb-generated/google/protobuf/any.upb.h +58 -0
  100. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +485 -0
  101. data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +1690 -0
  102. data/src/core/ext/upb-generated/google/protobuf/duration.upb.c +27 -0
  103. data/src/core/ext/upb-generated/google/protobuf/duration.upb.h +58 -0
  104. data/src/core/ext/upb-generated/google/protobuf/empty.upb.c +22 -0
  105. data/src/core/ext/upb-generated/google/protobuf/empty.upb.h +50 -0
  106. data/src/core/ext/upb-generated/google/protobuf/struct.upb.c +79 -0
  107. data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +215 -0
  108. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c +27 -0
  109. data/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +58 -0
  110. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c +106 -0
  111. data/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +238 -0
  112. data/src/core/ext/upb-generated/google/rpc/status.upb.c +33 -0
  113. data/src/core/ext/upb-generated/google/rpc/status.upb.h +74 -0
  114. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c +49 -0
  115. data/src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h +126 -0
  116. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c +209 -0
  117. data/src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h +681 -0
  118. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c +42 -0
  119. data/src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h +109 -0
  120. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c +36 -0
  121. data/src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h +84 -0
  122. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +133 -0
  123. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +359 -0
  124. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c +58 -0
  125. data/src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h +144 -0
  126. data/src/core/ext/upb-generated/validate/validate.upb.c +443 -0
  127. data/src/core/ext/upb-generated/validate/validate.upb.h +2037 -0
  128. data/src/core/lib/channel/channel_args.cc +21 -0
  129. data/src/core/lib/channel/channel_args.h +16 -2
  130. data/src/core/lib/channel/channel_stack.h +2 -1
  131. data/src/core/lib/channel/channelz.cc +54 -56
  132. data/src/core/lib/channel/channelz.h +29 -12
  133. data/src/core/lib/compression/compression.cc +2 -1
  134. data/src/core/lib/compression/compression_internal.h +8 -0
  135. data/src/core/lib/gpr/log_linux.cc +2 -2
  136. data/src/core/lib/gpr/log_posix.cc +2 -2
  137. data/src/core/lib/gpr/time_precise.cc +123 -36
  138. data/src/core/lib/gpr/time_precise.h +37 -0
  139. data/src/core/lib/gprpp/abstract.h +10 -0
  140. data/src/core/lib/gprpp/atomic.h +4 -0
  141. data/src/core/lib/gprpp/inlined_vector.h +20 -4
  142. data/src/core/lib/gprpp/map.h +109 -6
  143. data/src/core/lib/gprpp/memory.h +6 -0
  144. data/src/core/lib/gprpp/ref_counted_ptr.h +2 -0
  145. data/src/core/lib/iomgr/ev_epollex_linux.cc +29 -54
  146. data/src/core/lib/iomgr/exec_ctx.cc +27 -17
  147. data/src/core/lib/iomgr/exec_ctx.h +3 -0
  148. data/src/core/lib/iomgr/sockaddr_utils.cc +1 -3
  149. data/src/core/lib/iomgr/tcp_posix.cc +16 -25
  150. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -1
  151. data/src/core/lib/iomgr/timer_manager.cc +8 -1
  152. data/src/core/lib/iomgr/timer_manager.h +2 -0
  153. data/src/core/lib/security/credentials/credentials.h +8 -2
  154. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +23 -0
  155. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +3 -0
  156. data/src/core/lib/security/credentials/tls/spiffe_credentials.cc +3 -3
  157. data/src/core/lib/security/security_connector/ssl_utils.cc +1 -12
  158. data/src/core/lib/security/security_connector/ssl_utils.h +10 -6
  159. data/src/core/lib/security/security_connector/ssl_utils_config.cc +32 -0
  160. data/src/core/lib/security/security_connector/ssl_utils_config.h +30 -0
  161. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +161 -49
  162. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +34 -1
  163. data/src/core/lib/slice/slice_intern.cc +17 -9
  164. data/src/core/lib/slice/slice_internal.h +34 -7
  165. data/src/core/lib/slice/slice_utils.h +7 -3
  166. data/src/core/lib/surface/call.cc +97 -57
  167. data/src/core/lib/surface/channel.cc +2 -2
  168. data/src/core/lib/surface/completion_queue.cc +10 -16
  169. data/src/core/lib/surface/init.cc +3 -0
  170. data/src/core/lib/surface/server.cc +11 -14
  171. data/src/core/lib/surface/validate_metadata.cc +4 -0
  172. data/src/core/lib/surface/version.cc +2 -2
  173. data/src/core/lib/transport/metadata.cc +4 -4
  174. data/src/core/lib/transport/metadata_batch.cc +72 -16
  175. data/src/core/lib/transport/metadata_batch.h +38 -0
  176. data/src/core/lib/transport/static_metadata.cc +814 -1023
  177. data/src/core/lib/transport/static_metadata.h +271 -213
  178. data/src/core/lib/transport/transport.h +12 -0
  179. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  180. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +104 -76
  181. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +34 -16
  182. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +2 -2
  183. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +10 -6
  184. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +4 -3
  185. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +74 -48
  186. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +34 -26
  187. data/src/core/tsi/ssl_transport_security.cc +14 -6
  188. data/src/core/tsi/ssl_transport_security.h +4 -0
  189. data/src/ruby/ext/grpc/ext-export.clang +1 -0
  190. data/src/ruby/ext/grpc/ext-export.gcc +6 -0
  191. data/src/ruby/ext/grpc/extconf.rb +5 -0
  192. data/src/ruby/ext/grpc/rb_enable_cpp.cc +22 -0
  193. data/src/ruby/ext/grpc/rb_grpc.c +1 -42
  194. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  195. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  196. data/src/ruby/lib/grpc.rb +2 -0
  197. data/src/ruby/lib/grpc/core/status_codes.rb +135 -0
  198. data/src/ruby/lib/grpc/errors.rb +4 -7
  199. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +9 -4
  200. data/src/ruby/lib/grpc/structs.rb +15 -0
  201. data/src/ruby/lib/grpc/version.rb +1 -1
  202. data/src/ruby/spec/errors_spec.rb +1 -0
  203. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_import.proto +22 -0
  204. data/src/ruby/spec/pb/codegen/grpc/testing/package_options_ruby_style.proto +34 -0
  205. data/src/ruby/spec/pb/codegen/package_option_spec.rb +53 -29
  206. data/third_party/upb/upb/decode.c +604 -0
  207. data/third_party/upb/upb/decode.h +21 -0
  208. data/third_party/upb/upb/encode.c +378 -0
  209. data/third_party/upb/upb/encode.h +21 -0
  210. data/third_party/upb/upb/generated_util.h +105 -0
  211. data/third_party/upb/upb/msg.c +111 -0
  212. data/third_party/upb/upb/msg.h +69 -0
  213. data/third_party/upb/upb/port.c +27 -0
  214. data/third_party/upb/upb/port_def.inc +152 -0
  215. data/third_party/upb/upb/port_undef.inc +21 -0
  216. data/third_party/upb/upb/table.c +911 -0
  217. data/third_party/upb/upb/table.int.h +507 -0
  218. data/third_party/upb/upb/upb.c +261 -0
  219. data/third_party/upb/upb/upb.h +364 -0
  220. metadata +134 -55
  221. data/src/core/ext/filters/client_channel/health/health.pb.c +0 -23
  222. data/src/core/ext/filters/client_channel/health/health.pb.h +0 -73
  223. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c +0 -19
  224. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h +0 -54
  225. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c +0 -19
  226. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h +0 -54
  227. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +0 -89
  228. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -164
  229. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc +0 -520
  230. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.h +0 -323
  231. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc +0 -145
  232. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +0 -149
  233. data/src/core/tsi/alts/handshaker/altscontext.pb.c +0 -47
  234. data/src/core/tsi/alts/handshaker/altscontext.pb.h +0 -63
  235. data/src/core/tsi/alts/handshaker/handshaker.pb.c +0 -122
  236. data/src/core/tsi/alts/handshaker/handshaker.pb.h +0 -254
  237. data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +0 -49
  238. data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +0 -78
  239. data/third_party/nanopb/pb.h +0 -579
  240. data/third_party/nanopb/pb_common.c +0 -97
  241. data/third_party/nanopb/pb_common.h +0 -42
  242. data/third_party/nanopb/pb_decode.c +0 -1347
  243. data/third_party/nanopb/pb_decode.h +0 -149
  244. data/third_party/nanopb/pb_encode.c +0 -696
  245. data/third_party/nanopb/pb_encode.h +0 -154
@@ -214,6 +214,8 @@ void grpc_channel_args_destroy(grpc_channel_args* a) {
214
214
 
215
215
  int grpc_channel_args_compare(const grpc_channel_args* a,
216
216
  const grpc_channel_args* b) {
217
+ if (a == nullptr && b == nullptr) return 0;
218
+ if (a == nullptr || b == nullptr) return a == nullptr ? -1 : 1;
217
219
  int c = GPR_ICMP(a->num_args, b->num_args);
218
220
  if (c != 0) return c;
219
221
  for (size_t i = 0; i < a->num_args; i++) {
@@ -255,6 +257,13 @@ int grpc_channel_arg_get_integer(const grpc_arg* arg,
255
257
  return arg->value.integer;
256
258
  }
257
259
 
260
+ int grpc_channel_args_find_integer(const grpc_channel_args* args,
261
+ const char* name,
262
+ const grpc_integer_options options) {
263
+ const grpc_arg* arg = grpc_channel_args_find(args, name);
264
+ return grpc_channel_arg_get_integer(arg, options);
265
+ }
266
+
258
267
  char* grpc_channel_arg_get_string(const grpc_arg* arg) {
259
268
  if (arg == nullptr) return nullptr;
260
269
  if (arg->type != GRPC_ARG_STRING) {
@@ -264,6 +273,12 @@ char* grpc_channel_arg_get_string(const grpc_arg* arg) {
264
273
  return arg->value.string;
265
274
  }
266
275
 
276
+ char* grpc_channel_args_find_string(const grpc_channel_args* args,
277
+ const char* name) {
278
+ const grpc_arg* arg = grpc_channel_args_find(args, name);
279
+ return grpc_channel_arg_get_string(arg);
280
+ }
281
+
267
282
  bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value) {
268
283
  if (arg == nullptr) return default_value;
269
284
  if (arg->type != GRPC_ARG_INTEGER) {
@@ -282,6 +297,12 @@ bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value) {
282
297
  }
283
298
  }
284
299
 
300
+ bool grpc_channel_args_find_bool(const grpc_channel_args* args,
301
+ const char* name, bool default_value) {
302
+ const grpc_arg* arg = grpc_channel_args_find(args, name);
303
+ return grpc_channel_arg_get_bool(arg, default_value);
304
+ }
305
+
285
306
  bool grpc_channel_args_want_minimal_stack(const grpc_channel_args* args) {
286
307
  return grpc_channel_arg_get_bool(
287
308
  grpc_channel_args_find(args, GRPC_ARG_MINIMAL_STACK), false);
@@ -73,16 +73,30 @@ typedef struct grpc_integer_options {
73
73
  int max_value;
74
74
  } grpc_integer_options;
75
75
 
76
- /** Returns the value of \a arg, subject to the contraints in \a options. */
76
+ /** Returns the value of \a arg, subject to the constraints in \a options. */
77
77
  int grpc_channel_arg_get_integer(const grpc_arg* arg,
78
78
  const grpc_integer_options options);
79
+ /** Similar to the above, but needs to find the arg from \a args by the name
80
+ * first. */
81
+ int grpc_channel_args_find_integer(const grpc_channel_args* args,
82
+ const char* name,
83
+ const grpc_integer_options options);
79
84
 
80
85
  /** Returns the value of \a arg if \a arg is of type GRPC_ARG_STRING.
81
86
  Otherwise, emits a warning log, and returns nullptr.
82
87
  If arg is nullptr, returns nullptr, and does not emit a warning. */
83
88
  char* grpc_channel_arg_get_string(const grpc_arg* arg);
84
-
89
+ /** Similar to the above, but needs to find the arg from \a args by the name
90
+ * first. */
91
+ char* grpc_channel_args_find_string(const grpc_channel_args* args,
92
+ const char* name);
93
+ /** If \a arg is of type GRPC_ARG_INTEGER, returns true if it's non-zero.
94
+ * Returns \a default_value if \a arg is of other types. */
85
95
  bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value);
96
+ /** Similar to the above, but needs to find the arg from \a args by the name
97
+ * first. */
98
+ bool grpc_channel_args_find_bool(const grpc_channel_args* args,
99
+ const char* name, bool default_value);
86
100
 
87
101
  // Helpers for creating channel args.
88
102
  grpc_arg grpc_channel_arg_string_create(char* name, char* value);
@@ -42,6 +42,7 @@
42
42
  #include <grpc/support/time.h>
43
43
 
44
44
  #include "src/core/lib/debug/trace.h"
45
+ #include "src/core/lib/gpr/time_precise.h"
45
46
  #include "src/core/lib/gprpp/arena.h"
46
47
  #include "src/core/lib/iomgr/call_combiner.h"
47
48
  #include "src/core/lib/iomgr/polling_entity.h"
@@ -67,7 +68,7 @@ typedef struct {
67
68
  const void* server_transport_data;
68
69
  grpc_call_context_element* context;
69
70
  const grpc_slice& path;
70
- gpr_timespec start_time;
71
+ gpr_cycle_counter start_time;
71
72
  grpc_millis deadline;
72
73
  grpc_core::Arena* arena;
73
74
  grpc_core::CallCombiner* call_combiner;
@@ -107,51 +107,45 @@ char* BaseNode::RenderJsonString() {
107
107
 
108
108
  CallCountingHelper::CallCountingHelper() {
109
109
  num_cores_ = GPR_MAX(1, gpr_cpu_num_cores());
110
- per_cpu_counter_data_storage_ = static_cast<AtomicCounterData*>(
111
- gpr_zalloc(sizeof(AtomicCounterData) * num_cores_));
112
- }
113
-
114
- CallCountingHelper::~CallCountingHelper() {
115
- gpr_free(per_cpu_counter_data_storage_);
110
+ per_cpu_counter_data_storage_.reserve(num_cores_);
111
+ for (size_t i = 0; i < num_cores_; ++i) {
112
+ per_cpu_counter_data_storage_.emplace_back();
113
+ }
116
114
  }
117
115
 
118
116
  void CallCountingHelper::RecordCallStarted() {
119
- gpr_atm_no_barrier_fetch_add(
120
- &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
121
- .calls_started,
122
- static_cast<gpr_atm>(1));
123
- gpr_atm_no_barrier_store(
124
- &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
125
- .last_call_started_millis,
126
- (gpr_atm)ExecCtx::Get()->Now());
117
+ AtomicCounterData& data =
118
+ per_cpu_counter_data_storage_[ExecCtx::Get()->starting_cpu()];
119
+ data.calls_started.FetchAdd(1, MemoryOrder::RELAXED);
120
+ data.last_call_started_cycle.Store(gpr_get_cycle_counter(),
121
+ MemoryOrder::RELAXED);
127
122
  }
128
123
 
129
124
  void CallCountingHelper::RecordCallFailed() {
130
- gpr_atm_no_barrier_fetch_add(
131
- &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
132
- .calls_failed,
133
- static_cast<gpr_atm>(1));
125
+ per_cpu_counter_data_storage_[ExecCtx::Get()->starting_cpu()]
126
+ .calls_failed.FetchAdd(1, MemoryOrder::RELAXED);
134
127
  }
135
128
 
136
129
  void CallCountingHelper::RecordCallSucceeded() {
137
- gpr_atm_no_barrier_fetch_add(
138
- &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
139
- .calls_succeeded,
140
- static_cast<gpr_atm>(1));
130
+ per_cpu_counter_data_storage_[ExecCtx::Get()->starting_cpu()]
131
+ .calls_succeeded.FetchAdd(1, MemoryOrder::RELAXED);
141
132
  }
142
133
 
143
134
  void CallCountingHelper::CollectData(CounterData* out) {
144
135
  for (size_t core = 0; core < num_cores_; ++core) {
145
- out->calls_started += gpr_atm_no_barrier_load(
146
- &per_cpu_counter_data_storage_[core].calls_started);
147
- out->calls_succeeded += gpr_atm_no_barrier_load(
148
- &per_cpu_counter_data_storage_[core].calls_succeeded);
149
- out->calls_failed += gpr_atm_no_barrier_load(
150
- &per_cpu_counter_data_storage_[core].calls_failed);
151
- gpr_atm last_call = gpr_atm_no_barrier_load(
152
- &per_cpu_counter_data_storage_[core].last_call_started_millis);
153
- if (last_call > out->last_call_started_millis) {
154
- out->last_call_started_millis = last_call;
136
+ AtomicCounterData& data = per_cpu_counter_data_storage_[core];
137
+
138
+ out->calls_started += data.calls_started.Load(MemoryOrder::RELAXED);
139
+ out->calls_succeeded +=
140
+ per_cpu_counter_data_storage_[core].calls_succeeded.Load(
141
+ MemoryOrder::RELAXED);
142
+ out->calls_failed += per_cpu_counter_data_storage_[core].calls_failed.Load(
143
+ MemoryOrder::RELAXED);
144
+ const gpr_cycle_counter last_call =
145
+ per_cpu_counter_data_storage_[core].last_call_started_cycle.Load(
146
+ MemoryOrder::RELAXED);
147
+ if (last_call > out->last_call_started_cycle) {
148
+ out->last_call_started_cycle = last_call;
155
149
  }
156
150
  }
157
151
  }
@@ -173,8 +167,9 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) {
173
167
  json, json_iterator, "callsFailed", data.calls_failed);
174
168
  }
175
169
  if (data.calls_started != 0) {
176
- gpr_timespec ts = grpc_millis_to_timespec(data.last_call_started_millis,
177
- GPR_CLOCK_REALTIME);
170
+ gpr_timespec ts = gpr_convert_clock_type(
171
+ gpr_cycle_counter_to_time(data.last_call_started_cycle),
172
+ GPR_CLOCK_REALTIME);
178
173
  json_iterator =
179
174
  grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp",
180
175
  gpr_format_timespec(ts), GRPC_JSON_STRING, true);
@@ -493,26 +488,25 @@ SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote,
493
488
 
494
489
  void SocketNode::RecordStreamStartedFromLocal() {
495
490
  gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast<gpr_atm>(1));
496
- gpr_atm_no_barrier_store(&last_local_stream_created_millis_,
497
- (gpr_atm)ExecCtx::Get()->Now());
491
+ gpr_atm_no_barrier_store(&last_local_stream_created_cycle_,
492
+ gpr_get_cycle_counter());
498
493
  }
499
494
 
500
495
  void SocketNode::RecordStreamStartedFromRemote() {
501
496
  gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast<gpr_atm>(1));
502
- gpr_atm_no_barrier_store(&last_remote_stream_created_millis_,
503
- (gpr_atm)ExecCtx::Get()->Now());
497
+ gpr_atm_no_barrier_store(&last_remote_stream_created_cycle_,
498
+ gpr_get_cycle_counter());
504
499
  }
505
500
 
506
501
  void SocketNode::RecordMessagesSent(uint32_t num_sent) {
507
502
  gpr_atm_no_barrier_fetch_add(&messages_sent_, static_cast<gpr_atm>(num_sent));
508
- gpr_atm_no_barrier_store(&last_message_sent_millis_,
509
- (gpr_atm)ExecCtx::Get()->Now());
503
+ gpr_atm_no_barrier_store(&last_message_sent_cycle_, gpr_get_cycle_counter());
510
504
  }
511
505
 
512
506
  void SocketNode::RecordMessageReceived() {
513
507
  gpr_atm_no_barrier_fetch_add(&messages_received_, static_cast<gpr_atm>(1));
514
- gpr_atm_no_barrier_store(&last_message_received_millis_,
515
- (gpr_atm)ExecCtx::Get()->Now());
508
+ gpr_atm_no_barrier_store(&last_message_received_cycle_,
509
+ gpr_get_cycle_counter());
516
510
  }
517
511
 
518
512
  grpc_json* SocketNode::RenderJson() {
@@ -545,20 +539,22 @@ grpc_json* SocketNode::RenderJson() {
545
539
  if (streams_started != 0) {
546
540
  json_iterator = grpc_json_add_number_string_child(
547
541
  json, json_iterator, "streamsStarted", streams_started);
548
- gpr_atm last_local_stream_created_millis =
549
- gpr_atm_no_barrier_load(&last_local_stream_created_millis_);
550
- if (last_local_stream_created_millis != 0) {
551
- ts = grpc_millis_to_timespec(last_local_stream_created_millis,
552
- GPR_CLOCK_REALTIME);
542
+ gpr_cycle_counter last_local_stream_created_cycle =
543
+ gpr_atm_no_barrier_load(&last_local_stream_created_cycle_);
544
+ if (last_local_stream_created_cycle != 0) {
545
+ ts = gpr_convert_clock_type(
546
+ gpr_cycle_counter_to_time(last_local_stream_created_cycle),
547
+ GPR_CLOCK_REALTIME);
553
548
  json_iterator = grpc_json_create_child(
554
549
  json_iterator, json, "lastLocalStreamCreatedTimestamp",
555
550
  gpr_format_timespec(ts), GRPC_JSON_STRING, true);
556
551
  }
557
- gpr_atm last_remote_stream_created_millis =
558
- gpr_atm_no_barrier_load(&last_remote_stream_created_millis_);
559
- if (last_remote_stream_created_millis != 0) {
560
- ts = grpc_millis_to_timespec(last_remote_stream_created_millis,
561
- GPR_CLOCK_REALTIME);
552
+ gpr_cycle_counter last_remote_stream_created_cycle =
553
+ gpr_atm_no_barrier_load(&last_remote_stream_created_cycle_);
554
+ if (last_remote_stream_created_cycle != 0) {
555
+ ts = gpr_convert_clock_type(
556
+ gpr_cycle_counter_to_time(last_remote_stream_created_cycle),
557
+ GPR_CLOCK_REALTIME);
562
558
  json_iterator = grpc_json_create_child(
563
559
  json_iterator, json, "lastRemoteStreamCreatedTimestamp",
564
560
  gpr_format_timespec(ts), GRPC_JSON_STRING, true);
@@ -578,8 +574,9 @@ grpc_json* SocketNode::RenderJson() {
578
574
  if (messages_sent != 0) {
579
575
  json_iterator = grpc_json_add_number_string_child(
580
576
  json, json_iterator, "messagesSent", messages_sent);
581
- ts = grpc_millis_to_timespec(
582
- gpr_atm_no_barrier_load(&last_message_sent_millis_),
577
+ ts = gpr_convert_clock_type(
578
+ gpr_cycle_counter_to_time(
579
+ gpr_atm_no_barrier_load(&last_message_sent_cycle_)),
583
580
  GPR_CLOCK_REALTIME);
584
581
  json_iterator =
585
582
  grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp",
@@ -589,8 +586,9 @@ grpc_json* SocketNode::RenderJson() {
589
586
  if (messages_received != 0) {
590
587
  json_iterator = grpc_json_add_number_string_child(
591
588
  json, json_iterator, "messagesReceived", messages_received);
592
- ts = grpc_millis_to_timespec(
593
- gpr_atm_no_barrier_load(&last_message_received_millis_),
589
+ ts = gpr_convert_clock_type(
590
+ gpr_cycle_counter_to_time(
591
+ gpr_atm_no_barrier_load(&last_message_received_cycle_)),
594
592
  GPR_CLOCK_REALTIME);
595
593
  json_iterator = grpc_json_create_child(
596
594
  json_iterator, json, "lastMessageReceivedTimestamp",
@@ -24,6 +24,7 @@
24
24
  #include <grpc/grpc.h>
25
25
 
26
26
  #include "src/core/lib/channel/channel_trace.h"
27
+ #include "src/core/lib/gpr/time_precise.h"
27
28
  #include "src/core/lib/gprpp/inlined_vector.h"
28
29
  #include "src/core/lib/gprpp/manual_constructor.h"
29
30
  #include "src/core/lib/gprpp/map.h"
@@ -80,7 +81,10 @@ class BaseNode : public RefCounted<BaseNode> {
80
81
  kSocket,
81
82
  };
82
83
 
84
+ protected:
83
85
  BaseNode(EntityType type, UniquePtr<char> name);
86
+
87
+ public:
84
88
  virtual ~BaseNode();
85
89
 
86
90
  // All children must implement this function.
@@ -111,7 +115,6 @@ class BaseNode : public RefCounted<BaseNode> {
111
115
  class CallCountingHelper {
112
116
  public:
113
117
  CallCountingHelper();
114
- ~CallCountingHelper();
115
118
 
116
119
  void RecordCallStarted();
117
120
  void RecordCallFailed();
@@ -124,24 +127,38 @@ class CallCountingHelper {
124
127
  // testing peer friend.
125
128
  friend class testing::CallCountingHelperPeer;
126
129
 
130
+ // TODO(soheil): add a proper PerCPU helper and use it here.
127
131
  struct AtomicCounterData {
128
- gpr_atm calls_started = 0;
129
- gpr_atm calls_succeeded = 0;
130
- gpr_atm calls_failed = 0;
131
- gpr_atm last_call_started_millis = 0;
132
- };
132
+ // Define the ctors so that we can use this structure in InlinedVector.
133
+ AtomicCounterData() = default;
134
+ AtomicCounterData(const AtomicCounterData& that)
135
+ : calls_started(that.calls_started.Load(MemoryOrder::RELAXED)),
136
+ calls_succeeded(that.calls_succeeded.Load(MemoryOrder::RELAXED)),
137
+ calls_failed(that.calls_failed.Load(MemoryOrder::RELAXED)),
138
+ last_call_started_cycle(
139
+ that.last_call_started_cycle.Load(MemoryOrder::RELAXED)) {}
140
+
141
+ Atomic<intptr_t> calls_started{0};
142
+ Atomic<intptr_t> calls_succeeded{0};
143
+ Atomic<intptr_t> calls_failed{0};
144
+ Atomic<gpr_cycle_counter> last_call_started_cycle{0};
145
+ // Make sure the size is exactly one cache line.
146
+ uint8_t padding[GPR_CACHELINE_SIZE - 3 * sizeof(Atomic<intptr_t>) -
147
+ sizeof(Atomic<gpr_cycle_counter>)];
148
+ } GPR_ALIGN_STRUCT(GPR_CACHELINE_SIZE);
133
149
 
134
150
  struct CounterData {
135
151
  intptr_t calls_started = 0;
136
152
  intptr_t calls_succeeded = 0;
137
153
  intptr_t calls_failed = 0;
138
- intptr_t last_call_started_millis = 0;
154
+ gpr_cycle_counter last_call_started_cycle = 0;
139
155
  };
140
156
 
141
157
  // collects the sharded data into one CounterData struct.
142
158
  void CollectData(CounterData* out);
143
159
 
144
- AtomicCounterData* per_cpu_counter_data_storage_ = nullptr;
160
+ // Really zero-sized, but 0-sized arrays are illegal on MSVC.
161
+ InlinedVector<AtomicCounterData, 1> per_cpu_counter_data_storage_;
145
162
  size_t num_cores_ = 0;
146
163
  };
147
164
 
@@ -281,10 +298,10 @@ class SocketNode : public BaseNode {
281
298
  gpr_atm messages_sent_ = 0;
282
299
  gpr_atm messages_received_ = 0;
283
300
  gpr_atm keepalives_sent_ = 0;
284
- gpr_atm last_local_stream_created_millis_ = 0;
285
- gpr_atm last_remote_stream_created_millis_ = 0;
286
- gpr_atm last_message_sent_millis_ = 0;
287
- gpr_atm last_message_received_millis_ = 0;
301
+ gpr_atm last_local_stream_created_cycle_ = 0;
302
+ gpr_atm last_remote_stream_created_cycle_ = 0;
303
+ gpr_atm last_message_sent_cycle_ = 0;
304
+ gpr_atm last_message_received_cycle_ = 0;
288
305
  UniquePtr<char> local_;
289
306
  UniquePtr<char> remote_;
290
307
  };
@@ -127,7 +127,8 @@ void grpc_compression_options_disable_algorithm(
127
127
  int grpc_compression_options_is_algorithm_enabled(
128
128
  const grpc_compression_options* opts,
129
129
  grpc_compression_algorithm algorithm) {
130
- return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
130
+ return grpc_compression_options_is_algorithm_enabled_internal(opts,
131
+ algorithm);
131
132
  }
132
133
 
133
134
  grpc_slice grpc_compression_algorithm_slice(
@@ -23,6 +23,8 @@
23
23
 
24
24
  #include <grpc/impl/codegen/compression_types.h>
25
25
 
26
+ #include "src/core/lib/gpr/useful.h"
27
+
26
28
  #ifdef __cplusplus
27
29
  extern "C" {
28
30
  #endif
@@ -85,4 +87,10 @@ int grpc_stream_compression_algorithm_parse(
85
87
  }
86
88
  #endif
87
89
 
90
+ inline int grpc_compression_options_is_algorithm_enabled_internal(
91
+ const grpc_compression_options* opts,
92
+ grpc_compression_algorithm algorithm) {
93
+ return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
94
+ }
95
+
88
96
  #endif /* GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H */
@@ -40,7 +40,7 @@
40
40
  #include <time.h>
41
41
  #include <unistd.h>
42
42
 
43
- static long gettid(void) { return syscall(__NR_gettid); }
43
+ static long sys_gettid(void) { return syscall(__NR_gettid); }
44
44
 
45
45
  void gpr_log(const char* file, int line, gpr_log_severity severity,
46
46
  const char* format, ...) {
@@ -70,7 +70,7 @@ void gpr_default_log(gpr_log_func_args* args) {
70
70
  gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
71
71
  struct tm tm;
72
72
  static __thread long tid = 0;
73
- if (tid == 0) tid = gettid();
73
+ if (tid == 0) tid = sys_gettid();
74
74
 
75
75
  timer = static_cast<time_t>(now.tv_sec);
76
76
  final_slash = strrchr(args->file, '/');
@@ -31,7 +31,7 @@
31
31
  #include <string.h>
32
32
  #include <time.h>
33
33
 
34
- static intptr_t gettid(void) { return (intptr_t)pthread_self(); }
34
+ static intptr_t sys_gettid(void) { return (intptr_t)pthread_self(); }
35
35
 
36
36
  void gpr_log(const char* file, int line, gpr_log_severity severity,
37
37
  const char* format, ...) {
@@ -86,7 +86,7 @@ void gpr_default_log(gpr_log_func_args* args) {
86
86
  char* prefix;
87
87
  gpr_asprintf(&prefix, "%s%s.%09d %7" PRIdPTR " %s:%d]",
88
88
  gpr_log_severity_string(args->severity), time_buffer,
89
- (int)(now.tv_nsec), gettid(), display_file, args->line);
89
+ (int)(now.tv_nsec), sys_gettid(), display_file, args->line);
90
90
 
91
91
  fprintf(stderr, "%-70s %s\n", prefix, args->message);
92
92
  gpr_free(prefix);
@@ -18,61 +18,148 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #if GPR_LINUX
22
+ #include <fcntl.h>
23
+ #include <unistd.h>
24
+ #endif
25
+
26
+ #include <algorithm>
27
+
28
+ #include <grpc/impl/codegen/gpr_types.h>
21
29
  #include <grpc/support/log.h>
22
30
  #include <grpc/support/time.h>
23
- #include <stdio.h>
24
31
 
25
32
  #include "src/core/lib/gpr/time_precise.h"
26
33
 
27
- #ifdef GRPC_TIMERS_RDTSC
28
- #if defined(__i386__)
29
- static void gpr_get_cycle_counter(int64_t int* clk) {
30
- int64_t int ret;
31
- __asm__ volatile("rdtsc" : "=A"(ret));
32
- *clk = ret;
34
+ #if GPR_CYCLE_COUNTER_RDTSC_32 or GPR_CYCLE_COUNTER_RDTSC_64
35
+ #if GPR_LINUX
36
+ static bool read_freq_from_kernel(double* freq) {
37
+ // Google production kernel export the frequency for us in kHz.
38
+ int fd = open("/sys/devices/system/cpu/cpu0/tsc_freq_khz", O_RDONLY);
39
+ if (fd == -1) {
40
+ return false;
41
+ }
42
+ char line[1024] = {};
43
+ char* err;
44
+ bool ret = false;
45
+ int len = read(fd, line, sizeof(line) - 1);
46
+ if (len > 0) {
47
+ const long val = strtol(line, &err, 10);
48
+ if (line[0] != '\0' && (*err == '\n' || *err == '\0')) {
49
+ *freq = val * 1e3; // Value is kHz.
50
+ ret = true;
51
+ }
52
+ }
53
+ close(fd);
54
+ return ret;
33
55
  }
56
+ #endif /* GPR_LINUX */
34
57
 
35
- // ----------------------------------------------------------------
36
- #elif defined(__x86_64__) || defined(__amd64__)
37
- static void gpr_get_cycle_counter(int64_t* clk) {
38
- uint64_t low, high;
39
- __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
40
- *clk = (int64_t)(high << 32) | (int64_t)low;
58
+ static double cycles_per_second = 0;
59
+ static gpr_cycle_counter start_cycle;
60
+
61
+ static bool is_fake_clock() {
62
+ gpr_timespec start = gpr_now(GPR_CLOCK_MONOTONIC);
63
+ int64_t sum = 0;
64
+ for (int i = 0; i < 8; ++i) {
65
+ gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
66
+ gpr_timespec delta = gpr_time_sub(now, start);
67
+ sum += delta.tv_sec * GPR_NS_PER_SEC + delta.tv_nsec;
68
+ }
69
+ // If the clock doesn't move even a nano after 8 tries, it's a fake one.
70
+ return sum == 0;
41
71
  }
42
- #endif
43
72
 
44
- static double cycles_per_second = 0;
45
- static int64_t start_cycle;
46
73
  void gpr_precise_clock_init(void) {
47
- time_t start;
48
- int64_t end_cycle;
49
74
  gpr_log(GPR_DEBUG, "Calibrating timers");
50
- start = time(NULL);
51
- while (time(NULL) == start)
52
- ;
53
- gpr_get_cycle_counter(&start_cycle);
54
- while (time(NULL) <= start + 10)
55
- ;
56
- gpr_get_cycle_counter(&end_cycle);
57
- cycles_per_second = (double)(end_cycle - start_cycle) / 10.0;
75
+
76
+ #if GPR_LINUX
77
+ if (read_freq_from_kernel(&cycles_per_second)) {
78
+ start_cycle = gpr_get_cycle_counter();
79
+ return;
80
+ }
81
+ #endif /* GPR_LINUX */
82
+
83
+ if (is_fake_clock()) {
84
+ cycles_per_second = 1;
85
+ start_cycle = 0;
86
+ return;
87
+ }
88
+ // Start from a loop of 1ms, and gradually increase the loop duration
89
+ // until we either converge or we have passed 255ms (1ms+2ms+...+128ms).
90
+ int64_t measurement_ns = GPR_NS_PER_MS;
91
+ double last_freq = -1;
92
+ bool converged = false;
93
+ for (int i = 0; i < 8 && !converged; ++i, measurement_ns *= 2) {
94
+ start_cycle = gpr_get_cycle_counter();
95
+ int64_t loop_ns;
96
+ gpr_timespec start = gpr_now(GPR_CLOCK_MONOTONIC);
97
+ do {
98
+ // TODO(soheil): Maybe sleep instead of busy polling.
99
+ gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
100
+ gpr_timespec delta = gpr_time_sub(now, start);
101
+ loop_ns = delta.tv_sec * GPR_NS_PER_SEC + delta.tv_nsec;
102
+ } while (loop_ns < measurement_ns);
103
+ gpr_cycle_counter end_cycle = gpr_get_cycle_counter();
104
+ // Frequency should be in Hz.
105
+ const double freq =
106
+ static_cast<double>(end_cycle - start_cycle) / loop_ns * GPR_NS_PER_SEC;
107
+ converged =
108
+ last_freq != -1 && (freq * 0.99 < last_freq && last_freq < freq * 1.01);
109
+ last_freq = freq;
110
+ }
111
+ cycles_per_second = last_freq;
58
112
  gpr_log(GPR_DEBUG, "... cycles_per_second = %f\n", cycles_per_second);
59
113
  }
60
114
 
61
- void gpr_precise_clock_now(gpr_timespec* clk) {
62
- int64_t counter;
63
- double secs;
64
- gpr_get_cycle_counter(&counter);
65
- secs = (double)(counter - start_cycle) / cycles_per_second;
66
- clk->clock_type = GPR_CLOCK_PRECISE;
67
- clk->tv_sec = (int64_t)secs;
68
- clk->tv_nsec = (int32_t)(1e9 * (secs - (double)clk->tv_sec));
115
+ gpr_timespec gpr_cycle_counter_to_time(gpr_cycle_counter cycles) {
116
+ const double secs =
117
+ static_cast<double>(cycles - start_cycle) / cycles_per_second;
118
+ gpr_timespec ts;
119
+ ts.tv_sec = static_cast<int64_t>(secs);
120
+ ts.tv_nsec = static_cast<int32_t>(GPR_NS_PER_SEC *
121
+ (secs - static_cast<double>(ts.tv_sec)));
122
+ ts.clock_type = GPR_CLOCK_PRECISE;
123
+ return ts;
69
124
  }
70
125
 
71
- #else /* GRPC_TIMERS_RDTSC */
126
+ gpr_timespec gpr_cycle_counter_sub(gpr_cycle_counter a, gpr_cycle_counter b) {
127
+ const double secs = static_cast<double>(a - b) / cycles_per_second;
128
+ gpr_timespec ts;
129
+ ts.tv_sec = static_cast<int64_t>(secs);
130
+ ts.tv_nsec = static_cast<int32_t>(GPR_NS_PER_SEC *
131
+ (secs - static_cast<double>(ts.tv_sec)));
132
+ ts.clock_type = GPR_TIMESPAN;
133
+ return ts;
134
+ }
135
+
136
+ void gpr_precise_clock_now(gpr_timespec* clk) {
137
+ int64_t counter = gpr_get_cycle_counter();
138
+ *clk = gpr_cycle_counter_to_time(counter);
139
+ }
140
+ #elif GPR_CYCLE_COUNTER_FALLBACK
72
141
  void gpr_precise_clock_init(void) {}
73
142
 
143
+ gpr_cycle_counter gpr_get_cycle_counter() {
144
+ gpr_timespec ts = gpr_now(GPR_CLOCK_REALTIME);
145
+ return gpr_timespec_to_micros(ts);
146
+ }
147
+
148
+ gpr_timespec gpr_cycle_counter_to_time(gpr_cycle_counter cycles) {
149
+ gpr_timespec ts;
150
+ ts.tv_sec = cycles / GPR_US_PER_SEC;
151
+ ts.tv_nsec = (cycles - ts.tv_sec * GPR_US_PER_SEC) * GPR_NS_PER_US;
152
+ ts.clock_type = GPR_CLOCK_PRECISE;
153
+ return ts;
154
+ }
155
+
74
156
  void gpr_precise_clock_now(gpr_timespec* clk) {
75
157
  *clk = gpr_now(GPR_CLOCK_REALTIME);
76
158
  clk->clock_type = GPR_CLOCK_PRECISE;
77
159
  }
78
- #endif /* GRPC_TIMERS_RDTSC */
160
+
161
+ gpr_timespec gpr_cycle_counter_sub(gpr_cycle_counter a, gpr_cycle_counter b) {
162
+ return gpr_time_sub(gpr_cycle_counter_to_time(a),
163
+ gpr_cycle_counter_to_time(b));
164
+ }
165
+ #endif /* GPR_CYCLE_COUNTER_FALLBACK */