e690c74cdaaa4a05e3e80d37d142927004b6bbd2
[gcc.git] / gcc / ada / s-stusta.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- S Y S T E M . S T A C K _ U S A G E . T A S K I N G --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2009-2010, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNARL was developed by the GNARL team at Florida State University. --
28 -- Extensive contributions were provided by Ada Core Technologies, Inc. --
29 -- --
30 ------------------------------------------------------------------------------
31
32 with System.Stack_Usage;
33
34 -- This is why this package is part of GNARL:
35
36 with System.Tasking.Debug;
37 with System.Task_Primitives.Operations;
38
39 with System.IO;
40
41 package body System.Stack_Usage.Tasking is
42 use System.IO;
43
44 procedure Report_For_Task (Id : System.Tasking.Task_Id);
45 -- A generic procedure calculating stack usage for a given task
46
47 procedure Compute_All_Tasks;
48 -- Compute the stack usage for all tasks and saves it in
49 -- System.Stack_Usage.Result_Array
50
51 procedure Compute_Current_Task;
52 -- Compute the stack usage for a given task and saves it in the precise
53 -- slot in System.Stack_Usage.Result_Array;
54
55 procedure Report_Impl (All_Tasks : Boolean; Do_Print : Boolean);
56 -- Report the stack usage of either all tasks (All_Tasks = True) or of the
57 -- current task (All_Task = False). If Print is True, then results are
58 -- printed on stderr
59
60 procedure Convert
61 (TS : System.Stack_Usage.Task_Result;
62 Res : out Stack_Usage_Result);
63 -- Convert an object of type System.Stack_Usage in a Stack_Usage_Result
64
65 -------------
66 -- Convert --
67 -------------
68
69 procedure Convert
70 (TS : System.Stack_Usage.Task_Result;
71 Res : out Stack_Usage_Result) is
72 begin
73 Res := TS;
74 end Convert;
75
76 ---------------------
77 -- Report_For_Task --
78 ---------------------
79
80 procedure Report_For_Task (Id : System.Tasking.Task_Id) is
81 begin
82 System.Stack_Usage.Compute_Result (Id.Common.Analyzer);
83 System.Stack_Usage.Report_Result (Id.Common.Analyzer);
84 end Report_For_Task;
85
86 -----------------------
87 -- Compute_All_Tasks --
88 -----------------------
89
90 procedure Compute_All_Tasks is
91 Id : System.Tasking.Task_Id;
92 use type System.Tasking.Task_Id;
93 begin
94 if not System.Stack_Usage.Is_Enabled then
95 Put ("Stack Usage not enabled: bind with -uNNN switch");
96 else
97
98 -- Loop over all tasks
99
100 for J in System.Tasking.Debug.Known_Tasks'First + 1
101 .. System.Tasking.Debug.Known_Tasks'Last
102 loop
103 Id := System.Tasking.Debug.Known_Tasks (J);
104 exit when Id = null;
105
106 -- Calculate the task usage for a given task
107
108 Report_For_Task (Id);
109 end loop;
110
111 end if;
112 end Compute_All_Tasks;
113
114 --------------------------
115 -- Compute_Current_Task --
116 --------------------------
117
118 procedure Compute_Current_Task is
119 begin
120 if not System.Stack_Usage.Is_Enabled then
121 Put ("Stack Usage not enabled: bind with -uNNN switch");
122 else
123
124 -- The current task
125
126 Report_For_Task (System.Tasking.Self);
127
128 end if;
129 end Compute_Current_Task;
130
131 -----------------
132 -- Report_Impl --
133 -----------------
134
135 procedure Report_Impl (All_Tasks : Boolean; Do_Print : Boolean) is
136 begin
137
138 -- Lock the runtime
139
140 System.Task_Primitives.Operations.Lock_RTS;
141
142 -- Calculate results
143
144 if All_Tasks then
145 Compute_All_Tasks;
146 else
147 Compute_Current_Task;
148 end if;
149
150 -- Output results
151 if Do_Print then
152 System.Stack_Usage.Output_Results;
153 end if;
154
155 -- Unlock the runtime
156
157 System.Task_Primitives.Operations.Unlock_RTS;
158
159 end Report_Impl;
160
161 ---------------------
162 -- Report_All_Task --
163 ---------------------
164
165 procedure Report_All_Tasks is
166 begin
167 Report_Impl (True, True);
168 end Report_All_Tasks;
169
170 -------------------------
171 -- Report_Current_Task --
172 -------------------------
173
174 procedure Report_Current_Task is
175 Res : Stack_Usage_Result;
176 begin
177 Res := Get_Current_Task_Usage;
178 Print (Res);
179 end Report_Current_Task;
180
181 -------------------------
182 -- Get_All_Tasks_Usage --
183 -------------------------
184
185 function Get_All_Tasks_Usage return Stack_Usage_Result_Array is
186 Res : Stack_Usage_Result_Array
187 (1 .. System.Stack_Usage.Result_Array'Length);
188 begin
189 Report_Impl (True, False);
190
191 for J in Res'Range loop
192 Convert (System.Stack_Usage.Result_Array (J), Res (J));
193 end loop;
194
195 return Res;
196 end Get_All_Tasks_Usage;
197
198 ----------------------------
199 -- Get_Current_Task_Usage --
200 ----------------------------
201
202 function Get_Current_Task_Usage return Stack_Usage_Result is
203 Res : Stack_Usage_Result;
204 Original : System.Stack_Usage.Task_Result;
205 Found : Boolean := False;
206 begin
207
208 Report_Impl (False, False);
209
210 -- Look for the task info in System.Stack_Usage.Result_Array;
211 -- the search is based on task name
212
213 for T in System.Stack_Usage.Result_Array'Range loop
214 if System.Stack_Usage.Result_Array (T).Task_Name =
215 System.Tasking.Self.Common.Analyzer.Task_Name
216 then
217 Original := System.Stack_Usage.Result_Array (T);
218 Found := True;
219 exit;
220 end if;
221 end loop;
222
223 -- Be sure a task has been found
224
225 pragma Assert (Found);
226
227 Convert (Original, Res);
228 return Res;
229 end Get_Current_Task_Usage;
230
231 -----------
232 -- Print --
233 -----------
234
235 procedure Print (Obj : Stack_Usage_Result) is
236 Pos : Positive := Obj.Task_Name'Last;
237 begin
238
239 -- Simply trim the string containing the task name
240
241 for S in Obj.Task_Name'Range loop
242 if Obj.Task_Name (S) = ' ' then
243 Pos := S;
244 exit;
245 end if;
246 end loop;
247
248 declare
249 T_Name : constant String := Obj.Task_Name
250 (Obj.Task_Name'First .. Pos);
251 begin
252 Put_Line
253 ("| " & T_Name & " | " & Natural'Image (Obj.Max_Size) &
254 Natural'Image (Obj.Value) & " +/- " &
255 Natural'Image (Obj.Variation));
256 end;
257 end Print;
258
259 end System.Stack_Usage.Tasking;