aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/doc/src/lcnt.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tools/doc/src/lcnt.xml')
-rw-r--r--lib/tools/doc/src/lcnt.xml465
1 files changed, 465 insertions, 0 deletions
diff --git a/lib/tools/doc/src/lcnt.xml b/lib/tools/doc/src/lcnt.xml
new file mode 100644
index 0000000000..3c55e4e422
--- /dev/null
+++ b/lib/tools/doc/src/lcnt.xml
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2009</year>
+ <year>2010</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ 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 online 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 AB.
+ </legalnotice>
+
+ <title>lcnt</title>
+ <prepared>Björn-Egil Dahlberg</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked></checked>
+ <date>2009-11-26</date>
+ <rev>PA1</rev>
+ <file>lcnt.xml</file>
+ </header>
+ <module>lcnt</module>
+ <modulesummary>A runtime system Lock Profiling tool.</modulesummary>
+ <description>
+ <p>The <c>lcnt</c> module is used to profile the internal ethread locks in the
+ Erlang Runtime System. With <c>lcnt</c> enabled, Internal counters in the
+ runtime 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.
+ </p>
+ <p>
+ 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.
+ </p>
+ <p>Locks in the emulator are named after what type of resource they protect 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, i.e ets-tables, processes or ports. In other cases it protects a
+ specific range of a resource, e.g. <c>pix_lock</c> which protects index to process
+ mappings, and is given a unique number within the class. A unique lock in <c>lcnt</c>
+ is referenced by a name (class) and an identifier, <c>{Name, Id}</c>.
+ </p>
+ <p>Some locks in the system are static and protects global resources, for example
+ <c>bif_timers</c> and the <c>run_queue</c> 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 separately when the locks
+ are deleted. This behavior is by default turned off to save memory but can be
+ turned on via <c>lcnt:rt_opt({copy_save, true})</c>. The <c>lcnt:apply/1,2,3</c>
+ functions enables this behavior during profiling.
+ </p>
+ </description>
+ <funcs>
+
+ <func>
+ <name>start() -> {ok, Pid} | {error, {already_started, Pid}} </name>
+ <fsummary>Starts the lock profiler server.</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Starts the lock profiler server. The server only act as a medium for the
+ user and performs filtering and printing of data collected by <c>lcnt:collect/1</c>.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>stop() -> ok</name>
+ <fsummary>Stops the lock profiler server.</fsummary>
+ <desc>
+ <p>Stops the lock profiler server.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>collect() -> ok</name>
+ <fsummary>Same as <c>collect(node())</c>.</fsummary>
+ <desc><p>Same as <c>collect(node())</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>collect(Node) -> ok</name>
+ <fsummary>Collects lock statistics from the runtime system.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>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.
+ </p>
+ <note>
+ <p>
+ When collection occurs the runtime system transitions to a single thread,
+ blocking all other threads. No other tasks will be scheduled during this
+ operation. Depending on the size of the data this might take a long time
+ (several seconds) and cause timeouts in the system.
+ </p>
+ </note>
+ </desc>
+ </func>
+
+ <func>
+ <name>clear() -> ok</name>
+ <fsummary>Same as <c>clear(node())</c>.</fsummary>
+ <desc><p>Same as <c>clear(node())</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>clear(Node) -> ok</name>
+ <fsummary>Clears the internal lock statistics from runtime system.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc>
+ <p>Clears the internal lock statistics from the runtime system. This does not clear the
+ data on the server only on runtime system. 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.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>conflicts() -> ok</name>
+ <fsummary>Same as <c>conflicts([])</c>.</fsummary>
+ <desc><p>Same as <c>conflicts([])</c>.</p></desc>
+ </func>
+ <func>
+ <name>conflicts([Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters.</fsummary>
+ <type>
+ <v>Option = {sort, Sort} | {reverse, bool()} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time | entry</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal locks and its statistics.</p>
+ <p>For option description, see <seealso marker="#inspect/2">lcnt:inspect/2</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>locations() -> ok</name>
+ <fsummary>Same as <c>locations([])</c>.</fsummary>
+ <desc>
+ <p>Same as <c>locations([])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>locations([Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters by source code locations.</fsummary>
+ <type>
+ <v>Option = {sort, Sort} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time | entry</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal lock counters by source code locations.</p>
+ <p>For option description, see <seealso marker="#inspect/2">lcnt:inspect/2</seealso>.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>inspect(Lock) -> ok</name>
+ <fsummary>Same as <c>inspect(Lock, [])</c>.</fsummary>
+ <desc><p>Same as <c>inspect(Lock, [])</c>.</p></desc>
+ </func>
+ <func>
+ <name>inspect(Lock, [Option]) -> ok</name>
+ <fsummary>Prints a list of internal lock counters for a specific lock.</fsummary>
+ <type>
+ <v>Lock = Name | {Name, Id | [Id]}</v>
+ <v>Name = atom() | pid() | port()</v>
+ <v>Id = atom() | integer() | pid() | port()</v>
+ <v>Option = {sort, Sort} | {thresholds, [Thresholds]} | {print, [Print | {Print, integer()}]} | {max_locks, MaxLocks} | {combine, bool()} | {locations, bool()}</v>
+ <v>Sort = name | id | type | tries | colls | ratio | time</v>
+ <v>Thresholds = {tries, integer()} | {colls, integer()} | {time, integer()}</v>
+ <v>Print = name | id | type | entry | tries | colls | ratio | time | duration</v>
+ <v>MaxLocks = integer() | none</v>
+ </type>
+ <desc>
+ <p>Prints a list of internal lock counters for a specific lock.</p>
+ <p>Lock <c>Name</c> and <c>Id</c> for ports and processes are interchangeable with the use of <c>lcnt:swap_pid_keys/0</c> and is the reason why <c>pid()</c> and <c>port()</c> options can be used in both <c>Name</c> and <c>Id</c> space. Both pids and ports are special identifiers with stripped creation and can be recreated with <seealso marker="#pid/3">lcnt:pid/2,3</seealso> and <seealso marker="#port/2">lcnt:port/1,2</seealso>. </p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>{combine, bool()}</c></tag>
+ <item>Combine the statistics from different instances of a lock class.
+ <br/>Default: <c>true</c>
+ </item>
+
+ <tag><c>{locations, bool()}</c></tag>
+ <item>Print the statistics by source file and line numbers.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{max_locks, MaxLocks}</c></tag>
+ <item>Maximum number of locks printed or no limit with <c>none</c>.
+ <br/>Default: <c>20</c>
+ </item>
+
+ <tag><c>{print, PrintOptions}</c></tag>
+ <item>Printing options:
+ <taglist>
+ <tag><c>name</c></tag>
+ <item>Named lock or named set of locks (classes). The same name used for initializing the lock in the VM.</item>
+
+ <tag><c>id</c></tag>
+ <item>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.</item>
+
+ <tag><c>type</c></tag>
+ <item>Type of lock: <c>rw_mutex</c>, <c>mutex</c>, <c>spinlock</c>, <c>rw_spinlock</c> or <c>proclock</c>.</item>
+
+ <tag><c>entry</c></tag>
+ <item>In combination with <c>{locations, true}</c> this option prints the lock operations source file and line number entry-points along with statistics for each entry. </item>
+
+ <tag><c>tries</c></tag>
+ <item>Number of acquisitions of this lock.</item>
+
+ <tag><c>colls</c></tag>
+ <item>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 supervises this).</item>
+
+ <tag><c>ratio</c></tag>
+ <item>The ratio between the number of collisions and the number of tries (acquisitions) in percentage.</item>
+
+ <tag><c>time</c></tag>
+ <item>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.</item>
+
+ <tag><c>duration</c></tag>
+ <item>Percentage of accumulated waiting time of wall clock time. This percentage can be higher than 100% since accumulated time is from all threads.</item>
+ </taglist>
+ <br/>Default: <c>[name,id,tries,colls,ratio,time,duration]</c>
+ </item>
+
+ <tag><c>{reverse, bool()}</c></tag>
+ <item>Reverses the order of sorting.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{sort, Sort}</c></tag>
+ <item>Column sorting orders.
+ <br/>Default: <c>time</c>
+ </item>
+
+ <tag><c>{thresholds, Thresholds}</c></tag>
+ <item>Filtering thresholds. Anything values above the threshold value are passed through.
+ <br/>Default: <c>[{tries, 0}, {colls, 0}, {time, 0}]</c>
+ </item>
+
+ </taglist>
+
+ </desc>
+ </func>
+
+ <func>
+ <name>information() -> ok</name>
+ <fsummary>Prints lcnt server state and generic information about collected lock statistics.</fsummary>
+ <desc>
+ <p>Prints lcnt server state and generic information about collected lock statistics.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>swap_pid_keys() -> ok</name>
+ <fsummary>Swaps places on <c>Name</c> and <c>Id</c> space for ports and processes.</fsummary>
+ <desc>
+ <p>Swaps places on <c>Name</c> and <c>Id</c> space for ports and processes.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>load(Filename) -> ok</name>
+ <fsummary>Restores previously saved data to the server.</fsummary>
+ <type>
+ <v>Filename = filename()</v>
+ </type>
+ <desc>
+ <p>Restores previously saved data to the server.</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>save(Filename) -> ok</name>
+ <fsummary>Saves the collected data to file.</fsummary>
+ <type>
+ <v>Filename = filename()</v>
+ </type>
+ <desc>
+ <p>Saves the collected data to file.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Convenience functions</title>
+ <p>The following functions are used for convenience.</p>
+ </section>
+ <funcs>
+ <func>
+ <name>apply(Fun) -> term()</name>
+ <fsummary>Same as <c>apply(Fun, [])</c>.</fsummary>
+ <desc>
+ <p>Same as <c>apply(Fun, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Fun, Args) -> term()</name>
+ <fsummary>Clears counters, applies function and collects the profiling results.</fsummary>
+ <type>
+ <v>Fun = fun()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p> Clears the lock counters and then setups the instrumentation to save all destroyed locks.
+ After setup the fun is called, passing the elements in <c>Args</c> as arguments.
+ When the fun returns the statistics are immediately collected to the server. After the
+ collection the instrumentation is returned to its previous behavior.
+ The result of the applied fun is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Module, Function, Args) -> term()</name>
+ <fsummary>Clears counters, applies function and collects the profiling results.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p> Clears the lock counters and then setups the instrumentation to save all destroyed locks.
+ After setup the function is called, passing the elements in <c>Args</c> as arguments.
+ When the function returns the statistics are immediately collected to the server. After the
+ collection the instrumentation is returned to its previous behavior.
+ The result of the applied function is returned.
+ </p>
+ </desc>
+ </func>
+
+ <func>
+ <name>pid(Id, Serial) -> pid()</name>
+ <fsummary>Same as <c>pid(node(), Id, Serial)</c>.</fsummary>
+ <desc><p>Same as <c>pid(node(), Id, Serial)</c>.</p></desc>
+ </func>
+ <func>
+ <name>pid(Node, Id, Serial) -> pid()</name>
+ <fsummary>Creates a process id with creation 0.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Id = integer()</v>
+ <v>Serial = integer()</v>
+ </type>
+ <desc>
+ <p>Creates a process id with creation 0. Example:</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>port(Id) -> port()</name>
+ <fsummary>Same as <c>port(node(), Id)</c>.</fsummary>
+ <desc><p>Same as <c>port(node(), Id)</c>.</p></desc>
+ </func>
+ <func>
+ <name>port(Node, Id) -> port()</name>
+ <fsummary>Creates a port id with creation 0.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Id = integer()</v>
+ </type>
+ <desc><p>Creates a port id with creation 0.</p></desc>
+ </func>
+
+ </funcs>
+
+ <section>
+ <title>Internal runtime lock counter controllers</title>
+ <p> The following functions control the behavior of the internal counters. </p>
+ </section>
+
+ <funcs>
+ <func>
+ <name>rt_collect() -> [lock_counter_data()]</name>
+ <fsummary>Same as <c>rt_collect(node())</c>.</fsummary>
+ <desc> <p>Same as <c>rt_collect(node())</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_collect(Node) -> [lock_counter_data()]</name>
+ <fsummary>Returns a list of raw lock counter data.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc> <p>Returns a list of raw lock counter data.</p> </desc>
+ </func>
+
+ <func>
+ <name>rt_clear() -> ok</name>
+ <fsummary>Same as <c>rt_clear(node())</c>.</fsummary>
+ <desc> <p>Same as <c>rt_clear(node())</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_clear(Node) -> ok</name>
+ <fsummary>Clears the internal counters.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ </type>
+ <desc> <p>Clear the internal counters. Same as <c>lcnt:clear(Node)</c>.</p></desc>
+ </func>
+
+ <func>
+ <name>rt_opt({Type, bool()}) -> bool()</name>
+ <fsummary>Same as <c>rt_opt(node(), {Type, Opt})</c>.</fsummary>
+ <desc> <p>Same as <c>rt_opt(node(), {Type, Opt})</c>.</p> </desc>
+ </func>
+ <func>
+ <name>rt_opt(Node, {Type, bool()}) -> bool()</name>
+ <fsummary>Changes the lock counter behavior and returns the previous behaviour.</fsummary>
+ <type>
+ <v>Node = node()</v>
+ <v>Type = copy_save | process_locks</v>
+ </type>
+ <desc>
+ <p>Changes the lock counter behavior and returns the previous behaviour.</p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>{copy_save, bool()}</c></tag>
+ <item>Enable statistics saving from destroyed locks by copying. This might consume a lot of memory.
+ <br/>Default: <c>false</c>
+ </item>
+
+ <tag><c>{process_locks, bool()}</c></tag>
+ <item>Profile process locks.
+ <br/>Default: <c>true</c>
+ </item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p> <seealso marker="lcnt_chapter">LCNT User's Guide</seealso></p>
+ </section>
+</erlref>