From 876ecc058d0d7dd48f8c5f7ddaf189d278e69925 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Thu, 29 Jun 2017 19:32:41 +0200
Subject: Document rt_mask and add warnings about copy_save

---
 lib/tools/doc/src/lcnt.xml         | 98 +++++++++++++++++++++++++++++++++-----
 lib/tools/doc/src/lcnt_chapter.xml | 11 +++--
 2 files changed, 94 insertions(+), 15 deletions(-)

diff --git a/lib/tools/doc/src/lcnt.xml b/lib/tools/doc/src/lcnt.xml
index 590049e681..922c2ac0f4 100644
--- a/lib/tools/doc/src/lcnt.xml
+++ b/lib/tools/doc/src/lcnt.xml
@@ -5,7 +5,7 @@
     <header>
 	<copyright>
 	    <year>2009</year>
-	    <year>2016</year>
+	    <year>2017</year>
 	    <holder>Ericsson AB, All Rights Reserved</holder>
 	</copyright>
 	<legalnotice>
@@ -314,24 +314,22 @@
 	<func>
 	    <name>apply(Fun) -> term()</name>
 	    <fsummary>Same as <c>apply(Fun, [])</c>.</fsummary>
+	    <type>
+		<v>Fun = fun()</v>
+	    </type>
 	    <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>
+	    <fsummary>Same as <c>apply(Module, Function, Args)</c>.</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>
+		<p>Same as <c>apply(Module, Function, Args)</c>.</p>
 	    </desc>
 	</func>
 	<func>
@@ -349,6 +347,13 @@
 		    collection the instrumentation is returned to its previous behavior.
 		    The result of the applied function is returned.
 		</p>
+                <warning>
+                    <p>
+                        This function should only be used for micro-benchmarks; it sets <c>copy_save</c>
+                        to <c>true</c> for the duration of the call, which can quickly lead to running
+                        out of memory.
+                    </p>
+                </warning>
 	    </desc>
 	</func>
 
@@ -421,6 +426,68 @@
 	    <desc> <p>Clear the internal counters. Same as <c>lcnt:clear(Node)</c>.</p></desc>
 	</func>
 
+        <func>
+            <name>rt_mask() -> [category_atom()]</name>
+            <fsummary>Same as <c>rt_mask(node())</c>.</fsummary>
+            <desc><p>Same as <c>rt_mask(node())</c>.</p></desc>
+        </func>
+
+        <func>
+            <name>rt_mask(Node) -> [category_atom()]</name>
+            <fsummary>Returns the current lock category mask.</fsummary>
+            <type>
+                <v>Node = node()</v>
+            </type>
+            <desc>
+                <p>
+                    Refer to <c>rt_mask/2</c> for a list of valid categories. All
+                    categories are enabled by default.
+                </p>
+            </desc>
+        </func>
+
+        <func>
+            <name>rt_mask(Categories) -> ok | {error, copy_save_enabled}</name>
+            <fsummary>Same as <c>rt_mask(node(), Categories)</c>.</fsummary>
+            <type>
+                <v>Categories = [atom()]</v>
+            </type>
+            <desc><p>Same as <c>rt_mask(node(), Categories)</c>.</p></desc>
+        </func>
+
+        <func>
+            <name>rt_mask(Node, Categories) -> ok | {error, copy_save_enabled}</name>
+            <fsummary>Changes the lock category mask.</fsummary>
+            <type>
+                <v>Node = node()</v>
+                <v>Categories = [atom()]</v>
+            </type>
+            <desc>
+                <p>
+                    Sets the lock category mask to the given categories.
+                </p>
+                <p>
+                    This will fail if the <c>copy_save</c> option is enabled; see
+                    <c>lcnt:rt_opt/2</c>.
+                </p>
+                <p>Valid categories are:</p>
+                <taglist>
+                    <item><c>allocator</c></item>
+                    <item><c>db</c> (ETS tables)</item>
+                    <item><c>debug</c></item>
+                    <item><c>distribution</c></item>
+                    <item><c>generic</c></item>
+                    <item><c>io</c></item>
+                    <item><c>process</c></item>
+                    <item><c>scheduler</c></item>
+                </taglist>
+                <p>
+                    This list is subject to change at any time, as is the category any given lock
+                    may belong to.
+                </p>
+            </desc>
+        </func>
+
 	<func>
 	    <name>rt_opt({Type, bool()}) -> bool()</name>
 	    <fsummary>Same as <c>rt_opt(node(), {Type, Opt})</c>.</fsummary>
@@ -434,16 +501,25 @@
 		<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.
+		    <item>Retains the statistics of destroyed locks.
 			<br/>Default: <c>false</c>
+                        <warning>
+                            <p>
+                                This option will use a lot of memory when enabled, which must be
+                                reclaimed with <c>lcnt:rt_clear</c>. Note that it makes no distinction
+                                between locks that were destroyed and locks for which counting was
+                                disabled, so enabling this option will disable changes to the lock
+                                category mask.
+                            </p>
+                        </warning>
 		    </item>
 
 		    <tag><c>{process_locks, bool()}</c></tag>
-		    <item>Profile process locks.
+		    <item>Profile process locks, equal to adding <c>process</c> to the lock category mask;
+            see <c>lcnt:rt_mask/2</c>
 			<br/>Default: <c>true</c>
 		    </item>
 		</taglist>
diff --git a/lib/tools/doc/src/lcnt_chapter.xml b/lib/tools/doc/src/lcnt_chapter.xml
index 1981d66117..24b58136aa 100644
--- a/lib/tools/doc/src/lcnt_chapter.xml
+++ b/lib/tools/doc/src/lcnt_chapter.xml
@@ -4,7 +4,7 @@
 <chapter>
     <header>
 	<copyright>
-	    <year>2009</year><year>2016</year>
+	    <year>2009</year><year>2017</year>
 	    <holder>Ericsson AB. All Rights Reserved.</holder>
 	</copyright>
 	<legalnotice>
@@ -29,7 +29,7 @@
 	<approved>nobody</approved>
 	<checked>no</checked>
 	<date>2009-11-26</date>
-	<rev>PA1</rev>
+	<rev>PA2</rev>
 	<file>lcnt_chapter.xml</file>
     </header>
     <p>
@@ -97,8 +97,11 @@ ok
 ok
 </pre>
 <p>
-    Another way to to profile a specific function is to use <c>lcnt:apply/3</c> or <c>lcnt:apply/1</c> which does <c>lcnt:clear/0</c> before the function and <c>lcnt:collect/0</c> after its invocation.
-    It also sets <c>copy_save</c> to <c>true</c> for the duration of the function call
+    Another way to to profile a specific function is to use <c>lcnt:apply/3</c> or <c>lcnt:apply/1</c>
+    which does <c>lcnt:clear/0</c> before the function and <c>lcnt:collect/0</c> after its invocation.
+    This method should only be used in micro-benchmarks since it sets <c>copy_save</c> to <c>true</c>
+    for the duration of the function call, which may cause the emulator to run out of memory if
+    attempted under load.
 </p>
 <pre>
 Erlang R13B03 (erts-5.7.4) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe]
-- 
cgit v1.2.3