Browse Source

inprogress - cleanup and expand gproc_eqc test

git-svn-id: http://svn.ulf.wiger.net/gproc/branches/experimental-0906/gproc@21 f3948e33-8234-0410-8a80-a07eae3b6c4d
jwnorton 15 years ago
parent
commit
476b9bd302
2 changed files with 409 additions and 143 deletions
  1. 362 97
      src/gproc_eqc.erl
  2. 47 46
      src/gproc_lib.erl

+ 362 - 97
src/gproc_eqc.erl

@@ -1,101 +1,307 @@
-%%% File    : gproc_eqc.erl
-%%% Author  : <Ulf.Wiger@erlang-consulting.com>
-%%%         : <John.Hughes@quviq.com>
-%%% Description :
-%%% Created : 11 Dec 2008 by  <John Hughes@JTABLET2007>
+%%% File        : gproc_eqc.erl
+%%% Author      : <norton@alum.mit.edu>
+%%%             : <Ulf.Wiger@erlang-consulting.com>
+%%%             : <John.Hughes@quviq.com>
+%%% Description : QuickCheck test model for gproc
+%%% Created     : 11 Dec 2008 by  <John Hughes@JTABLET2007>
+
 -module(gproc_eqc).
 
 
--include_lib("eqc/include/eqc.hrl").
--include_lib("eqc/include/eqc_statem.hrl").
+-include("eqc.hrl").
+-include("eqc_statem.hrl").
 
 -compile(export_all).
 
--record(state,{pids=[],regs=[],killed=[]}).
+
+%% records
+-record(n_reg,
+        {key           %% atom() ... only in this model
+         , pid          %% pid()
+        }).
+
+-record(c_reg,
+        {key           %% atom() ... only in this model
+         , pid          %% pid()
+         , value=0      %% int()
+        }).
+
+-record(a_reg,
+        {key           %% atom() ... only in this model
+         , pid          %% pid()
+         , value=0      %% int()
+        }).
+
+-record(state,
+        {pids=[]        %% [pid()]
+         , killed=[]    %% [pid()]
+         , n_regs=[]    %% [n_reg()]
+         , c_regs=[]    %% [c_reg()]
+         , a_regs=[]    %% [a_reg()]
+        }).
+
 
 %% external API
 start_test() ->
     eqc:module({numtests, 500}, ?MODULE).
 
 run() ->
-    run(200).
+    run(500).
 
 run(Num) ->
     eqc:quickcheck(eqc:numtests(Num, prop_gproc())).
 
-%% Initialize the state
-initial_state() ->
-    #state{}.
 
 %% Command generator, S is the state
