g-andrade / nlocks

Native spinlocks for Erlang
MIT License
4 stars 1 forks source link
erlang ownership-objects spinlock

nlocks

Copyright (c) 2016 Guilherme Andrade

Version: 1.1.2

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

nlocks: Native spinlocks for Erlang


An experiment on Erlang native spinlocks:


Lock = nlocks:new(),
Transaction = fun() ->
    io:format("hello from ~p at ~p~n", [self(), os:timestamp()]),
    timer:sleep(100)
end,

[spawn(fun () -> nlocks:transaction(Lock, Transaction) end) || _ <- lists:seq(1, 4)].
% hello from <0.66.0> at {1465,509871,454813}
% hello from <0.69.0> at {1465,509871,555028}
% hello from <0.67.0> at {1465,509871,656021}
% hello from <0.68.0> at {1465,509871,757031}

Brutal kills and unreleased locks

Hackish solution. Other than setting up some sort of monitor in the Erlang land, I found no practical way to deal with these other than making use of ownership objects, references to which should never leave the process under which they were created; the release therefore becomes dependent on the garbage collector calling their destructor, but this also makes it more convenient for regularly terminated processes that forget to clean up.

Ownership objects


struct Ownership {
    ERL_NIF_TERM pid;
    Lock** lockResource;
};

Lock objects


struct Lock {
    std::atomic<Ownership*> ownership;
};

The spinning

Internal metrics


% nlocks:info()
[{allocated_locks,2},
 {allocated_ownerships,6},
 {acquired_locks,1},
 {contention,5}, % amount of processes attempting lock acquisition
 {has_lockfree_counters,true},
 {has_lockfree_ownership,true}]

Modules

nlocks