1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%% Purpose : Main atomics API module. 22 23-module(counters). 24 25-export([new/2, 26 get/2, 27 add/3, 28 sub/3, 29 put/3, 30 info/1]). 31 32-export_type([counters_ref/0]). 33 34-opaque counters_ref() :: {atomics, reference()} | {write_concurrency, reference()}. 35 36-spec new(Size, Opts) -> counters_ref() when 37 Size :: pos_integer(), 38 Opts :: [Opt], 39 Opt :: atomics | write_concurrency. 40new(Size, [atomics]) -> 41 {atomics, atomics:new(Size, [{signed, true}])}; 42new(Size, [write_concurrency]) -> 43 {write_concurrency, erts_internal:counters_new(Size)}; 44new(Size, []) -> 45 new(Size, [atomics]); 46new(_, _) -> 47 erlang:error(badarg). 48 49-spec get(Ref, Ix) -> integer() when 50 Ref :: counters_ref(), 51 Ix :: integer(). 52get({atomics,Ref}, Ix) -> 53 atomics:get(Ref, Ix); 54get({write_concurrency, Ref}, Ix) -> 55 erts_internal:counters_get(Ref, Ix); 56get(_, _) -> 57 erlang:error(badarg). 58 59 60 61-spec add(Ref, Ix, Incr) -> ok when 62 Ref :: counters_ref(), 63 Ix :: integer(), 64 Incr :: integer(). 65add({atomics, Ref}, Ix, Incr) -> 66 atomics:add(Ref, Ix, Incr); 67add({write_concurrency, Ref}, Ix, Incr) -> 68 erts_internal:counters_add(Ref, Ix, Incr); 69add(_, _, _) -> 70 erlang:error(badarg). 71 72 73-spec sub(Ref, Ix, Decr) -> ok when 74 Ref :: counters_ref(), 75 Ix :: integer(), 76 Decr :: integer(). 77sub(Ref, Ix, Decr) -> 78 add(Ref, Ix, -Decr). 79 80 81-spec put(Ref, Ix, Value) -> ok when 82 Ref :: counters_ref(), 83 Ix :: integer(), 84 Value :: integer(). 85put({atomics, Ref}, Ix, Value) -> 86 atomics:put(Ref, Ix, Value); 87put({write_concurrency, Ref}, Ix, Value) -> 88 erts_internal:counters_put(Ref, Ix, Value); 89put(_, _, _) -> 90 erlang:error(badarg). 91 92 93-spec info(Ref) -> Info when 94 Ref :: counters_ref(), 95 Info :: #{'size':=Size, 'memory':=Memory}, 96 Size :: non_neg_integer(), 97 Memory :: non_neg_integer(). 98info({atomics, Ref}) -> 99 atomics:info(Ref); 100info({write_concurrency, Ref}) -> 101 erts_internal:counters_info(Ref); 102info(_) -> 103 erlang:error(badarg). 104 105