Logd retry throttling.

Test: statsd test

BUG: b/77852322
Change-Id: I3b4c46aaa592e21bfed13330c2ca72fac8e8320a
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 057772f..4146e02 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -101,6 +101,7 @@
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
 
+    fprintf(out, "#include <mutex>\n");
     fprintf(out, "#include <chrono>\n");
     fprintf(out, "#include <thread>\n");
     fprintf(out, "#include <log/log_event_list.h>\n");
@@ -150,9 +151,7 @@
     fprintf(out, "};\n");
     fprintf(out, "\n");
 
-    fprintf(out,
-            "static std::map<int, int> "
-            "getAtomUidField() {\n");
+    fprintf(out, "static std::map<int, int> getAtomUidField() {\n");
     fprintf(out, "  std::map<int, int> uidField;\n");
     for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
          atom != atoms.decls.end(); atom++) {
@@ -206,6 +205,11 @@
             "AtomsInfo::kStateAtomsFieldOptions = "
             "getStateAtomFieldOptions();\n");
 
+
+    fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
+    fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
+    fprintf(out, "static std::mutex mLogdRetryMutex;\n");
+
     // Print write methods
     fprintf(out, "\n");
     for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
@@ -317,7 +321,7 @@
        fprintf(out, "{\n");
        fprintf(out, "  int ret = 0;\n");
 
-       fprintf(out, "  for(int retry = 0; retry < 3; ++retry) {\n");
+       fprintf(out, "  for(int retry = 0; retry < 2; ++retry) {\n");
        fprintf(out, "      ret =  try_stats_write(code");
 
        argIndex = 1;
@@ -340,8 +344,15 @@
        }
        fprintf(out, ");\n");
        fprintf(out, "      if (ret >= 0) { return retry; }\n");
-       fprintf(out,
-               "      std::this_thread::sleep_for(std::chrono::milliseconds(10 + 10 * retry));\n");
+
+
+       fprintf(out, "      {\n");
+       fprintf(out, "          std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n");
+       fprintf(out, "          if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= "
+                                "kMinRetryIntervalNs) break;\n");
+       fprintf(out, "          lastRetryTimestampNs = android::elapsedRealtimeNano();\n");
+       fprintf(out, "      }\n");
+       fprintf(out, "      std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
        fprintf(out, "  }\n");
        fprintf(out, "  return ret;\n");
        fprintf(out, "}\n");
@@ -408,7 +419,7 @@
        fprintf(out, "{\n");
 
        fprintf(out, "  int ret = 0;\n");
-       fprintf(out, "  for(int retry = 0; retry < 3; ++retry) {\n");
+       fprintf(out, "  for(int retry = 0; retry < 2; ++retry) {\n");
        fprintf(out, "      ret =  try_stats_write_non_chained(code");
 
        argIndex = 1;
@@ -419,8 +430,15 @@
        }
        fprintf(out, ");\n");
        fprintf(out, "      if (ret >= 0) { return retry; }\n");
-       fprintf(out,
-               "      std::this_thread::sleep_for(std::chrono::milliseconds(10 + 10 * retry));\n");
+
+       fprintf(out, "      {\n");
+       fprintf(out, "          std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n");
+       fprintf(out, "          if ((android::elapsedRealtimeNano() - lastRetryTimestampNs) <= "
+                                "kMinRetryIntervalNs) break;\n");
+       fprintf(out, "          lastRetryTimestampNs = android::elapsedRealtimeNano();\n");
+       fprintf(out, "      }\n");
+
+       fprintf(out, "      std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
        fprintf(out, "  }\n");
        fprintf(out, "  return ret;\n");
        fprintf(out, "}\n");