Skip to content

Commit ade2d35

Browse files
committed
binary: add linux perf chapter
1 parent 0ec03a7 commit ade2d35

File tree

9 files changed

+1098
-63
lines changed

9 files changed

+1098
-63
lines changed

code/lethargy/app/Main.hs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -ddump-asm #-}
12
module Main where
23

34
main :: IO ()

code/lethargy/lethargy.cabal

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ executable lethargy
2525
hs-source-dirs: app
2626
default-language: Haskell2010
2727

28+
executable lethargy-asm
29+
import: warnings
30+
main-is: Main.hs
31+
build-depends: base >=4.15.1.0
32+
hs-source-dirs: app
33+
default-language: Haskell2010
34+
ghc-options: -ddump-asm
35+
2836

2937
benchmark inlining
3038
type : exitcode-stdio-1.0

conf.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,25 @@
5454
]
5555

5656
# flags
57-
todo_include_todos = False
57+
todo_include_todos = True
5858
todo_link_only = False
5959
autosectionlabel_prefix_document = True
6060

6161
# tikz support
6262
tikz_proc_suite = "pdf2svg"
63-
tikz_tikzlibraries = "arrows, arrows.meta"
63+
tikz_tikzlibraries = "arrows, arrows.meta, decorations.pathreplacing"
64+
tikz_latex_preamble = r"""
65+
\newcommand{\MemoryLayout}[1]{
66+
\draw[thick](0,0)--++(0,3)node[above]{$0$};
67+
\foreach \pt/\col/\lab [remember=\pt as \lastpt (initially 0)] in {#1} {
68+
\draw[fill=\col]({\lastpt},0) rectangle ++(\pt,2);
69+
\if\lab\relax\relax\else
70+
\draw[thick,decorate, decoration={brace,amplitude=4mm}]
71+
(\pt,-0.4)--node[below=4mm]{\lab} (\lastpt,-0.4);
72+
\fi
73+
}
74+
}
75+
"""
6476

6577
## global links in the book that share a prefix that we've named.
6678
extlinks = {'userGuide': ('https://downloads.haskell.org/~ghc/9.2.4/docs/html/users_guide/%s', '%s'),

extensions/sphinx_exec_directive.py

+24-11
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def execute_code_with_pipe(command, code_in, post_process=[]):
4747
out = f(out)
4848

4949
# Log any stderr.
50-
if err is not None and err.strip() != "":
50+
if err is not None and len(err.strip()) > 0:
5151
print(err)
5252

5353
return out
@@ -71,6 +71,8 @@ def execute_code_with_pipe(command, code_in, post_process=[]):
7171
runner['with'] = 'runghc' # default is runghc, no hooks
7272

7373
if runner['with'] == 'ghci':
74+
# TODO: properly add in an args argument to execute_code_with_pipe
75+
runner['with'] = 'ghci -ignore-dot-ghci'.split()
7476
# if running with ghci then we post process the output to remove
7577
# ghci specific text
7678
post_process += [lambda s: s.replace("ghci>",""),
@@ -87,18 +89,26 @@ def execute_code_with_pipe(command, code_in, post_process=[]):
8789
out = comp_proc.stdout
8890
err = comp_proc.stderr
8991
code_out = out
90-
found = False
9192

93+
## control the output
9294
out_stream = code_out.splitlines()
95+
linking_index = 0
9396
for index, line in enumerate(out_stream):
9497
if "Linking" in line:
95-
i = index + 1
96-
code_out = '\n'.join(out_stream[i:])
97-
break # only want first hit, and we are guarenteed
98-
# that linking is in the list because you
99-
# cannot run a binary without linking! Log
100-
101-
if err is not None and err.strip() != "":
98+
linking_index = index
99+
break
100+
if runner['output'] == 'all':
101+
## then we want the whole of stdout including the program
102+
code_out = '\n'.join(out_stream)
103+
elif runner['output'] == 'comp':
104+
## then we only want ghc's output and not the program
105+
code_out = '\n'.join(out_stream[:linking_index])
106+
else:
107+
## the default case, we only want the program output
108+
code_out = '\n'.join(out_stream[linking_index:])
109+
110+
# Log
111+
if err is not None and len(err.strip()) > 0:
102112
print(err) # should use sphinx logger
103113

104114
else:
@@ -120,7 +130,7 @@ def execute_code_with_pipe(command, code_in, post_process=[]):
120130
out = comp_proc.stdout.decode('utf-8')
121131
err = comp_proc.stderr
122132
# Log any stderr.
123-
if err is not None and err.strip() != "":
133+
if err is not None and len(err.strip()) > 0:
124134
print(err)
125135
code_out = out
126136

@@ -164,6 +174,7 @@ class Exec(Directive):
164174
'context': _option_boolean,
165175
'cache': _option_boolean,
166176
'process': _option_process,
177+
'output': _option_str,
167178
'intertext': _option_str,
168179
'project_dir': _option_str,
169180
'with': _option_str,
@@ -192,6 +203,7 @@ def run(self):
192203
project_dir = self.options.get('project_dir', '')
193204
opt_with = self.options.get('with', '')
194205
args = self.options.get ('args','').split()
206+
output = self.options.get ('output','')
195207

196208
# A runner is "that which runs the code", i.e., a dictionary that
197209
# defines the entire external process
@@ -204,7 +216,8 @@ def run(self):
204216
# the contents of source_file,
205217
# if not then its the contents
206218
# of a literal code block
207-
'args': args} # args to run with, with
219+
'args': args, # args to run with, with
220+
'output': output} # how much output to display
208221

209222
# Determine whether input is to be read from a file, or directly from
210223
# the exec block's contents.

hoh.nix

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ pkgs.stdenv.mkDerivation {
3434

3535
preBuild = ''
3636
unset SOURCE_DATE_EPOCH
37-
'';
37+
export CABAL_DIR=$(mktemp -d)
38+
cabal user-config update
39+
'';
3840

3941
buildPhase = ''
4042
runHook preBuild
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.. _Reading Asm:
2+
3+
Reading Asm
4+
===========
5+
6+
..
7+
we must use --no-sandbox with nix or else this will fail
8+
.. exec::
9+
:context: true
10+
:process: haskell
11+
:project_dir: code/lethargy
12+
:with: cabal
13+
:args: run lethargy-asm
14+
:output: comp
15+
:intertext: Core output (the 0 at the end is the program's result):
16+

src/Measurement_Observation/Binary_Profiling/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Binary Profiling and Probing
66
:glob:
77
:name: binary_prof
88

9+
asm
910
linux_time
1011
linux_perf
1112
dtrace

0 commit comments

Comments
 (0)