File 0438-erts-Fix-ets-memstat-false-leak-of-FixedDeletion.patch of Package erlang

From 4253f875c73c577a768847639e9d2411f935d4d2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 3 Sep 2018 20:05:32 +0200
Subject: [PATCH 1/2] erts: Fix ets memstat false leak of FixedDeletion

causing erlang:memory to report too much ets memory.
---
 erts/emulator/beam/erl_db_hash.c |  1 +
 lib/stdlib/test/ets_SUITE.erl    | 45 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index b988a19cf4..b648965885 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -162,6 +162,7 @@ static ERTS_INLINE int link_fixdel(DbTableHash* tb,
         if (NFIXED(tb) <= fixated_by_me) {
             erts_db_free(ERTS_ALC_T_DB_FIX_DEL, (DbTable*)tb,
                          fixd, sizeof(FixedDeletion));
+            ERTS_ETS_MISC_MEM_ADD(-sizeof(FixedDeletion));
             return 0; /* raced by unfixer */
         }
         exp_next = was_next;
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 7a48d1d55e..d8912e548c 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -64,7 +64,7 @@
 	 meta_lookup_named_read/1, meta_lookup_named_write/1,
 	 meta_newdel_unnamed/1, meta_newdel_named/1]).
 -export([smp_insert/1, smp_fixed_delete/1, smp_unfix_fix/1, smp_select_delete/1,
-         otp_8166/1, otp_8732/1]).
+         otp_8166/1, otp_8732/1, delete_unfix_race/1]).
 -export([exit_large_table_owner/1,
 	 exit_many_large_table_owner/1,
 	 exit_many_tables_owner/1,
@@ -156,6 +156,7 @@ all() ->
      otp_9423,
      ets_all,
      take,
+     delete_unfix_race,
 
      memory_check_summary]. % MUST BE LAST
 
@@ -5190,6 +5191,46 @@ smp_fixed_delete_do() ->
     %%verify_table_load(T),
     ets:delete(T).
 
+%% ERL-720
+%% Provoke race between ets:delete and table unfix (by select_count)
+%% that caused ets_misc memory counter to indicate false leak.
+delete_unfix_race(Config) when is_list(Config) ->
+    EtsMem = etsmem(),
+    Table = ets:new(t,[set,public,{write_concurrency,true}]),
+    InsertOp =
+        fun() ->
+                receive stop ->
+                        false
+                after 0 ->
+                        ets:insert(Table, {rand:uniform(10)}),
+                        true
+                end
+        end,
+    DeleteOp =
+        fun() ->
+                receive stop ->
+                        false
+                after 0 ->
+                        ets:delete(Table, rand:uniform(10)),
+                        true
+                end
+        end,
+    SelectOp =
+        fun() ->
+                ets:select_count(Table, ets:fun2ms(fun(X) -> true end))
+        end,
+    Main = self(),
+    Ins = spawn(fun()-> repeat_while(InsertOp), Main ! self() end),
+    Del = spawn(fun()-> repeat_while(DeleteOp), Main ! self() end),
+    spawn(fun()->
+                  repeat(SelectOp, 10000),
+                  Del ! stop,
+                  Ins ! stop
+          end),
+    [receive Pid -> ok end || Pid <- [Ins,Del]],
+    ets:delete(Table),
+    verify_etsmem(EtsMem).
+
 num_of_buckets(T) ->
     element(1,ets:info(T,stats)).
 
-- 
2.16.4

openSUSE Build Service is sponsored by