1 ///Collects massif data for a given command, (and parses it)
2 module commands.memory;
3 
4 import util.statman;
5 import util.owns;
6 import util.config;
7 
8 StatManager* command(inout BuildSpecification build, string[] args)
9 {
10     import std.process, std.path, std.file;
11     string fileLocation = buildPath(".benchquark", "memory", build.name);
12     auto stats = new StatManager("memory");
13     fixSubDir("memory");
14 
15     //executeShell(format!"valgrind --tool=massif --massif-out-file=%s %s"(fileLocation, build.exactCommand));
16 
17     parseMassifOutput(readText(fileLocation), stats);
18     return stats;
19 }
20 
21 
22 void parseMassifOutput(string fileContent, StatManager* stats)
23 {
24     import std.format, std.stdio;
25     struct Header {
26         string desc;
27         string cmd;
28         char time_unit;
29         //Better be in instructions, else we're fucked
30         invariant(time_unit == 'i');
31         void atomsOut(T)(auto ref T x)
32         {
33             x.setAtom("desc", desc);
34             x.setAtom("cmd", cmd);
35             x.setAtom("time_unit", time_unit);
36         }
37     }
38     string theRest;
39     Header header;
40     {
41         alias _ = header;
42         fileContent
43         .formattedRead!"desc: %s\ncmd: %s\ntime_unit: %c\n#-----------\n%s"(_.desc, _.cmd, _.time_unit, theRest);
44     }
45 
46     header.atomsOut(stats);
47 
48 
49 
50 
51     immutable snapFormat = 
52 "snapshot=%d\n#-----------\ntime=%d\nmem_heap_B=%d\nmem_heap_extra_B=%d\nmem_stacks_B=%d\nheap_tree=%s#-----------\n%s";
53     struct Snapshot {
54         ulong snapshot;
55         ulong time;
56         ulong mem_heap_B;
57         ulong mem_heap_extra_B;
58         ulong mem_stacks_B;
59         //Level of heap detail
60         string heapData;
61     }
62     ulong count = 0;
63     
64     while(theRest != "")
65     {
66         if(count)
67             writef!"\r%d Snapshots counted"(++count);
68         else
69             writef!"%d Snapshots counted"(++count);
70         Snapshot theShot;
71         alias _ = theShot;
72         try {
73             theRest.formattedRead!snapFormat(_.snapshot, _.time,
74                                          _.mem_heap_B, _.mem_heap_extra_B,
75                                          _.mem_stacks_B, _.heapData, theRest);
76         } catch(Exception e)
77         {
78             import util.inform;
79             //inform(e.msg);
80             
81             theRest = "";
82             //This is a hack until parsed properly (let it fail in lieu of checking for EOF)   
83         }
84         auto arr = stats.initArray("samples");
85         with(arr.bump)
86         {
87             setAtom("snapshot", _.snapshot);
88             setAtom("time", _.time);
89             setAtom("mem_heap_B", _.mem_heap_B);
90             setAtom("mem_heap_extra_B", _.mem_heap_extra_B);
91             setAtom("mem_stacks_B", _.mem_stacks_B);
92             category("heapData").setAtom("winkWink", "notImplementedYet");
93         }
94         
95     }
96     //Correct for the counter above
97     writeln("");
98 }