lcnt(3)



lcnt(3erl)                 Erlang Module Definition                 lcnt(3erl)

NAME
       lcnt - A runtime system Lock Profiling tool.

DESCRIPTION
       The  lcnt  module  is used to profile the internal ethread locks in the
       Erlang Runtime System. With lcnt enabled, internal counters in the run-
       time  system are updated each time a lock is taken. The counters stores
       information about the number of acquisition tries  and  the  number  of
       collisions that has occurred during the acquisition tries. The counters
       also record the waiting time a lock has caused  for  a  blocked  thread
       when a collision has occurred.

       The  data  produced  by  the lock counters will give an estimate on how
       well the runtime system will behave from a  parallelizable  view  point
       for the scenarios tested. This tool was mainly developed to help Erlang
       runtime developers iron out potential and generic bottlenecks.

       Locks in the emulator are named after what type of resource  they  pro-
       tect  and  where  in  the emulator they are initialized, those are lock
       'classes'. Most of those locks are also instantiated several times, and
       given unique identifiers, to increase locking granularity. Typically an
       instantiated lock protects a disjunct set of the resource, for  example
       ets  tables,  processes or ports. In other cases it protects a specific
       range of a resource, for  example  pix_lock  which  protects  index  to
       process  mappings,  and  is  given  a unique number within the class. A
       unique lock in lcnt is referenced by a name (class) and an  identifier:
       {Name, Id}.

       Some  locks in the system are static and protects global resources, for
       example bif_timers and the run_queue locks. Other locks are dynamic and
       not  necessarily  long  lived,  for example process locks and ets-table
       locks. The statistics data from short lived locks can be  stored  sepa-
       rately  when  the locks are deleted. This behavior is by default turned
       off to save memory but can be  turned  on  via  lcnt:rt_opt({copy_save,
       true}).  The  lcnt:apply/1,2,3  functions  enables this behavior during
       profiling.

