Skip to content

Commit 55993b9

Browse files
committed
Added escaping HTML in the original markdown.
1 parent 0b4cf4d commit 55993b9

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

mcq_hammertime/example/Synchronization,-Part-1:-Mutex-Locks.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
## What is a Critical Section?
22
A critical section is a section of code that can only be executed by one thread at a time, if the program is to function correctly. If two threads (or processes) were to execute code inside the critical section at the same time then it is possible that program may no longer have correct behavior.
33

4+
<h1>
5+
I can be malicious!
6+
</h1>
7+
8+
<script>
9+
alert("no");
10+
</script>
11+
412
## Is just incrementing a variable a critical section?
513
Possibly. Incrementing a variable (`i++`) is performed in three individual steps: Copy the memory contents to the CPU register. Increment the value in the CPU. Store the new value in memory. If the memory location is only accessible by one thread (e.g. automatic variable `i` below) then there is no possibility of a race condition and no Critical Section associated with `i`. However the `sum` variable is a global variable and accessed by two threads. It is possible that two threads may attempt to increment the variable at the same time.
614
```C

mcq_hammertime/example/output/synchronization-converted.html

+28-22
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,32 @@
99
<body>
1010
<h2>What is a Critical Section?</h2>
1111
<p>A critical section is a section of code that can only be executed by one thread at a time, if the program is to function correctly. If two threads (or processes) were to execute code inside the critical section at the same time then it is possible that program may no longer have correct behavior.</p>
12+
<p>&lt;h1&gt;<br />
13+
I can be malicious!<br />
14+
&lt;/h1&gt;</p>
15+
<p>&lt;script&gt;<br />
16+
alert("no");<br />
17+
&lt;/script&gt;</p>
1218
<h2>Is just incrementing a variable a critical section?</h2>
1319
<p>Possibly. Incrementing a variable (<code>i++</code>) is performed in three individual steps: Copy the memory contents to the CPU register. Increment the value in the CPU. Store the new value in memory. If the memory location is only accessible by one thread (e.g. automatic variable <code>i</code> below) then there is no possibility of a race condition and no Critical Section associated with <code>i</code>. However the <code>sum</code> variable is a global variable and accessed by two threads. It is possible that two threads may attempt to increment the variable at the same time.</p>
14-
<div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
15-
<span class="cp">#include &lt;pthread.h&gt;</span>
20+
<div class="highlight"><pre><span class="cp">#include &amp;lt;stdio.h&amp;gt;</span>
21+
<span class="cp">#include &amp;lt;pthread.h&amp;gt;</span>
1622
<span class="c1">// Compile with -pthread</span>
1723

1824
<span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">//shared</span>
1925

2026
<span class="kt">void</span> <span class="o">*</span><span class="nf">countgold</span><span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="n">param</span><span class="p">)</span> <span class="p">{</span>
2127
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span> <span class="c1">//local to each thread</span>
22-
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
28+
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
2329
<span class="n">sum</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
2430
<span class="p">}</span>
2531
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
2632
<span class="p">}</span>
2733

2834
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
2935
<span class="kt">pthread_t</span> <span class="n">tid1</span><span class="p">,</span> <span class="n">tid2</span><span class="p">;</span>
30-
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
31-
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tid2</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
36+
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
37+
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">tid2</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
3238

3339
<span class="c1">//Wait for both threads to finish:</span>
3440
<span class="n">pthread_join</span><span class="p">(</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
@@ -47,12 +53,12 @@ <h2>How do I ensure only one thread at a time can access a global variable?</h2>
4753
If one thread is currently inside a critical section we would like another thread to wait until the first thread is complete. For this purpose we can use a mutex (short for Mutual Exclusion).</p>
4854
<p>For simple examples the smallest amount of code we need to add is just three lines:</p>
4955
<div class="highlight"><pre><span class="kt">pthread_mutex_t</span> <span class="n">m</span> <span class="o">=</span> <span class="n">PTHREAD_MUTEX_INITIALIZER</span><span class="p">;</span> <span class="c1">// global variable</span>
50-
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span> <span class="c1">// start of Critical Section</span>
51-
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span> <span class="c1">//end of Critical Section</span>
56+
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span> <span class="c1">// start of Critical Section</span>
57+
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span> <span class="c1">//end of Critical Section</span>
5258
</pre></div>
5359

5460

55-
<p>Once we are finished with the mutex we should also call <code>pthread_mutex_destroy(&amp;m)</code> too. Note, you can only destroy an unlocked mutex. Calling destroy on a destroyed lock, initializing an initialized lock, locking an already locked lock, unlocking an unlocked lock etc are unsupported (at least for default mutexes) and usually result in undefined behavior.</p>
61+
<p>Once we are finished with the mutex we should also call <code>pthread_mutex_destroy(&amp;amp;m)</code> too. Note, you can only destroy an unlocked mutex. Calling destroy on a destroyed lock, initializing an initialized lock, locking an already locked lock, unlocking an unlocked lock etc are unsupported (at least for default mutexes) and usually result in undefined behavior.</p>
5662
<div class="question-container">
5763
<div class="question">
5864
<h3>What is the class I am taking?</h3>
@@ -72,7 +78,7 @@ <h2>If I lock a mutex, does it stop all other threads?</h2>
7278
<h2>Are there other ways to create a mutex?</h2>
7379
<p>Yes. You can use the macro PTHREAD_MUTEX_INITIALIZER only for global ('static') variables.<br />
7480
m = PTHREAD_MUTEX_INITIALIZER is equivalent to the more general purpose<br />
75-
<code>pthread_mutex_init(&amp;m,NULL)</code>. The init version includes options to trade performance for additional error-checking and advanced sharing options.</p>
81+
<code>pthread_mutex_init(&amp;amp;m,NULL)</code>. The init version includes options to trade performance for additional error-checking and advanced sharing options.</p>
7682
<div class="highlight"><pre><span class="kt">pthread_mutex_t</span> <span class="o">*</span><span class="n">lock</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">pthread_mutex_t</span><span class="p">));</span>
7783
<span class="n">pthread_mutex_init</span><span class="p">(</span><span class="n">lock</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
7884
<span class="c1">//later</span>
@@ -110,8 +116,8 @@ <h2>Is there any overhead in calling lock and unlock?</h2>
110116
<p>There is a small amount of overhead of calling <code>pthread_mutex_lock</code> and <code>_unlock</code>; however this is the price you pay for correctly functioning programs!</p>
111117
<h2>Simplest complete example?</h2>
112118
<p>A complete example is shown below</p>
113-
<div class="highlight"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
114-
<span class="cp">#include &lt;pthread.h&gt;</span>
119+
<div class="highlight"><pre><span class="cp">#include &amp;lt;stdio.h&amp;gt;</span>
120+
<span class="cp">#include &amp;lt;pthread.h&amp;gt;</span>
115121

116122
<span class="c1">// Compile with -pthread</span>
117123
<span class="c1">// Create a mutex this ready to be locked!</span>
@@ -127,21 +133,21 @@ <h2>Simplest complete example?</h2>
127133
<span class="c1">//However locking and unlocking a million times</span>
128134
<span class="c1">//has significant overhead in this simple answer</span>
129135

130-
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
136+
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
131137

132138
<span class="c1">// Other threads that call lock will have to wait until we call unlock</span>
133139

134-
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
140+
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
135141
<span class="n">sum</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
136142
<span class="p">}</span>
137-
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
143+
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
138144
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
139145
<span class="p">}</span>
140146

141147
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
142148
<span class="kt">pthread_t</span> <span class="n">tid1</span><span class="p">,</span> <span class="n">tid2</span><span class="p">;</span>
143-
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
144-
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">tid2</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
149+
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
150+
<span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">tid2</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">countgold</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
145151

146152
<span class="c1">//Wait for both threads to finish:</span>
147153
<span class="n">pthread_join</span><span class="p">(</span><span class="n">tid1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
@@ -154,10 +160,10 @@ <h2>Simplest complete example?</h2>
154160

155161

156162
<p>In the code above, the thread gets the lock to the counting house before entering. The critical section is only the <code>sum+=1</code> so the following version is also correct but slower - </p>
157-
<div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
158-
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
163+
<div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
164+
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
159165
<span class="n">sum</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
160-
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
166+
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
161167
<span class="p">}</span>
162168
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
163169
<span class="p">}</span>
@@ -166,13 +172,13 @@ <h2>Simplest complete example?</h2>
166172

167173
<p>This process runs slower because we lock and unlock the mutex a million times, which is expensive - at least compared with incrementing a variable. (And in this simple example we didn't really need threads - we could have added up twice!) A faster multi-thread example would be to add one million using an automatic(local) variable and only then adding it to a shared total after the calculation loop has finished:</p>
168174
<div class="highlight"><pre> <span class="kt">int</span> <span class="n">local</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
169-
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
175+
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span> <span class="mi">10000000</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
170176
<span class="n">local</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
171177
<span class="p">}</span>
172178

173-
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
179+
<span class="n">pthread_mutex_lock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
174180
<span class="n">sum</span> <span class="o">+=</span> <span class="n">local</span><span class="p">;</span>
175-
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m</span><span class="p">);</span>
181+
<span class="n">pthread_mutex_unlock</span><span class="p">(</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="n">m</span><span class="p">);</span>
176182

177183
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
178184
<span class="p">}</span>

mcq_hammertime/mcq_hammertime.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
from __future__ import absolute_import
22
from markdown.blockprocessors import BlockProcessor
33
from markdown.extensions import Extension
4+
from markdown.preprocessors import Preprocessor
45
from markdown.util import etree
5-
import re
6+
import re, cgi
67

78
MCQ_START = "@MCQ\n"
89
ANS = "@ANS"
910
HINT = "@HINT"
1011
EXP = "@EXP"
1112
MCQ_END = "@END\n"
1213

14+
class HTMLPreprocessor(Preprocessor):
15+
def run(self, lines):
16+
return [cgi.escape(l) for l in lines]
17+
1318
class MCQuestion(object):
1419
"""
1520
Class to hold properties of a Multiple Choice Question.
@@ -142,6 +147,7 @@ class MCExtension(Extension):
142147
Add Multiple Choice Questions to Markdown.
143148
"""
144149
def extendMarkdown(self, md, md_globals):
150+
md.preprocessors.add('html_escape', HTMLPreprocessor(md), '_begin')
145151
md.parser.blockprocessors.add('mcq', MCProcessor(md.parser), '_begin')
146152

147153
def makeExtension(**kwargs):

0 commit comments

Comments
 (0)