+
+%% NOTE: These are the only use cases that make sense to me so far.
+%% Other APIs seem possible but I'm not sure why/how/when they can be
+%% useful.
+
 command(S) ->
     oneof(
-      [{call,?MODULE,spawn,[]}]++
-      [{call,?MODULE,kill,[elements(S#state.pids)]} || S#state.pids/=[]] ++
-      [{call,?MODULE,reg,[name(),elements(S#state.pids)]}
-       || S#state.pids/=[]] ++
-      [{call,?MODULE,unreg,[elements(S#state.regs)]} || S#state.regs/=[]] ++
-      [{call,gproc,where,[{n,l,name()}]}]
+      %% spawn
+      [ {call,?MODULE,spawn,[]} ]
+      %% kill
+      ++ [ {call,?MODULE,kill,[elements(S#state.pids)]}
+           || S#state.pids/=[] ]
+
+      %% name - register
+      ++ [ {call,?MODULE,n_reg,[name(),elements(S#state.pids)]}
+           || S#state.pids/=[] ]
+      %% name - unregister
+      ++ [ {call,?MODULE,n_unreg,[elements(S#state.n_regs)]}
+           || S#state.n_regs/=[] ]
+      %% counter - register
+      ++ [ {call,?MODULE,c_reg,[counter(),elements(S#state.pids),int()]}
+           || S#state.pids/=[] ]
+      %% counter - unregister
+      ++ [ {call,?MODULE,c_unreg,[elements(S#state.c_regs)]}
+           || S#state.c_regs/=[] ]
+      %% aggr counter - register
+      ++ [ {call,?MODULE,a_reg,[aggr_counter(),elements(S#state.pids)]}
+           || S#state.pids/=[] ]
+      %% aggr counter - unregister
+      ++ [ {call,?MODULE,a_unreg,[elements(S#state.a_regs)]}
+           || S#state.a_regs/=[] ]
+
+      %% counter - set_value
+      ++ [ {call,?MODULE,set_value,[elements(S#state.c_regs),int()]}
+           || S#state.c_regs/=[] ]
+
+      %% aggr counter - get_value
+      ++ [{call,?MODULE,get_value,[elements(S#state.c_regs)]}
+          || S#state.c_regs/=[] ]
+      ++ [{call,?MODULE,get_value,[elements(S#state.a_regs)]}
+          || S#state.a_regs/=[] ]
+
+      %% name - where
+      ++ [{call,gproc,where,[{n,l,name()}]}]
+      %% aggr counter - where
+      ++ [{call,gproc,where,[{a,l,aggr_counter()}]}]
+      %% counter - lookup_pids
+      ++ [ {call,gproc,lookup_pids,[{c,l,counter()}]}
+           || S#state.c_regs/=[] ]
+
      ).
 
+%% name generator
 name() ->
-    elements([a,b,c,d]).
+    elements([n1,n2,n3,n4]).
+
+%% counter generator
+counter() ->
+    elements([c1,c2,c3,c4]).
+
+%% aggr counter generator
+aggr_counter() ->
+    elements([a1,a2,a3,a4]).
+
+
+%% Initialize the state
+initial_state() ->
+    #state{}.
+
 
 %% Next state transformation, S is the current state
+
+%% spawn
 next_state(S,V,{call,_,spawn,_}) ->
     S#state{pids=[V|S#state.pids]};
+%% kill
 next_state(S,_V,{call,_,kill,[Pid]}) ->
-    S#state{killed=[Pid|S#state.killed],
-            pids=S#state.pids -- [Pid],
-            regs = [{Name,Pid2} || {Name,Pid2} <- S#state.regs,
-                                   Pid/=Pid2]};
-next_state(S,_V,{call,_,reg,[Name,Pid]}) ->
-    case register_ok(S,Name,Pid) of
+    S#state{killed=[Pid|S#state.killed]
+            , pids=S#state.pids -- [Pid]
+            , n_regs=[ X || #n_reg{pid=Pid1}=X <- S#state.n_regs, Pid/=Pid1 ]
+            , c_regs=[ X || #c_reg{pid=Pid1}=X <- S#state.c_regs, Pid/=Pid1 ]
+            , a_regs=[ X || #a_reg{pid=Pid1}=X <- S#state.a_regs, Pid/=Pid1 ]
+           };
+%% n_reg
+next_state(S,_V,{call,_,n_reg,[Name,Pid]}) ->
+    case is_n_register_ok(S,Name,Pid) of
+        false ->
+            S;
+        true ->
+            S#state{n_regs=[#n_reg{key=Name,pid=Pid}|S#state.n_regs]}
+    end;
+%% n_unreg
+next_state(S,_V,{call,_,n_unreg,[#n_reg{key=Name}]}) ->
+    S#state{n_regs=[ X || #n_reg{key=Name1}=X <- S#state.n_regs
+                              , Name/=Name1 ]};
+%% c_reg
+next_state(S,_V,{call,_,c_reg,[Counter,Pid,Value]}) ->
+    case is_c_register_ok(S,Counter,Pid) of
         false ->
             S;
         true ->
-            S#state{regs=[{Name,Pid}|S#state.regs]}
+            S#state{c_regs=[#c_reg{key=Counter,pid=Pid,value=Value}|S#state.c_regs]}
     end;
-next_state(S,_V,{call,_,unreg,[{Name,_}]}) ->
-    S#state{regs=lists:keydelete(Name,1,S#state.regs)};
+%% c_unreg
+next_state(S,_V,{call,_,c_unreg,[#c_reg{key=Counter,pid=Pid}]}) ->
+    S#state{c_regs=[ X || #c_reg{key=Counter1,pid=Pid1}=X <- S#state.c_regs
+                              , Counter/=Counter1 andalso Pid/=Pid1 ]};
+%% a_reg
+next_state(S,_V,{call,_,a_reg,[AggrCounter,Pid]}) ->
+    case is_a_register_ok(S,AggrCounter,Pid) of
+        false ->
+            S;
+        true ->
+            S#state{a_regs=[#a_reg{key=AggrCounter,pid=Pid,value=0}|S#state.a_regs]}
+    end;
+%% a_unreg
+next_state(S,_V,{call,_,a_unreg,[#a_reg{key=AggrCounter}]}) ->
+    S#state{a_regs=[ X || #a_reg{key=AggrCounter1}=X <- S#state.a_regs
+                              , AggrCounter/=AggrCounter1 ]};
+%% set_value
+next_state(S,_V,{call,_,set_value,[#c_reg{key=Counter,pid=Pid},Value]}) ->
+    case is_c_registered_and_alive(S,Counter,Pid) of
+        false ->
+            S;
+        true ->
+            Fun = fun(#c_reg{key=Counter1,pid=Pid1}) -> Counter==Counter1 andalso Pid==Pid1 end,
+            case lists:splitwith(Fun, S#state.c_regs) of
+                {[#c_reg{key=Counter,pid=Pid,value=_OldValue}], Others} ->
+                    S#state{c_regs=[#c_reg{key=Counter,pid=Pid,value=Value}|Others]}
+            end
+    end;
+%% otherwise
 next_state(S,_V,{call,_,_,_}) ->
     S.
 
-%% Precondition, checked before command is added to the command sequence
-%% precondition(S,{call,_,unreg,[Name]}) ->
-%%
-%% precondition(S,{call,_,reg,[Name,Pid]}) ->
-%%
+
+%% Precondition, checked before command is added to the command
+%% sequence
 precondition(_S,{call,_,_,_}) ->
     true.
 
-unregister_ok(S,Name) ->
-    lists:keymember(Name,1,S#state.regs).
 
-register_ok(S,Name,_Pid) ->
-    not lists:keymember(Name,1,S#state.regs).
+%% Postcondition, checked after command has been evaluated.  S is the
+%% state before next_state(S,_,<command>)
 
-%% Postcondition, checked after command has been evaluated
-%% OBS: S is the state before next_state(S,_,<command>)
-postcondition(S,{call,_,where,[{_,_,Name}]},Res) ->
-    Res == proplists:get_value(Name,S#state.regs);
-postcondition(S,{call,_,unreg,[{Name,_}]},Res) ->
+%% spawn
+postcondition(_S,{call,_,spawn,_},_Res) ->
+    true;
+%% kill
+postcondition(_S,{call,_,kill,_},_Res) ->
+    true;
+%% n_reg
+postcondition(S,{call,_,n_reg,[Name,Pid]},Res) ->
     case Res of
         true ->
-            unregister_ok(S,Name);
+            is_n_register_ok(S,Name,Pid);
         {'EXIT',_} ->
-            not unregister_ok(S,Name)
+            not is_n_register_ok(S,Name,Pid)
     end;
-postcondition(S,{call,_,reg,[Name,Pid]},Res) ->
+%% n_unreg
+postcondition(S,{call,_,n_unreg,[#n_reg{key=Name,pid=Pid}]},Res) ->
     case Res of
         true ->
-            register_ok(S,Name,Pid);
+            is_n_unregister_ok(S,Name,Pid);
         {'EXIT',_} ->
-            not register_ok(S,Name,Pid)
+            not is_n_unregister_ok(S,Name,Pid)
     end;
+%% c_reg
+postcondition(S,{call,_,c_reg,[Counter,Pid,_Value]},Res) ->
+    case Res of
+        true ->
+            is_c_register_ok(S,Counter,Pid);
+        {'EXIT',_} ->
+            not is_c_register_ok(S,Counter,Pid)
+    end;
+%% c_unreg
+postcondition(S,{call,_,c_unreg,[#c_reg{key=Counter,pid=Pid}]},Res) ->
+    case Res of
+        true ->
+            is_c_unregister_ok(S,Counter,Pid);
+        {'EXIT',_} ->
+            not is_c_unregister_ok(S,Counter,Pid)
+    end;
+%% a_reg
+postcondition(S,{call,_,a_reg,[AggrCounter,Pid]},Res) ->
+    case Res of
+        true ->
+            is_a_register_ok(S,AggrCounter,Pid);
+        {'EXIT',_} ->
+            not is_a_register_ok(S,AggrCounter,Pid)
+    end;
+%% a_unreg
+postcondition(S,{call,_,a_unreg,[#a_reg{key=AggrCounter,pid=Pid}]},Res) ->
+    case Res of
+        true ->
+            is_a_unregister_ok(S,AggrCounter,Pid);
+        {'EXIT',_} ->
+            not is_a_unregister_ok(S,AggrCounter,Pid)
+    end;
+%% set_value
+postcondition(S,{call,_,set_value,[#c_reg{key=Counter,pid=Pid},_Value]},Res) ->
+    case Res of
+        true ->
+            is_c_registered_and_alive(S,Counter,Pid);
+        {'EXIT',_} ->
+            not is_c_registered_and_alive(S,Counter,Pid)
+    end;
+%% get_value
+postcondition(S,{call,_,get_value,[#c_reg{key=Counter,pid=Pid}]},Res) ->
+    case [ Value1 || #c_reg{key=Counter1,pid=Pid1,value=Value1} <- S#state.c_regs
+                         , Counter==Counter1 andalso Pid==Pid1 ] of
+        [] ->
+            case Res of {'EXIT',_} -> true; _ -> false end;
+        [Value] ->
+            Res == Value
+    end;
+%% get_value
+postcondition(S,{call,_,get_value,[#a_reg{key=AggrCounter,pid=Pid}]},Res) ->
+    case [ Value1 || #a_reg{key=AggrCounter1,pid=Pid1,value=Value1} <- S#state.a_regs
+                         , AggrCounter==AggrCounter1 andalso Pid==Pid1 ] of
+        [] ->
+            case Res of {'EXIT',_} -> true; _ -> false end;
+        [Value] ->
+            Res == Value
+    end;
+%% where
+postcondition(S,{call,_,where,[{n,l,Name}]},Res) ->
+    case lists:keysearch(Name,#n_reg.key,S#state.n_regs) of
+        {value, #n_reg{pid=Pid}} ->
+            Res == Pid;
+        false ->
+            Res == undefined
+    end;
+postcondition(S,{call,_,where,[{a,l,AggrCounter}]},Res) ->
+    case lists:keysearch(AggrCounter,#a_reg.key,S#state.a_regs) of
+        {value, #a_reg{pid=Pid}} ->
+            Res == Pid;
+        false ->
+            Res == undefined
+    end;
+%% lookup_pids
+postcondition(S,{call,_,lookup_pids,[{c,l,Counter}]},Res) ->
+    lists:usort(Res) ==
+        [ Pid || #c_reg{key=Counter1,pid=Pid} <- S#state.c_regs, Counter==Counter1 ];
+%% otherwise
 postcondition(_S,{call,_,_,_},_Res) ->
-    true.
+    false.
 
+%% property
 prop_gproc() ->
     ?FORALL(Cmds,commands(?MODULE),
             ?TRAPEXIT(
@@ -109,20 +315,6 @@ prop_gproc() ->
                       Res == ok)
                end)).
 
-
-seed() ->
-    noshrink({largeint(),largeint(),largeint()}).
-
-cleanup(Tabs,Server) ->
-    unlink(Server),
-    unlink(Tabs),
-    exit(Server,kill),
-    exit(Tabs,kill),
-    catch unregister(proc_reg),
-    catch unregister(proc_reg_tabs),
-    delete_tables(),
-    ok.%    timer:sleep(1).
-
 start_app() ->
     case application:start(gproc) of
         {error, {already_started,_}} ->
@@ -136,9 +328,50 @@ stop_app() ->
     ok = application:stop(gproc).
 
 
-delete_tables() ->
-    catch ets:delete(proc_reg).
+%% If using the scheduler... This code needs to run in a separate
+%% module, so it can be compiled without instrumentation.
 
+kill_all_pids(Pid) when is_pid(Pid) ->
+    case is_process_alive(Pid) of
+        true ->
+            exit(Pid,kill);
+        false ->
+            ok
+    end;
+kill_all_pids(Tup) when is_tuple(Tup) ->
+    kill_all_pids(tuple_to_list(Tup));
+kill_all_pids([H|T]) ->
+    kill_all_pids(H),
+    kill_all_pids(T);
+kill_all_pids(_) ->
+    ok.
+
+
+%% helpers
+is_n_register_ok(S,Name,Pid) ->
+    not is_n_unregister_ok(S,Name,Pid).
+
+is_n_unregister_ok(S,Name,_Pid) ->
+    lists:keymember(Name,#n_reg.key,S#state.n_regs).
+
+is_c_register_ok(S,Counter,Pid) ->
+    not is_c_unregister_ok(S,Counter,Pid).
+
+is_c_unregister_ok(S,Counter,_Pid) ->
+    [] /= [ Pid1 || #c_reg{key=Counter1,pid=Pid1} <- S#state.c_regs, Counter==Counter1 ].
+
+is_a_register_ok(S,AggrCounter,Pid) ->
+    not is_a_unregister_ok(S,AggrCounter,Pid).
+
+is_a_unregister_ok(S,AggrCounter,_Pid) ->
+    lists:keymember(AggrCounter,#a_reg.key,S#state.a_regs).
+
+is_c_registered_and_alive(S,Counter,Pid) ->
+    [Pid] == [ Pid1 || #c_reg{key=Counter1,pid=Pid1} <- S#state.c_regs, Counter==Counter1 ]
+        andalso lists:member(Pid,S#state.pids)
+        andalso not lists:member(Pid,S#state.killed).
+
+%% spawn
 spawn() ->
     spawn(fun() ->
                   loop()
@@ -152,51 +385,83 @@ loop() ->
         stop -> ok
     end.
 
-do(Pid, F) ->
-    Ref = erlang:monitor(process, Pid),
-    Pid ! {self(), Ref, F},
-    receive
-        {'DOWN', Ref, process, Pid, Reason} ->
-            {'EXIT', {'DOWN',Reason}};
-        {Ref, Result} ->
-            erlang:demonitor(Ref),
-            Result
-    after 3000 ->
-            {'EXIT', timeout}
-    end.
-
+%% kill
 kill(Pid) ->
     exit(Pid,foo),
     timer:sleep(10).
 
-unreg({Name,Pid}) ->
+%% n_reg
+n_reg(Name,Pid) ->
+    do(Pid,
+       fun() ->
+               catch gproc:reg({n,l,Name},Pid)
+       end).
+
+%% n_unreg
+n_unreg(#n_reg{key=Name,pid=Pid}) ->
     do(Pid,
        fun() ->
                catch gproc:unreg({n,l,Name})
        end).
 
-reg(Name,Pid) ->
+%% c_reg
+c_reg(Counter,Pid,Value) ->
     do(Pid,
        fun() ->
-               catch gproc:reg({n,l,Name},Pid)
+               catch gproc:reg({c,l,Counter},Value)
        end).
 
+%% c_unreg
+c_unreg(#c_reg{key=Counter,pid=Pid}) ->
+    do(Pid,
+       fun() ->
+               catch gproc:unreg({c,l,Counter})
+       end).
 
-%% If using the scheduler...
-%% This code needs to run in a separate module, so it can be compiled
-%% without instrumentation.
+%% a_reg
+a_reg(AggrCounter,Pid) ->
+    do(Pid,
+       fun() ->
+               catch gproc:reg({a,l,AggrCounter},Pid)
+       end).
 
-kill_all_pids(Pid) when is_pid(Pid) ->
-    case is_process_alive(Pid) of
-        true ->
-            exit(Pid,kill);
-        false ->
-            ok
-    end;
-kill_all_pids(Tup) when is_tuple(Tup) ->
-    kill_all_pids(tuple_to_list(Tup));
-kill_all_pids([H|T]) ->
-    kill_all_pids(H),
-    kill_all_pids(T);
-kill_all_pids(_) ->
-    ok.
+%% a_unreg
+a_unreg(#a_reg{key=AggrCounter,pid=Pid}) ->
+    do(Pid,
+       fun() ->
+               catch gproc:unreg({a,l,AggrCounter})
+       end).
+
+%% set_value
+set_value(#c_reg{key=Counter,pid=Pid},Value) ->
+    do(Pid,
+       fun() ->
+               catch gproc:set_value({c,l,Counter},Value)
+       end).
+
+%% get_value
+get_value(#c_reg{key=Counter,pid=Pid}) ->
+    do(Pid,
+       fun() ->
+               catch gproc:get_value({c,l,Counter})
+       end);
+get_value(#a_reg{key=AggrCounter,pid=Pid}) ->
+    do(Pid,
+       fun() ->
+               catch gproc:get_value({a,l,AggrCounter})
+       end).
+
+
+%% do
+do(Pid, F) ->
+    Ref = erlang:monitor(process, Pid),
+    Pid ! {self(), Ref, F},
+    receive
+        {'DOWN', Ref, process, Pid, Reason} ->
+            {'EXIT', {'DOWN',Reason}};
+        {Ref, Result} ->
+            erlang:demonitor(Ref),
+            Result
+    after 3000 ->
+            {'EXIT', timeout}
+    end.

+ 47 - 46
src/gproc_lib.erl

@@ -3,18 +3,18 @@
 %% compliance with the License. You should have received a copy of the
 %% Erlang Public License along with this software. If not, it can be
 %% retrieved via the world wide web at http://www.erlang.org/.
-%% 
+%%
 %% Software distributed under the License is distributed on an "AS IS"
 %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 %% the License for the specific language governing rights and limitations
 %% under the License.
-%% 
+%%
 %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 %% AB. All Rights Reserved.''
 %%
 %% @author Ulf Wiger <ulf.wiger@ericsson.com>
-%% 
+%%
 %% @doc Extended process registry
 %% <p>This module implements an extended process registry</p>
 %% <p>For a detailed description, see gproc/doc/erlang07-wiger.pdf.</p>
@@ -24,26 +24,27 @@
 
 -include("gproc.hrl").
 
-insert_reg({T,_,Name} = K, Value, Pid, C) when T==a; T==n ->
+insert_reg({T,_,Name} = K, Value, Pid, C) when T==a; T==c; T==n ->
     %%% We want to store names and aggregated counters with the same
     %%% structure as properties, but at the same time, we must ensure
-    %%% that the key is unique. We replace the Pid in the key part with
-    %%% an atom. To know which Pid owns the object, we lug the Pid around
-    %%% as payload as well. This is a bit redundant, but symmetric.
+    %%% that the key is unique. We replace the Pid in the key part
+    %%% with an atom. To know which Pid owns the object, we lug the
+    %%% Pid around as payload as well. This is a bit redundant, but
+    %%% symmetric.
     %%%
     case ets:insert_new(?TAB, [{{K, T}, Pid, Value}, {{Pid,K}}]) of
-	true ->
-	    if T == a ->
-		    Initial = scan_existing_counters(C, Name),
-		    ets:insert(?TAB, {{K,a}, Pid, Initial});
-	       T == c ->
-		    update_aggr_counter(l, Name, Value);
-	       true ->
-		    true
-	    end,
-	    true;
-	false ->
-	    false
+        true ->
+            if T == a ->
+                    Initial = scan_existing_counters(C, Name),
+                    ets:insert(?TAB, {{K,a}, Pid, Initial});
+               T == c ->
+                    update_aggr_counter(l, Name, Value);
+               true ->
+                    true
+            end,
+            true;
+        false ->
+            false
     end;
 insert_reg(Key, Value, Pid, _C) ->
     %% Non-unique keys; store Pid in the key part
@@ -54,37 +55,37 @@ insert_reg(Key, Value, Pid, _C) ->
 insert_many(T, C, KVL, Pid) ->
     Objs = mk_reg_objs(T, C, Pid, KVL),
     case ets:insert_new(?TAB, Objs) of
-	true ->
-	    RevObjs = mk_reg_rev_objs(T, C, Pid, KVL),
-	    ets:insert(?TAB, RevObjs),
-	    {true, Objs};
-	false ->
-	    false
+        true ->
+            RevObjs = mk_reg_rev_objs(T, C, Pid, KVL),
+            ets:insert(?TAB, RevObjs),
+            {true, Objs};
+        false ->
+            false
     end.
 
 
 mk_reg_objs(T, C, _, L) when T == n; T == a ->
     lists:map(fun({K,V}) ->
-		      {{{T,C,K},T}, V};
-		 (_) ->
-		      erlang:error(badarg)
-	      end, L);
+                      {{{T,C,K},T}, V};
+                 (_) ->
+                      erlang:error(badarg)
+              end, L);
 mk_reg_objs(p = T, C, Pid, L) ->
     lists:map(fun({K,V}) ->
-		      {{{T,C,K},Pid}, V};
-		 (_) ->
-		      erlang:error(badarg)
-	      end, L).
+                      {{{T,C,K},Pid}, V};
+                 (_) ->
+                      erlang:error(badarg)
+              end, L).
 
 mk_reg_rev_objs(T, C, Pid, L) ->
     [{Pid,{T,C,K}} || {K,_} <- L].
-			  
+
 
 
 ensure_monitor(Pid) when node(Pid) == node() ->
     case ets:insert_new(?TAB, {Pid}) of
-	false -> ok;
-	true  -> erlang:monitor(process, Pid)
+        false -> ok;
+        true  -> erlang:monitor(process, Pid)
     end;
 ensure_monitor(_) ->
     true.
@@ -106,13 +107,13 @@ remove_counter_1({c,C,N} = Key, Val, Pid) ->
 
 do_set_value({T,_,_} = Key, Value, Pid) ->
     K2 = if T==n -> T;
-	    true -> Pid
-	 end,
+            true -> Pid
+         end,
     case ets:member(?TAB, {Key, K2}) of
-	true ->
-	    ets:insert(?TAB, {{Key, K2}, Pid, Value});
-	false ->
-	    false
+        true ->
+            ets:insert(?TAB, {{Key, K2}, Pid, Value});
+        false ->
+            false
     end.
 
 do_set_counter_value({_,C,N} = Key, Value, Pid) ->
@@ -135,10 +136,10 @@ update_aggr_counter(C, N, Val) ->
 cleanup_counter({c,g,N}=K, Pid, Acc) ->
     remove_reg(K,Pid),
     case ets:lookup(?TAB, {{a,g,N},a}) of
-	[Aggr] ->
-	    [Aggr|Acc];
-	[] ->
-	    Acc
+        [Aggr] ->
+            [Aggr|Acc];
+        [] ->
+            Acc
     end;
 cleanup_counter(K, Pid, Acc) ->
     remove_reg(K,Pid),