EXPORTS
       start() -> {ok, Pid} | {error, {already_started, Pid}}

              Types:

                 Pid = pid()

              Starts the lock profiler server. The server only act as a medium
              for  the  user  and performs filtering and printing of data col-
              lected by lcnt:collect/1.

       stop() -> ok

              Stops the lock profiler server.

       collect() -> ok

              Same as collect(node()).

       collect(Node) -> ok

              Types:

                 Node = node()

              Collects lock statistics from the runtime system.  The  function
              starts  a server if it is not already started. It then populates
              the server with lock statistics. If the  server  held  any  lock
              statistics data before the collect then that data is lost.

       clear() -> ok

              Same as clear(node()).

       clear(Node) -> ok

              Types:

                 Node = node()

              Clears  the  internal  lock  statistics from the runtime system.
              This does not clear the data on the server only on runtime  sys-
              tem. All counters for static locks are zeroed, all dynamic locks
              currently alive are zeroed and all saved locks now destroyed are
              removed. It also resets the duration timer.

       conflicts() -> ok

              Same as conflicts([]).

       conflicts([Option]) -> ok

              Types:

                 Option  =  {sort,  Sort}  |  {reverse, bool()} | {thresholds,
                 [Thresholds]} |  {print,  [Print  |  {Print,  integer()}]}  |
                 {max_locks, MaxLocks} | {combine, bool()}
                 Sort  = name | id | type | tries | colls | ratio | time | en-
                 try
                 Thresholds = {tries, integer()} | {colls, integer()} | {time,
                 integer()}
                 Print  =  name  | id | type | entry | tries | colls | ratio |
                 time | duration
                 MaxLocks = integer() | none

              Prints a list of internal locks and its statistics.

              For option description, see lcnt:inspect/2.

       locations() -> ok

              Same as locations([]).

       locations([Option]) -> ok

              Types:

                 Option = {sort, Sort} | {thresholds, [Thresholds]} |  {print,
                 [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {com-
                 bine, bool()}
                 Sort = name | id | type | tries | colls | ratio | time |  en-
                 try
                 Thresholds = {tries, integer()} | {colls, integer()} | {time,
                 integer()}
                 Print = name | id | type | entry | tries | colls  |  ratio  |
                 time | duration
                 MaxLocks = integer() | none

              Prints  a  list  of  internal lock counters by source code loca-
              tions.

              For option description, see lcnt:inspect/2.

       inspect(Lock) -> ok

              Same as inspect(Lock, []).

       inspect(Lock, [Option]) -> ok

              Types:

                 Lock = Name | {Name, Id | [Id]}
                 Name = atom() | pid() | port()
                 Id = atom() | integer() | pid() | port()
                 Option = {sort, Sort} | {thresholds, [Thresholds]} |  {print,
                 [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {com-
                 bine, bool()} | {locations, bool()}
                 Sort = name | id | type | tries | colls | ratio | time
                 Thresholds = {tries, integer()} | {colls, integer()} | {time,
                 integer()}
                 Print  =  name  | id | type | entry | tries | colls | ratio |
                 time | duration
                 MaxLocks = integer() | none

              Prints a list of internal lock counters for a specific lock.

              Lock Name and Id for ports  and  processes  are  interchangeable
              with the use of lcnt:swap_pid_keys/0 and is the reason why pid()
              and port() options can be used in both Name and Id  space.  Both
              pids  and  ports  are special identifiers with stripped creation
              and can be recreated with lcnt:pid/2,3 and lcnt:port/1,2.

              Option description:

                {combine, bool()}:
                  Combine the statistics from different instances  of  a  lock
                  class.
                  Default: true

                {locations, bool()}:
                  Print the statistics by source file and line numbers.
                  Default: false

                {max_locks, MaxLocks}:
                  Maximum number of locks printed or no limit with none.
                  Default: 20

                {print, PrintOptions}:
                  Printing options:

                  name:
                    Named  lock or named set of locks (classes). The same name
                    used for initializing the lock in the VM.

                  id:
                    Internal id for set of  locks,  not  always  unique.  This
                    could  be  table name for ets tables (db_tab), port id for
                    ports, integer identifiers for allocators, etc.

                  type:
                    Type of lock: rw_mutex, mutex,  spinlock,  rw_spinlock  or
                    proclock.

                  entry:
                    In  combination  with {locations, true} this option prints
                    the lock operations source file  and  line  number  entry-
                    points along with statistics for each entry.

                  tries:
                    Number of acquisitions of this lock.

                  colls:
                    Number  of  collisions when a thread tried to acquire this
                    lock. This is when a trylock is EBUSY, a write try on read
                    held  rw_lock,  a try read on write held rw_lock, a thread
                    tries to lock an already locked lock. (Internal states su-
                    pervises this).

                  ratio:
                    The  ratio between the number of collisions and the number
                    of tries (acquisitions) in percentage.

                  time:
                    Accumulated waiting time for  this  lock.  This  could  be
                    greater than actual wall clock time, it is accumulated for
                    all threads. Trylock conflicts does not accumulate time.

                  duration:
                    Percentage of accumulated waiting time of wall clock time.
                    This  percentage can be higher than 100% since accumulated
                    time is from all threads.
                Default: [name,id,tries,colls,ratio,time,duration]

                {reverse, bool()}:
                  Reverses the order of sorting.
                  Default: false

                {sort, Sort}:
                  Column sorting orders.
                  Default: time

                {thresholds, Thresholds}:
                  Filtering thresholds. Anything values  above  the  threshold
                  value are passed through.
                  Default: [{tries, 0}, {colls, 0}, {time, 0}]

       information() -> ok

              Prints lcnt server state and generic information about collected
              lock statistics.

       swap_pid_keys() -> ok

              Swaps places on Name and Id space for ports and processes.

       load(Filename) -> ok

              Types:

                 Filename = filename()

              Restores previously saved data to the server.

       save(Filename) -> ok

              Types:

                 Filename = filename()

              Saves the collected data to file.

CONVENIENCE FUNCTIONS
       The following functions are used for convenience.

EXPORTS
       apply(Fun) -> term()

              Types:

                 Fun = fun()

              Same as apply(Fun, []).

       apply(Fun, Args) -> term()

              Types:

                 Fun = fun()
                 Args = [term()]

              Same as apply(Module, Function, Args).

       apply(Module, Function, Args) -> term()

              Types:

                 Module = atom()
                 Function = atom()
                 Args = [term()]

              Clears the lock counters and then setups the instrumentation  to
              save  all  destroyed  locks. After setup the function is called,
              passing the elements in Args as arguments. When the function re-
              turns  the  statistics  are immediately collected to the server.
              After the collection the instrumentation is returned to its pre-
              vious behavior. The result of the applied function is returned.

          Warning:
              This  function should only be used for micro-benchmarks; it sets
              copy_save to true for  the  duration  of  the  call,  which  can
              quickly lead to running out of memory.

       pid(Id, Serial) -> pid()

              Same as pid(node(), Id, Serial).

       pid(Node, Id, Serial) -> pid()

              Types:

                 Node = node()
                 Id = integer()
                 Serial = integer()

              Creates a process id with creation 0.

       port(Id) -> port()

              Same as port(node(), Id).

       port(Node, Id) -> port()

              Types:

                 Node = node()
                 Id = integer()

              Creates a port id with creation 0.

INTERNAL RUNTIME LOCK COUNTER CONTROLLERS
       The following functions control the behavior of the internal counters.

EXPORTS
       rt_collect() -> [lock_counter_data()]

              Same as rt_collect(node()).

       rt_collect(Node) -> [lock_counter_data()]

              Types:

                 Node = node()

              Returns a list of raw lock counter data.

       rt_clear() -> ok

              Same as rt_clear(node()).

       rt_clear(Node) -> ok

              Types:

                 Node = node()

              Clear the internal counters. Same as lcnt:clear(Node).

       rt_mask() -> [category_atom()]

              Same as rt_mask(node()).

       rt_mask(Node) -> [category_atom()]

              Types:

                 Node = node()

              Refer  to  rt_mask/2  for  a list of valid categories. All cate-
              gories are enabled by default.

       rt_mask(Categories) -> ok | {error, copy_save_enabled}

              Types:

                 Categories = [atom()]

              Same as rt_mask(node(), Categories).

       rt_mask(Node, Categories) -> ok | {error, copy_save_enabled}

              Types:

                 Node = node()
                 Categories = [atom()]

              Sets the lock category mask to the given categories.

              This  will  fail  if  the  copy_save  option  is  enabled;   see
              lcnt:rt_opt/2.

              Valid categories are:

                * allocator

                * db (ETS tables)

                * debug

                * distribution

                * generic

                * io

                * process

                * scheduler

              This  list  is subject to change at any time, as is the category
              any given lock may belong to.

       rt_opt({Type, bool()}) -> bool()

              Same as rt_opt(node(), {Type, Opt}).

       rt_opt(Node, {Type, bool()}) -> bool()

              Types:

                 Node = node()
                 Type = copy_save | process_locks

              Option description:

                {copy_save, bool()}:
                  Retains the statistics of destroyed locks.
                  Default: false

            Warning:
                This option will use a lot of memory when enabled, which  must
                be  reclaimed  with  lcnt:rt_clear. Note that it makes no dis-
                tinction between locks that were destroyed and locks for which
                counting  was  disabled,  so enabling this option will disable
                changes to the lock category mask.

                {process_locks, bool()}:
                  Profile process locks, equal to adding process to  the  lock
                  category mask; see lcnt:rt_mask/2
                  Default: true

SEE ALSO
       LCNT User's Guide

Ericsson AB                        tools 3.4                        lcnt(3erl)

Man(1) output converted with man2html
list of all man pages