神刀安全网

Vegrandis: Atomic shared variables for Erlang

vegrandis

Copyright (c) 2016 Guilherme Andrade

Version:1.0.0

Authors:Guilherme Andrade ( vegrandis(at)gandrade(dot)net ).

vegrandis : Native atomic shared variables for Erlang

vegrandis provides native atomic variables and flags that can be shared between Erlang processes living in the same node.

It consists of a NIF library wrapping around C++11’s std::atomic ; a majority of the standard integral data types can be used and most of the original operations can be performed, including optionally specifying memory ordering constraints and, if both hardware and compiler implementation allow it, operating in a lockfree fashion.

Any allocated variables will be automatically deallocated by the garbage collector once there are no more references to it.

Original development rig runs OTP 17.5 over GNU/Linux x86_64, and quick test with OTP 17.5 over GNU/Linux ARM was also successful; other platforms have not been tested. Building dependencies include make and g++ (but there’s no reason clang won’t work as well.)

Examples

{ok, AtomicCounter} = vegrandis_var:new(uint8), Increments = 10, Parent = self(),  [spawn(     fun () ->         Parent ! vegrandis_var:fetch_add(AtomicCounter, 1)     end)  || _ <- lists:seq(1, Increments)],  % [0,1,2,3,4,5,6,7,8,9] [receive Value -> Value end || _ <- lists:seq(1, Increments)],  % 10 vegrandis_var:load(AtomicCounter).
{ok, AtomicCounter} = vegrandis_var:new(int_fast32), vegrandis_var:store(AtomicCounter, 123), [spawn(     fun F() ->         Value = vegrandis_var:load(AtomicCounter, memory_order_relaxed),         case vegrandis_var:compare_exchange_weak(AtomicCounter,                 Value, Value + 1, memory_order_release, memory_order_relaxed)         of             true ->                 ok;             {false, ChangedValue} ->                 F()         end     end)  || _ <- lists:seq(1, 100)],  timer:sleep(1000), vegrandis_var:load(AtomicCounter). % 223
{ok, AtomicFlag} = vegrandis_flag:new(), [spawn(     fun F() ->         case vegrandis_flag:test_and_set(AtomicFlag) of             false ->                 io:format("~p acquired spinlock~n", [self()]),                 vegrandis_flag:clear(AtomicFlag),                 io:format("~p cleared spinlock~n", [self()]);             true ->                 F()         end     end)  || _ <- lists:seq(1, 10)].
{ok, AtomicCounter} = vegrandis_var:new(long), vegrandis_var:is_lock_free(AtomicCounter) orelse exit(this_wont_do).

Building

The ERTS headers are required; if they’re not available on a global include path, ‘ERL_INCLUDE’ can be explicitly defined.

% Example path ERL_INCLUDE=/opt/kerl/17.5/usr/include rebar compile

The NIF shared object will be dumped into the priv/ directory.

Variable types

  • int8
  • uint8
  • int16
  • uint16
  • int32
  • uint32
  • int64
  • uint64
  • char
  • schar
  • uchar
  • short
  • ushort
  • int
  • uint
  • long
  • ulong
  • llong
  • ullong
  • char16
  • char32
  • wchar
  • int_least8
  • uint_least8
  • int_least16
  • uint_least16
  • int_least32
  • uint_least32
  • int_least64
  • uint_least64
  • int_fast8
  • uint_fast8
  • int_fast16
  • uint_fast16
  • int_fast32
  • uint_fast32
  • int_fast64
  • uint_fast64
  • intmax
  • uintmax

Memory orderings

  • memory_order_relaxed
  • memory_order_consume
  • memory_order_acquire
  • memory_order_release
  • memory_order_acq_rel
  • memory_order_seq_cst

TODO

  • Unit tests
  • Clean up C++ code / look for alternatives to the current template hell
  • Support named variables (in ETS fashion)

Modules

vegrandis_flag
vegrandis_var

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Vegrandis: Atomic shared variables for Erlang

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址