<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[A First-Principles-Driven Life - Miao's Search for Meaning]]></title>
<description><![CDATA[A First-Principles-Driven Life - Miao's Search for Meaning]]></description>
<link>http://miaozc.me/</link>
<lastBuildDate>Fri, 21 Feb 2025 23:38:18 +0200</lastBuildDate>
<item>
  <title><![CDATA[PatternMatchable, Yoneda Embedding, and Adjunction]]></title>
  <description><![CDATA[
<div id="outline-container-org8e20ae9" class="outline-2">
<h2 id="org8e20ae9">Pattern Matching For an Embedded DSL</h2>
<div class="outline-text-2" id="text-org8e20ae9">
<p>
For a embedded DSL <code>m :: Type -&gt; Type</code>, we would like to introduce a function <code>match</code> to match a pattern and a function
<code>be</code> to construct such a pattern. Here is an example of using them:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #5F7F5F;">-- </span><span style="color: #7F9F7F;">Note: BlockArguments &amp; LambdaCase extensions used</span>

<span style="color: #5F7F5F;">-- </span><span style="color: #7F9F7F;">Pattern match @pat@ of two cases, and recreate the pattern @pat'@</span>
<span style="color: #93E0E3;">pat'</span> <span style="color: #DFAF8F;">=</span> match pat <span style="color: #DFAF8F;">\</span><span style="color: #F0DFAF; font-weight: bold;">case</span>
  <span style="color: #7CB8BB;">Maybe</span> a <span style="color: #DFAF8F;">-&gt;</span> be (<span style="color: #7CB8BB;">Maybe</span> a)
  <span style="color: #7CB8BB;">Nothing</span> <span style="color: #DFAF8F;">-&gt;</span> be <span style="color: #7CB8BB;">Nothing</span>
</pre>
</div>

<p>
Generally, the property of pattern matchable is <code>\pat -&gt; match pat be ≃ id</code>.
</p>

<p>
How about their type signatures? Let's have the pattern as <code>pat :: m p</code>, the pattern cases <code>c</code>, and the pattern matching
result as <code>:: m b</code>.  Then we have:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #93E0E3;">match</span> <span style="color: #DFAF8F;">::</span> <span style="color: #DFAF8F;">&#8704;</span> m p c b<span style="color: #DFAF8F;">.</span> m p <span style="color: #DFAF8F;">-&gt;</span> (c <span style="color: #DFAF8F;">-&gt;</span> m b) <span style="color: #DFAF8F;">-&gt;</span> m b
<span style="color: #93E0E3;">be</span> <span style="color: #DFAF8F;">::</span> <span style="color: #DFAF8F;">&#8704;</span> m p c<span style="color: #DFAF8F;">.</span> c <span style="color: #DFAF8F;">-&gt;</span> m p
</pre>
</div>

<p>
However, typically, in any language, <code>b</code> should be constrained, say by k. Now, we need a type class to put everything
together:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #F0DFAF; font-weight: bold;">class</span> <span style="color: #7CB8BB;">PatternMatchable</span> m k p c <span style="color: #DFAF8F;">|</span> m <span style="color: #DFAF8F;">-&gt;</span> k, m p <span style="color: #DFAF8F;">-&gt;</span> c, c <span style="color: #DFAF8F;">-&gt;</span> m p <span style="color: #F0DFAF; font-weight: bold;">where</span>
  match <span style="color: #DFAF8F;">::</span> <span style="color: #DFAF8F;">&#8704;</span> b<span style="color: #DFAF8F;">.</span> k b <span style="color: #DFAF8F;">=&gt;</span> m p <span style="color: #DFAF8F;">-&gt;</span> (c <span style="color: #DFAF8F;">-&gt;</span> m b) <span style="color: #DFAF8F;">-&gt;</span> m b
  be <span style="color: #DFAF8F;">::</span> <span style="color: #DFAF8F;">&#8704;</span> <span style="color: #DFAF8F;">.</span> c <span style="color: #DFAF8F;">-&gt;</span> m p
</pre>
</div>

<p>
Indeed, this is the code used in the <a href="https://github.com/yolc-dev/yul-dsl-monorepo/blob/master/hs-pkgs/yul-dsl-pure/src/Control/PatternMatchable.hs">Yolc project</a>. As a further illustration, here is a couple of example instances of
the <code>PatternMatchable</code> from the Yolc project:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #5F7F5F;">-- </span><span style="color: #7F9F7F;">Pattern matching of Maybe values</span>
<span style="color: #F0DFAF; font-weight: bold;">instance</span> <span style="color: #7CB8BB;">PatternMatchable</span> (<span style="color: #7CB8BB;">YulCat</span> eff r) <span style="color: #7CB8BB;">YulCatObj</span> (<span style="color: #7CB8BB;">Maybe</span> (<span style="color: #7CB8BB;">INTx</span> s n)) (<span style="color: #7CB8BB;">Maybe</span> (<span style="color: #7CB8BB;">YulCat</span> eff r (<span style="color: #7CB8BB;">INTx</span> s n)))
<span style="color: #5F7F5F;">-- </span><span style="color: #7F9F7F;">Pattern matching of Solo tuple</span>
<span style="color: #F0DFAF; font-weight: bold;">instance</span> <span style="color: #7CB8BB;">PatternMatchable</span> (<span style="color: #7CB8BB;">YulCat</span> eff r) <span style="color: #7CB8BB;">YulCatObj</span> (<span style="color: #7CB8BB;">Solo</span> a) (<span style="color: #7CB8BB;">YulCat</span> eff r a)
<span style="color: #5F7F5F;">-- </span><span style="color: #7F9F7F;">Pattern matching of tuple</span>
<span style="color: #7CB8BB;">PatternMatchable</span> (<span style="color: #7CB8BB;">YulCat</span> eff r) <span style="color: #7CB8BB;">YulCatObj</span> (a1, a2) (<span style="color: #7CB8BB;">YulCat</span> eff r a1, <span style="color: #7CB8BB;">YulCat</span> eff r a2)
</pre>
</div>
</div>
</div>
<div id="outline-container-orgeae8c29" class="outline-2">
<h2 id="orgeae8c29">Working Backward: Yoneda Embedding</h2>
<div class="outline-text-2" id="text-orgeae8c29">
<p>
How can you come up with such a design in the first place?
</p>

<p>
While admittedly, I had to look at the problem for a very long time with trial and error on paper or in code,
eventually, the solution came to mind like a light bulb lit up.
</p>

<p>
More experienced practitioners may find this task easy. But the question is, apart from practicing Haskell or functional
programming more, what sort of general knowledge should one learn to find these solutions faster?
</p>

<p>
I went back to category theory for answers, and indeed, it is an application of no other than the Yoneda lemma
itself. Specifically, it is the special case "Yoneda embedding."
</p>

<p>
Bartosz Milewski has a wonderful article about <a href="https://bartoszmilewski.com/2015/10/28/yoneda-embedding/">Yoneda Embedding</a> itself, I will not repeat here. Instead, I take its
conclusion directly below.
</p>

<p>
In its categorical formulation, in the functor category <code>[C, Set]</code>, a natural transformation from hom-functor <code>C(a, -)</code>
to hom-functor <code>C(b, -)</code> is isomorphic to <code>C(b, a)</code>.
</p>

<blockquote>
<p>
[C, Set](C(a, -), C(b, -)) ≃ C(b, a)
</p>
</blockquote>

<p>
We can translate the above to its equivalent Haskell code.
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #DFAF8F;">&#8704;</span> x<span style="color: #DFAF8F;">.</span> (a <span style="color: #DFAF8F;">-&gt;</span> x) <span style="color: #DFAF8F;">-&gt;</span> (b <span style="color: #DFAF8F;">-&gt;</span> x) <span style="color: #DFAF8F;">&#8771;</span> b <span style="color: #DFAF8F;">-&gt;</span> a
</pre>
</div>

<p>
Now, let's work backward. We should be able to implement <code>be :: c -&gt; m p</code> easily for the DSL. However, it is not possible
for its inverse: <code>not_possible :: m p -&gt; c</code>. This is because <code>c</code> is not part of the language <code>m</code>, so it cannot "escape"
as an independent value.
</p>

<p>
At this point, you may use some ad-hoc functional programming jargon, such as "continuation," to find the <code>match</code>
function solution. Instead, I'd like to show that with Yoneda embedding, it becomes a rather mechanical exercise. Here
is how:
</p>

<ol class="org-ol">
<li>Since we cannot implement <code>m p -&gt; c</code>, we apply Yoneda embedding.</li>
<li>We then have <code>m p -&gt; c ≃ (c -&gt; x) -&gt; (m p -&gt; x)</code>.</li>
<li>We replace <code>x</code> with <code>m b</code>, the result we are looking for: <code>(c -&gt; m b) -&gt; (m p -&gt; m b)</code>.</li>
<li>We remove the second pair of brackets, which are redundant: <code>(c -&gt; m b) -&gt; m p -&gt; m b</code>.</li>
<li>We flip the first and second argument: <code>m p -&gt; (c -&gt; m b) -&gt; m b</code>.</li>
<li>We arrived at the same signature of the <code>match</code> function.</li>
</ol>

<p>
As the category theory often promises, every knowledge we know of is likely an example of a category and some universal
properties. I am glad I have found an application of Yoneda lemma after all.
</p>
</div>
</div>
<div id="outline-container-orgaa9d606" class="outline-2">
<h2 id="orgaa9d606">Adjunction Between Hask and Your DSL</h2>
<div class="outline-text-2" id="text-orgaa9d606">
<p>
Here is another observation of how <code>match</code> function is also an adjunction.
</p>

<p>
Again, I will refer you to Bartosz' article about <a href="https://bartoszmilewski.com/2016/04/18/adjunctions/">adjunctions</a>, for more about the topic.
</p>

<p>
Let's say your eDSL program <code>m a</code> is of category <code>D</code>. Additionally, we can also view Haskell types as objects in the category of
<a href="https://wiki.haskell.org/Hask">Hask</a>. Technically, as an deep embedded DSL, all objects in <code>D</code> is also in Hask. However, as a DSL, there should be no
morphism from object in <code>D</code> to ones outside of <code>D</code>. For this reason, we illustrate the <code>match</code> function as an
adjunction that depicts <code>D</code> and <code>Hask</code> not overlapped for better visuals.
</p>


<figure id="org52f7026">
<img src="../static/2025-01-15/match-as-adjunction.png" alt="match-as-adjunction.png">

</figure>
</div>
</div>
<div id="outline-container-org10ad667" class="outline-2">
<h2 id="org10ad667">Conclusion</h2>
<div class="outline-text-2" id="text-org10ad667">
<p>
There is one thing about Category Theory that I have found <a href="https://x.com/ChShersh/status/1877867017354522897">other such as @ChShersh also agree with</a> "you can program
perfectly fine without it. Many people do, it's not the end of the world. But it's not a great life either."
</p>

<p>
In a world where AI can increasingly spit out code patterns that accomplish tasks effectively, I would like to believe
that category theory and mathematics are what give meaning to our lives by training our brains with these beautiful and
elegant knowledge.
</p>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-haskell.html">haskell</a> <a href="http://miaozc.me/tag-category-theory.html">category-theory</a> </div>
]]></description>
  <category><![CDATA[haskell]]></category>
  <category><![CDATA[category-theory]]></category>
  <link>http://miaozc.me/2025-01-15-patternmatchable-and-yoneda-embedding.html</link>
  <guid>http://miaozc.me/2025-01-15-patternmatchable-and-yoneda-embedding.html</guid>
  <pubDate>Sat, 15 Feb 2025 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[What Is Principle and Can We Know It?]]></title>
  <description><![CDATA[
<p>
The opening chapter in the same-title book of Leonard Peikoff's "Why Act on Principle?" - a collection of his best
articles and talks - starts with paying attention to the most commonly observed intuition of our world today: we live in
a "complex" world. As the author then points out, the utterance of this observation is used as an argument for a
methodology that goes unchecked in today's society, which is called <i>pragmatism</i>.
</p>

<p>
So, what is wrong with <i>pragmatism</i>? Is it not a <i>reasonable</i> thing to do for any well-educated man?
</p>

<p>
The world is complex, and man's life is inherently complex. "He has countless choices to make, he has the whole world
spread before him, he must continually make decisions and weigh results keeping in mind a multiplicity of factors."
Facing the complexity, the most fundamental methodological choice man must make is whether he can find a generalization
over concrete, and if so, how can he find such a generalization?
</p>

<p>
As a pragmatist, the answer is no. Instead of looking for generalizations, a pragmatist deals with the
particular. "Well, it depends on the situation." says a pragmatist. You then press him further, "Had we studied as much
of the situations as possible, is it possible for us to come up with a generalization that says something about this
situation?" "But who could have?" The pragmatist deflects. "<i>A principle is a basic generalization</i>. We have learned
principles suited for many situations from the vast wealth of human knowledge." You should now strike straight into the
heart of the issue. "You are just being simple-minded." The pragmatist inevitably resorts to ad hominem. That's when you
know that's where the "Big Lie" is.
</p>

<p>
It cannot be further from the truth to say that a rational thinker who acts on principle is being "simple." Contrarily,
he engages in a complex mental activity that condenses information he has gathered and retained. "Concepts are man's
means of condensing information," and the conceptual faculty in humans is called "reason."
</p>

<p>
With reason, a man can fully grasp new principles from experiencing reality. And a man does not need to do it
alone. Experiences gathered from other men and principles reasoned by other men can all be a man's source of new
knowledge. To say a man acting on principle is simple is a grotesque defamation, and we must be ready to rebuke it
immediately.
</p>

<p>
Of course, that is not to say a man is not fallible. After all, man and all men's experience is expanding, thanks to our
growing wealth of knowledge. Newton's law of gravity was not wrong, in the face of the theory of general relativity, but
a knowledge applicable under a specific context that men had not known otherwise. It is not a repudiation of man's
capability of reason but an endorsement of men's ability to continually expand our understanding of reality.
</p>

<p>
So, a principle is a basic generalization, and can men know it? Absolutely.
</p>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-philosophy.html">philosophy</a> </div>
]]></description>
  <category><![CDATA[philosophy]]></category>
  <link>http://miaozc.me/2024-09-21-principle-1.html</link>
  <guid>http://miaozc.me/2024-09-21-principle-1.html</guid>
  <pubDate>Sat, 21 Sep 2024 18:15:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[Goodbye, the Waystation Crypto Libertarians!]]></title>
  <description><![CDATA[

<figure id="org2efc52a">
<img src="../static/2023-11-28-crypto-libertarians/goodbye-crypto-libertarians.png" alt="goodbye-crypto-libertarians.png">

</figure>

<p>
It is Stephan Kinsella, one of the authoritative living minds in libertarian legal theory, who <a href="https://www.stephankinsella.com/2021/01/creative-common-law-project-r-i-p-and-waystation-libertarians/">coined the term</a>
"waystation libertarians" as "Someone who was only 'passing through' libertarianism on their meandering, endless journey
through ideologies and faddish, dilettantish interests."
</p>

<p>
As someone who has been in the libertarian movement actively for almost a decade and is currently retreating to a side
project named <a href="https://missionliberty.ee">"Mission: Liberty"</a> due to time conflicts, I should like to have something to say about it.
</p>

<p>
Considering all other waystation libertarian movements during my time, Ron Paul libertarians, Sound Money (Goldgug or
Bitcoin) libertarians, NatCon/Trump libertarians, Crypto libertarians, Covid libertarians, and now Milei libertarians,
what I have been entangling my life the most is the sound money and crypto libertarians, where my startup is a business
that surviving the post-SBF crypto winter. I have a growing grudge against the crypto libertarians, which I will explain
in a moment. But similar to Mr. Kinsella's realization, I really should not.
</p>


<figure id="org2cc87fc">
<img src="../static/2023-11-28-crypto-libertarians/recent-wastations.png" alt="recent-wastations.png">

</figure>

<p>
I will put out my conclusion: the crypto libertarian movement is dead. If it's comforting to hear in a somewhat perverse
way, its predecessor, the Sound Money/Bitcoin libertarians movement, is barely limping along, where the biggest hopes
are that Blackrock can create an ETF and buy their digital gold! What an abomination!
</p>

<p>
In fairness, for the libertarian meetups I organize or go to, the Bitcoin movement remains the most activism-oriented
and keeps bringing in new energy. Undoubtedly, <a href="https://saifedean.com/">Saifedean Ammous's works</a> "The Bitcoin Standard" and "Principles of
Economics" have inspired young minds to get into the idea of sound money, the Austrian
school of thought in economics, and rational individualism.
</p>

<p>
But crypto libertarians, with its ever-moving targets (and some comical sagas along its way) - from native internet of
money to stablecoins backed by fiat; from crowdfunding to VC-backed; from fully decentralized to sufficiently
decentralized; from lemonade coin to decentralized physical infrastructure (DePIN!); from peer-to-peer decentralized
operating systems (e.g. Urbit) to decentralized social (DeSo!); the list goes on - it is a rather elusive term that
after a while, just like other waystation movements, it might have never existed!
</p>

<p>
So it is perhaps instead, the hope that it ever can exist is dead. In the face of this, anyone can justify their
emotion. Anger: how we end up here where no one cares to promote our ideas. Sad and self-pity: how we didn't know better
when we brought in detractors and fraudsters. Cynical: libertarian objectives will forever remain fringe. Jealous: look
at the ones who joined and made the money; if I had the money, I should fund a movement myself!
</p>

<p>
There can be an indifferent emotion: it is just what it is. But it is a nonproductive emotion. While I believe the most
practical and positive emotion and attitude to the matter is a subtle one. That is a skillful play between a rational
acceptance and a wise realization of the libertarian movement under the historical context. Understanding the waystation
phenomenon of movement is essential for anyone to come to this realization.
</p>

<p>
It is a relieving realization and practical attitude:
</p>

<ul class="org-ul">
<li>If you are still deep in the crypto industry like me, stop thinking about it still being part of the libertarian
movement anymore, focus on what is in it for you, and get the job done.</li>
<li>Think of the whole libertarian movement as a non-stopping train to a destination in which we all share the same
faith. Let's welcome the passengers along the waystations we pass through and wish them all good fortune after they
hop off.</li>
<li>To quote a motto of mine from an ancient book of wisdom: "I have fought a good fight, I have finished my course, I
have kept the faith."</li>
</ul>

<p>
P.S.
</p>

<p>
Congrats to Milei, and let us wholeheartedly welcome the upcoming Milei libertarians at our next stop!
</p>


<figure id="orgd738d93">
<img src="../static/2023-11-28-crypto-libertarians/dont-tread-on-me-argentina.png" alt="dont-tread-on-me-argentina.png">

</figure>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-politics.html">politics</a> </div>
]]></description>
  <category><![CDATA[politics]]></category>
  <link>http://miaozc.me/2023-11-28-goodbye-crypto-libertarians.html</link>
  <guid>http://miaozc.me/2023-11-28-goodbye-crypto-libertarians.html</guid>
  <pubDate>Tue, 28 Nov 2023 13:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[A Solidity Compilers Collection in Nix]]></title>
  <description><![CDATA[
<p>
I have written <a href="https://github.com/hellwolf/solc.nix"><code>solc.nix</code></a> for a while, this article is a summary of it.
</p>

<p>
It is a collection of solidity compilers as nix expressions. While most solidity development toolchains (foundry,
truffle, hardhat, etc.) have their bespoke mechanisms of downloading solidity compiler (<code>solc</code>) binaries, there are
situations you would want not to rely on them:
</p>

<ul class="org-ul">
<li>In a CI environment, you provide the compiler during setup instead of letting toolchains download them again.</li>
<li>You have a development process that does not have the <code>solc</code> resolution mechanism.</li>
<li>You are juggling with multiple versions of solidity compilers.</li>
<li>You are using NixOS or the "Nix package manager".</li>
</ul>

<p>
If any of these cases apply to you, you should consider using <code>solc.nix</code>. Here are some tips on how.
</p>

<div id="outline-container-org50dd301" class="outline-2">
<h2 id="org50dd301">Install Nix</h2>
<div class="outline-text-2" id="text-org50dd301">
<p>
Here is a write-up of <a href="https://medium.com/@miaozc/stop-writing-instructions-and-use-nix-47644dbc9b6">why I think you should use Nix</a>.
</p>

<p>
The fastest way to have it installed on your system is to follow the <a href="https://nixos.org/download.html#download-nix">official instruction</a>.
</p>

<p>
Once installed, you are good to go!
</p>
</div>
</div>

<div id="outline-container-orgf984cf6" class="outline-2">
<h2 id="orgf984cf6">Using Nix Shell</h2>
<div class="outline-text-2" id="text-orgf984cf6">
<p>
If you just wanted to have some version of <code>solc</code> ad-hoc, you just need one simple line:
</p>

<pre class="example" id="org1913422">
$ nix shell github:hellwolf/solc.nix#solc_0_4_26 github:hellwolf/solc.nix#solc_0_8_19
</pre>

<p>
Then you will have two different <code>solc</code> binary available for you:
</p>

<pre class="example" id="org7d0f242">
$ solc-0.4.26 --version
solc, the solidity compiler commandline interface
Version: 0.4.26+commit.4563c3fc.Linux.g++

$ solc-0.8.19 --version
solc, the solidity compiler commandline interface
Version: 0.8.19+commit.7dd6d404.Linux.g++
</pre>
</div>
</div>

<div id="outline-container-org0115f28" class="outline-2">
<h2 id="org0115f28">Using Nix Flake</h2>
<div class="outline-text-2" id="text-org0115f28">
<p>
If you want a deeper integration of it, you should consider using Nix Flake, here is an example of how to have multiple
<code>solc</code> installed and one of them as the default one:
</p>

<div class="org-src-container">
<pre class="src src-nix">{
  <span style="color: #DFAF8F;">inputs</span> = {
    <span style="color: #DFAF8F;">solc</span> = {
      <span style="color: #DFAF8F;">url</span> = <span style="color: #CC9393;">"github:hellwolf/solc.nix"</span>;
      <span style="color: #DFAF8F;">inputs.nixpkgs.follows</span> = <span style="color: #CC9393;">"nixpkgs"</span>;
    };
  };

  <span style="color: #DFAF8F;">outputs</span> = { self, nixpkgs, solc }: <span style="color: #F0DFAF; font-weight: bold;">let</span>
    <span style="color: #DFAF8F;">pkgs</span> = <span style="color: #DCDCCC; font-weight: bold;">import</span> nixpkgs {
      <span style="color: #DFAF8F;">system</span> = <span style="color: #CC9393;">"x86_64-linux"</span>;
      <span style="color: #DFAF8F;">overlays</span> = [
        solc.overlay
      ];
    };
  <span style="color: #F0DFAF; font-weight: bold;">in</span> {
    <span style="color: #DFAF8F;">devShell.x86_64-linux</span> = <span style="color: #F0DFAF; font-weight: bold;">with</span> pkgs; mkShell {
      <span style="color: #DFAF8F;">buildInputs</span> = [
        solc_0_4_26
        solc_0_7_6
        solc_0_8_19
        (solc.mkDefault pkgs solc_0_8_19)
      ];
    };
  };
}
</pre>
</div>
</div>
</div>

<div id="outline-container-orgc5b2987" class="outline-2">
<h2 id="orgc5b2987">Contribute</h2>
<div class="outline-text-2" id="text-orgc5b2987">
<p>
If you find this tool useful, please follow up at the <a href="https://github.com/hellwolf/solc.nix">git repo</a>, contribute to keep this up to date, and share with
people you might think it can help them too!
</p>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-nix.html">nix</a> <a href="http://miaozc.me/tag- .html"> </a> <a href="http://miaozc.me/tag-solidity.html">solidity</a> </div>
]]></description>
  <category><![CDATA[nix]]></category>
  <category><![CDATA[ ]]></category>
  <category><![CDATA[solidity]]></category>
  <link>http://miaozc.me/2023-07-07-solc-nix.html</link>
  <guid>http://miaozc.me/2023-07-07-solc-nix.html</guid>
  <pubDate>Fri, 07 Jul 2023 09:18:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[My Haskell Tiny Game Jam Submissions: Othello & Lol]]></title>
  <description><![CDATA[
<p>
This post is a last-minute write-up for my participation in the <a href="https://github.com/haskell-game/tiny-games-hs">Haskell Tiny Game Jam</a>. The goal was to implement a game
that fits into 10 lines of 80 characters. I have submitted two entries: one is a <a href="https://github.com/haskell-game/tiny-games-hs/blob/main/prelude/mini-othello/">mini-othello game</a>, the other is a <a href="https://github.com/haskell-game/tiny-games-hs/blob/main/default/lol">meta
game called "lol"</a>.
</p>

<div id="outline-container-org73d9f83" class="outline-2">
<h2 id="org73d9f83">Mini Othello</h2>
<div class="outline-text-2" id="text-org73d9f83">
<p>
It is a minimum <i>Othello game</i> implementation with MiniMax "AI" opponent using GHC 9.X with only the "prelude" module
allowed.
</p>

<p>
The rule of the game is: "There are sixty-four identical game pieces called disks, which are light on one side and dark
on the other. Players take turns placing disks on the board with their assigned color facing up. During a play, any
disks of the opponent's color that are in a straight line and bounded by the disk just placed and another disk of the
current player's color are turned over to the current player's color. The objective of the game is to have the majority
of disks turned to display one's color when the last playable empty square is filled."
(<a href="https://en.wikipedia.org/wiki/Reversi">https://en.wikipedia.org/wiki/Reversi</a>)
</p>

<p>
To play the game, checkout the <a href="https://github.com/haskell-game/tiny-games-hs">tiny game repository</a> and type <code>./play mini-othello</code>:
</p>


<figure id="org64c1384">
<img src="https://github.com/haskell-game/tiny-games-hs/raw/main/prelude/mini-othello/mini-othello-1.gif" alt="mini-othello-1.gif">

</figure>

<p>
I implemented the game entirely in minified code, so the variable and function names will be pretty cryptic!
</p>
</div>

<div id="outline-container-org399e1ca" class="outline-3">
<h3 id="org399e1ca">Functions Overview</h3>
<div class="outline-text-3" id="text-org399e1ca">
<p>
First, I represent the game state with a product type of Board and Side (only conceptually, but without actual code):
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #b4fa70;">type</span> <span style="color: #8cc4ff;">Side</span> <span style="color: #fcaf3e;">=</span> <span style="color: #8cc4ff;">Black</span> <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">White</span> <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">None</span>
<span style="color: #b4fa70;">type</span> <span style="color: #8cc4ff;">Coordinate</span> <span style="color: #fcaf3e;">=</span> (<span style="color: #8cc4ff;">Int</span>, <span style="color: #8cc4ff;">Int</span>) <span style="color: #73d216;">-- </span><span style="color: #73d216;">from (0,0) to (7,7)</span>
<span style="color: #b4fa70;">type</span> <span style="color: #8cc4ff;">Board</span> <span style="color: #fcaf3e;">=</span> [<span style="color: #8cc4ff;">Char</span>] <span style="color: #73d216;">-- </span><span style="color: #73d216;">64 of them!</span>
<span style="color: #e9b96e;">-- | Game state type alias</span>
<span style="color: #b4fa70;">type</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">=</span> (<span style="color: #8cc4ff;">Board</span>, <span style="color: #8cc4ff;">Side</span>)

<span style="color: #fce94f;">n</span> <span style="color: #fcaf3e;">=</span> <span style="color: #e9b96e;">"_XO"</span> <span style="color: #73d216;">-- </span><span style="color: #73d216;">visually they are reprensed these chars.</span>
</pre>
</div>

<p>
Then I implemented a helper function <code>v</code> for checking the number of flips per each line. There are 8 different
directions the line can go, they are all enumerable by a <code>StepCoordinate</code> type.
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #73d216;">-- </span><span style="color: #73d216;">number of steps (-1,0 or 1) in each direction to represent 8 different directions.</span>
<span style="color: #b4fa70;">type</span> <span style="color: #8cc4ff;">StepCoordinate</span> <span style="color: #fcaf3e;">=</span> (<span style="color: #8cc4ff;">Int</span>, <span style="color: #8cc4ff;">Int</span>)

<span style="color: #e9b96e;">-- | Check number of flips for one single direction</span>
<span style="color: #fce94f;">v</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">-&gt;</span> (<span style="color: #8cc4ff;">GameState</span>, <span style="color: #8cc4ff;">Int</span>) <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">Coordinate</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">StepCoordinate</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">State</span>
  <span style="color: #fcaf3e;">-&gt;</span> (<span style="color: #8cc4ff;">GameState</span>, <span style="color: #8cc4ff;">Int</span>)
<span style="color: #fce94f;">v</span> savedGameState (currentGameState, nFlips) cor stepCor state
  <span style="color: #fcaf3e;">-&gt;</span> (newGameState, nFlips)
</pre>
</div>

<p>
Then the <code>%</code> operator for trial plays. Because this is used so often, the usage of this binary operator saves a lot of
spaces!
</p>

<div class="org-src-container">
<pre class="src src-haskell">(<span style="color: #fce94f;">%</span>) <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">Coordinate</span> <span style="color: #fcaf3e;">-&gt;</span> (<span style="color: #8cc4ff;">GameState</span>, <span style="color: #8cc4ff;">Int</span>)
(<span style="color: #fce94f;">%</span>) inGameState <span style="color: #fcaf3e;">-&gt;</span> cor <span style="color: #fcaf3e;">-&gt;</span> (outGameState, nFlips)
</pre>
</div>

<p>
The <code>q</code> function moves the game state to the next round.
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #e9b96e;">-- | Play and move to next round</span>
<span style="color: #fce94f;">q</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">Coordinate</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">GameState</span>
<span style="color: #fce94f;">q</span> currentGameState <span style="color: #fcaf3e;">-&gt;</span> cor <span style="color: #fcaf3e;">-&gt;</span> nextRoundGameState
</pre>
</div>

<p>
The <code>z</code> function starts the game in the IO monad.
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #e9b96e;">-- | Start game</span>
<span style="color: #fce94f;">z</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Side</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">IO</span> <span style="color: #8cc4ff;">()</span>
<span style="color: #fce94f;">z</span> humanSide (initialBoard,currentSide)
</pre>
</div>

<p>
The <code>e</code> function is the game strategy for the AI:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #e9b96e;">-- | Strategy function!</span>
<span style="color: #fce94f;">e</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">GameState</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">GameState</span>
</pre>
</div>

<p>
It should use the <code>q</code> function to move the game state forward.
</p>

<p>
There are three game strategies attempted during the code jam:
</p>

<ol class="org-ol">
<li>A naive strategy that finds the first possible move.</li>
<li>A greedy strategy that finds the immediate move that flips the most pieces.</li>
<li>A MiniMax strategy that tries to play the game with a few levels of depth with <a href="https://en.wikipedia.org/wiki/Minimax">MiniMax</a> decision rules.</li>
</ol>

<p>
I will enlist the code of (3) here. And because of its minified nature, it looks pretty hideous, I admit:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #fce94f;">g</span> h a<span style="color: #fcaf3e;">=</span>f(<span style="color: #fcaf3e;">\</span>c e<span style="color: #fcaf3e;">-&gt;</span>i e<span style="color: #fcaf3e;">&gt;</span>i c<span style="color: #fcaf3e;">?</span>e<span style="color: #fcaf3e;">$</span>c)(<span style="color: #fcaf3e;">-</span>65<span style="color: #fcaf3e;">*</span>h,(0,0))<span style="color: #fcaf3e;">$</span>
        (<span style="color: #fcaf3e;">\</span>((b,p),d)<span style="color: #fcaf3e;">-&gt;</span>(h<span style="color: #fcaf3e;">*</span>(h<span style="color: #fcaf3e;">*</span>p<span style="color: #fcaf3e;">==</span>0<span style="color: #fcaf3e;">?</span>j a<span style="color: #fcaf3e;">`c`</span>i b<span style="color: #fcaf3e;">$</span>i<span style="color: #fcaf3e;">$</span>g(div h(<span style="color: #fcaf3e;">-</span>2))b),d))<span style="color: #fcaf3e;">&amp;</span>
        ((<span style="color: #8cc4ff;">(,)</span><span style="color: #fcaf3e;">=&lt;&lt;</span>(a<span style="color: #fcaf3e;">%</span>))<span style="color: #fcaf3e;">&amp;</span>k r);
<span style="color: #fce94f;">e</span> a<span style="color: #fcaf3e;">=</span>q a<span style="color: #fcaf3e;">.</span>j<span style="color: #fcaf3e;">$</span>g 4a
</pre>
</div>

<p>
Here <code>g 4a</code> is a recursive function starting with 4, and it oscillates between positive ("max" stage) and negative
("min" stage) and halves at the same time (<code>g -2a</code>, then <code>g 0a</code>). This is a trick to use a single number to represent
the stage and depth limit of the minimax process.
</p>

<p>
The evaluation function is kept simple; the more flips, the better. In a better strategy, certain pieces are worth more
(at the corner or at the side).
</p>
</div>
</div>

<div id="outline-container-orgf767767" class="outline-3">
<h3 id="orgf767767">Code Golfing Tricks</h3>
<div class="outline-text-3" id="text-orgf767767">
</div>
<div id="outline-container-org5c79973" class="outline-4">
<h4 id="org5c79973">Compact Ternary Operator (Prelude)</h4>
<div class="outline-text-4" id="text-org5c79973">
<p>
If you use a lot of <code>if then else</code>, use this <code>test?yes$no</code> to save a lot of spaces:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #b4fa70;">infixr</span> 1<span style="color: #fcaf3e;">?</span>;(b<span style="color: #fcaf3e;">?</span>x)y<span style="color: #fcaf3e;">|</span>b<span style="color: #fcaf3e;">=</span>x<span style="color: #fcaf3e;">|</span>0<span style="color: #fcaf3e;">&lt;</span>3<span style="color: #fcaf3e;">=</span>y;
</pre>
</div>

<p>
If you are not limited to using only "prelude" module, you might also use <code>bool :: a -&gt; a -&gt; Bool -&gt; a</code> in base.
</p>
</div>
</div>

<div id="outline-container-org498f1e7" class="outline-4">
<h4 id="org498f1e7">Shortest Function for "Other Side"</h4>
<div class="outline-text-4" id="text-org498f1e7">
<p>
<code>o=1:2:o</code>, so that <code>o 1=2</code> and <code>o 2=1</code>. Any other output is uninteresting!
</p>

<p>
This is a funny function enabled by Haskell's lazy evaluation semantics.
</p>
</div>
</div>

<div id="outline-container-org6862283" class="outline-4">
<h4 id="org6862283">Shortest Cross Product Function</h4>
<div class="outline-text-4" id="text-org6862283">
<p>
<code>k=(&lt;*&gt;)=&lt;&lt;((,)&lt;$&gt;)</code>, so that:
</p>

<ol class="org-ol">
<li><code>k[-1..1]</code> is for interacting through all 8 directions (<code>[1,1],[1,0],[1,-1],[0,1],[0,-1][-1,-1],[-1,1],[-1,0]</code>), the
9th direction <code>[0,0]</code> is uninteresting and doesn't create trouble fur us.</li>
<li><code>k[0..7]</code> generates all 64 positions on the board for iterating through them.</li>
</ol>

<p>
The alternative would be using twice List applicative; this version saves spaces!
</p>
</div>
</div>

<div id="outline-container-org89b47aa" class="outline-4">
<h4 id="org89b47aa">Make a move</h4>
<div class="outline-text-4" id="text-org89b47aa">
<p>
This bizarre ternary function put a piece "w" at position "i" on the board "b":
</p>

<div class="org-src-container">
<pre class="src src-haskell">(w<span style="color: #fcaf3e;">^</span>i)b<span style="color: #fcaf3e;">=</span>take i b<span style="color: #fcaf3e;">++</span>w<span style="color: #8cc4ff;">:</span>drop (i<span style="color: #fcaf3e;">+</span>1)b;
</pre>
</div>
</div>
</div>

<div id="outline-container-org618689e" class="outline-4">
<h4 id="org618689e">Other Ad-hoc One-Letter Functions</h4>
<div class="outline-text-4" id="text-org618689e">
<p>
More tips about minifying and unminifying techniques can be found at: <a href="https://github.com/haskell-game/tiny-games-hs/issues/52">https://github.com/haskell-game/tiny-games-hs/issues/52</a>
</p>
</div>
</div>
</div>
</div>

<div id="outline-container-orgf1bc1f7" class="outline-2">
<h2 id="orgf1bc1f7">Lol - The Meta Game</h2>
<div class="outline-text-2" id="text-orgf1bc1f7">
<p>
My second submission to the game jam is less serious. In fact, it is a knock-off of the <a href="https://github.com/busyloop/lolcat/">lolcat program</a>! But it is
tightly integrated with the game itself, hence a <b>meta game</b>!
</p>

<p>
The idea of it is straightforward: it pipes the "play" command to colorize its output and add additional text effects
depending on how many "lols" you have inserted in the command line, e.g.:
</p>

<p>
<code>./play lol lol lol lol lol ski</code> would give you a rather trippy ski trip:
</p>


<figure id="org77eb3cc">
<img src="../static/2023-02-27-hs-tiny-games/trippy-ski.png" alt="trippy-ski.png">

</figure>

<p>
The trick of using the applicative list to generate an infinite list of variations:
</p>

<div class="org-src-container">
<pre class="src src-haskell">(<span style="color: #fce94f;">,,</span>)<span style="color: #fcaf3e;">&lt;$&gt;</span>[1<span style="color: #fcaf3e;">..</span>]<span style="color: #fcaf3e;">&lt;*&gt;</span>s[38,48]<span style="color: #fcaf3e;">&lt;*&gt;</span>s[0,4,5]
</pre>
</div>

<p>
The first parameter is the frequency of the rainbow color effects; the second one is the anis-terminal color code choice for
foreground or background; the third one is additional text effects such as underlined texts and blinking texts.
</p>
</div>
</div>

<div id="outline-container-org1d71abb" class="outline-2">
<h2 id="org1d71abb">Conclusion</h2>
<div class="outline-text-2" id="text-org1d71abb">
<p>
I have enjoyed the journey, learned and jammed with various Haskell syntaxes for code golfing. Comparing to
<a href="https://perlgolf.sourceforge.net/">perl golf</a> in the old days, code golfing in Haskell is a joy: if it type-checks, it usually works!
</p>

<p>
And I would like to thank the organizers, the participants, and all the fine folks at #haskell-game.
</p>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-haskell.html">haskell</a> <a href="http://miaozc.me/tag-game.html">game</a> </div>
]]></description>
  <category><![CDATA[haskell]]></category>
  <category><![CDATA[game]]></category>
  <link>http://miaozc.me/2023-02-27-hs-tiny-games.html</link>
  <guid>http://miaozc.me/2023-02-27-hs-tiny-games.html</guid>
  <pubDate>Tue, 28 Feb 2023 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Reactive Exchanges - SLAMM dunk with Superfluid]]></title>
  <description><![CDATA[

<div id="outline-container-orga828ddc" class="outline-2">
<h2 id="orga828ddc">Introduction</h2>
<div class="outline-text-2" id="text-orga828ddc">
<p>
<i>Superfluid protocol</i> enables money to move between entities continuously in time with no transaction. It is a new
paradigm of how the money payment system works. Using this innovative building block, one can build novel applications
for payroll, subscriptions, vesting, streaming AMMs, gaming, trade finance, rentals, and NFTs. <a href="https://docs.superfluid.finance/">Click here to read more
what is Superfluid</a>.
</p>

<p>
Though modeling a problem domain explicitly with time is not a novel concept. In fact, <a href="https://en.wikipedia.org/wiki/Functional_reactive_programming">functional reactive programming</a>
(FRP) that was formulated in a ICFP 97 paper<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> demonstrated that we can model animations elegantly and efficiently
using continuous time. More than 20 years later, it was Superfluid, the first one that successfully connected the dots
between FRP and the domain of money payment system, and has made it available on more than 6 EVM (Ethereum Virtual
Machine) chains<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.
</p>

<p>
In this article, we focus on one of its novel applications: different designs of exchanges that can facilitate swaps
continuously in time<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. By now, you should understand why I shall name them "Reactive Exchanges." Reactive exchanges
are types of exchanges modeled with functional reactive programming.
</p>

<p>
The article expects you to be familiar with the trading terminologies and related innovations on decentralized
ledgers. <a href="https://www.axo.trade/whitepaper.pdf">Axo trade whitepaper</a><sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>, for instance, provides an excellent overview of this domain. Additionally, it would
be best if you had an in-depth overview of what is Superfluid is and how it works<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.
</p>
</div>
</div>

<div id="outline-container-org67fdbbf" class="outline-2">
<h2 id="org67fdbbf">Different Reactiveness</h2>
<div class="outline-text-2" id="text-org67fdbbf">
<p>
Throughout the article, we separate the "reactiveness" of an exchange into three primary functions:
</p>

<ul class="org-ul">
<li><b>Contribution</b>: does the input asset enter the exchange continuously in time?</li>
<li><b>Swap</b>: does swap between the input and assets happen continuously in time?</li>
<li><b>Distribution</b>: is output asset distributed continuously in time?</li>
</ul>

<p>
At the end of the article, we will then compare different designs using this classification.
</p>
</div>
</div>

<div id="outline-container-org50a7313" class="outline-2">
<h2 id="org50a7313">Pseudo Reactive Exchange</h2>
<div class="outline-text-2" id="text-org50a7313">
<p>
The first attempt at having reactive exchange is making only the contribution continuous in time. The actual swaps are
done through an external DEX (decentralized exchange), and distribution of the swap output is done through Superfluid
IDA<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>, both happen periodically and are triggered by keepers ("cronjob at scale").
</p>

<p>
Let's call this "pseudo reactive exchange" since the actual swaps do not continuously in time. Here is a visualization
of such exchange:
</p>


<figure id="orgdc3725e">
<img src="../static/2023-01-27-reactive-exchanges/pseudo-reactive-exchange.png" alt="pseudo-reactive-exchange.png">

</figure>

<p>
An example of such exchanges that is in production is <a href="https://github.com/Ricochet-Exchange/ricochet-protocol">Ricochet Exchange</a>, an original and earliest example of how to
build an unique exchange using Superfluid. It has been live for over an year, and provides an efficient way for anyone
to DCA (dollar cost average)<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup> invest into on-chain assets.
</p>
</div>
</div>

<div id="outline-container-org7a53c77" class="outline-2">
<h2 id="org7a53c77">Reactive Constant Function Market Maker (R-CFMM) Exchange</h2>
<div class="outline-text-2" id="text-org7a53c77">
<p>
CFMM (Constant Function Market Maker) was the first class of AMM (Automatic Market Maker) applied to real-world
financial markets<sup><a id="fnr.4.100" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>. In this article, we look into making one of the earliest and simplest versions of CFMM,
Constant Liquidity Product (CLP) used in Uniswap v1 and v2 <sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup> <sup>, </sup><sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>, reactive.
</p>

<p>
To solve the equations required to make the CLP reactive, I used <a href="https://wiki.python.org/moin/SageMath">the python binding</a> of the <a href="https://www.sagemath.org/">SageMath framework</a>, a free
open-source mathematics software system licensed under the GPL:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #b4fa70;">from</span> sage.<span style="color: #e090d7;">all</span> <span style="color: #b4fa70;">import</span> var, assume, function, solve

<span style="color: #73d216;"># </span><span style="color: #73d216;">let's define a handful of symbols</span>
<span style="color: #fcaf3e;">L_a</span>, <span style="color: #fcaf3e;">L_b</span>, <span style="color: #fcaf3e;">T</span>, <span style="color: #fcaf3e;">r</span>, <span style="color: #fcaf3e;">r_a</span>, <span style="color: #fcaf3e;">r_b</span>, <span style="color: #fcaf3e;">t_0</span>, <span style="color: #fcaf3e;">t</span> = var(<span style="color: #e9b96e;">"L_a"</span>, <span style="color: #e9b96e;">"L_b"</span>, <span style="color: #e9b96e;">"T"</span>, <span style="color: #e9b96e;">"r"</span>, <span style="color: #e9b96e;">"r_a"</span>, <span style="color: #e9b96e;">"r_b"</span>, <span style="color: #e9b96e;">"t_0"</span>, <span style="color: #e9b96e;">"t"</span>)
assume(t &gt;= t_0)
</pre>
</div>

<p>
First, let's define CLP:
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #b4fa70;">from</span> sage.<span style="color: #e090d7;">all</span> <span style="color: #b4fa70;">import</span> var, assume, function, solve

<span style="color: #b4fa70;">def</span> <span style="color: #fce94f;">CLP</span>(x, y, x_prime, y_prime):
    <span style="color: #e9b96e;">"""Constant Liquidity Product Swap"""</span>
    <span style="color: #b4fa70;">return</span> x * y == x_prime * y_prime
assume(t &gt;= t_0)
</pre>
</div>

<p>
Secondly, let's try to use sage to solve the price function for selling asset A (sell amount \(a_\Delta\)) for asset B (get
amount \(b_\Delta\)):
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #b4fa70;">def</span> <span style="color: #fce94f;">solve_clp_a4b</span>():
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"# Solve CLP equation for selling A for B instantly\n"</span>)
    <span style="color: #fcaf3e;">v_a</span> = var(<span style="color: #e9b96e;">"a_&#916;"</span>)
    <span style="color: #fcaf3e;">v_b</span> = var(<span style="color: #e9b96e;">"b_&#916;"</span>)
    <span style="color: #fcaf3e;">clp</span> = CLP(
        L_a,
        L_b,
        L_a + v_a,
        L_b + v_b
    )
    <span style="color: #fcaf3e;">sols</span> = solve(clp, v_b)
    <span style="color: #b4fa70;">assert</span>(<span style="color: #e090d7;">len</span>(sols) == 1)
    <span style="color: #e090d7;">print</span>(sols[0])
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"\n"</span>)
</pre>
</div>

<p>
Sage spits out the well-known equation as expected:
</p>

<p>
\[L_{b\Delta} = \frac{L_b * a_\Delta}{L_a + a_\Delta}\]
</p>

<p>
Now it comes to how to make it reactive; two functions of time need to be solved: one for asset A and another for asset B. There
are not enough free variables to solve two equations, but we do know that these two equations should be elated to each
other. Here was the stroke of insight, and a magic variable "q" was introduced (and please don't ask more):
</p>

<div class="org-src-container">
<pre class="src src-python"><span style="color: #b4fa70;">def</span> <span style="color: #fce94f;">solve_rclp_rtb_bidir</span>():
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"# Solve Reactive CLP rtb_bidir equation\n"</span>)
    <span style="color: #fcaf3e;">cf_a</span> = r_a * (t - t_0)
    <span style="color: #fcaf3e;">cf_b</span> = r_b * (t - t_0)

    <span style="color: #fcaf3e;">q</span> = var(<span style="color: #e9b96e;">"q"</span>)
    <span style="color: #fcaf3e;">clp</span> = CLP(
        L_a,
        L_b,
        L_a + cf_a + q * cf_b,
        L_b + cf_b + 1/q * cf_a
    )
    <span style="color: #fcaf3e;">sols</span> = solve(clp, q)
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"L_{flowswap_a} ="</span>, (1/q * cf_a).subs(sols[0]))
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"L_{flowswap_b} ="</span>, (q * cf_b).subs(sols[0]))
    <span style="color: #e090d7;">print</span>(<span style="color: #e9b96e;">"\n"</span>)
</pre>
</div>

<p>
Gratefully, Sage spits out the magic formula we are looking for. Let's call it <i>flowswap</i> formula:
</p>

<ol class="org-ol">
<li>\[L_{flowswap_a} = \frac{-(r_b * t_\Delta - L_b) * r_a * t_\Delta}{r_a * t_\Delta + L_a}\]</li>
<li>\[L_{flowswap_b} = \frac{-(r_a * t_\Delta - L_a) * r_b * t_\Delta}{r_b * t_\Delta + L_b}\]</li>
</ol>

<p>
Here is an illustration of the global view of a reactive CLP exchange:
</p>


<figure id="org240c5fc">
<img src="../static/2023-01-27-reactive-exchanges/R-CLP-global-view.png" alt="R-CLP-global-view.png">

</figure>

<p>
Another way of seeing it is from how swaps look after "reactification" on the chart of the CLP formula:
</p>


<figure id="org50cc5a7">
<img src="../static/2023-01-27-reactive-exchanges/R-CLP-formula-view.png" alt="R-CLP-formula-view.png">

</figure>

<p>
To make the exchange work for more participants, we again need to use IDA from Superfluid money, where the proportion of
the flowswap output is determined by the market takers' continuous flow contributions.
</p>

<p>
Regarding "reactiveness, " market takers always "flowswap" constant flows for another non-linear flow of money, and they
are both continuous in time and reactive.  However, Superfluid money cannot distribute money through arbitrary formulas;
that's why the distribution cannot be reactive unless a bespoke flowswap primitive is a built-in feature of the money.
</p>

<p>
You can find the work-in-progress prototype of this in the <a href="https://github.com/hellwolf/trex-monorepo/">T-REX (Toy Reactive Exchange) Monorepo</a>. If you are interested
in making this closer to production, join Superfluid's <a href="http://superfluid.finance/wavepool">wave pool program</a>.
</p>
</div>
</div>

<div id="outline-container-org77ca55d" class="outline-2">
<h2 id="org77ca55d">Zero-Intermediate-Liquidity Market Maker (ZILMM) Exchange</h2>
<div class="outline-text-2" id="text-org77ca55d">
<p>
Another fascinating and unique variation of AMM enabled by Superfluid money is a market maker that requires zero
intermediate liquidity, where liquidity goes from LPs to traders directly as constant flows. As a result, a trade-off
(or feature) is that such exchanges may not easily facilitate instant swaps.
</p>

<p>
I shall call such exchange <i>ZILMM: Zero-Intermediate-Liquidity Market Makers</i>. The pioneer of such design is
Superfluid's ecosystem project <a href="https://aqueductfinance.vercel.app/">Aqueduct</a>. We will leave the reader to discover more about the project on their own, and
we will only include an illustration from them to get a taste of it:
</p>

<ol class="org-ol">
<li><p>
At market liquidity "equilibrium"
</p>

<figure id="org6852811">
<img src="../static/2023-01-27-reactive-exchanges/aqueduct-1.png" alt="aqueduct-1.png">

</figure></li>

<li><p>
Traders tilting the "equilibrium"
</p>

<figure id="orgd50d91a">
<img src="../static/2023-01-27-reactive-exchanges/aqueduct-2.png" alt="aqueduct-2.png">

</figure></li>
</ol>

<p>
Since all flows involved are constant flows, it should not be a surprise that this design of the reactive exchange ticks
all the reactiveness boxes!
</p>
</div>
</div>

<div id="outline-container-org44ee28c" class="outline-2">
<h2 id="org44ee28c">Conclusion</h2>
<div class="outline-text-2" id="text-org44ee28c">
<p>
Let us review the "reactiveness" of all three Superfluid money enabled market maker designs:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Exchange Type</th>
<th scope="col" class="org-left">Contribution</th>
<th scope="col" class="org-left">Swap</th>
<th scope="col" class="org-left">Distribution</th>
<th scope="col" class="org-left">Known</th>
</tr>

<tr>
<th scope="col" class="org-left">/ Reactiveness</th>
<th scope="col" class="org-left">Reactiveness</th>
<th scope="col" class="org-left">Reactiveness</th>
<th scope="col" class="org-left">Reactiveness</th>
<th scope="col" class="org-left">Projects</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Pseudo</td>
<td class="org-left">Yes</td>
<td class="org-left">No</td>
<td class="org-left">No</td>
<td class="org-left">Ricochet</td>
</tr>

<tr>
<td class="org-left">R-CFMM</td>
<td class="org-left">Yes</td>
<td class="org-left">Yes</td>
<td class="org-left">Maybe(a)</td>
<td class="org-left">T-Rex</td>
</tr>

<tr>
<td class="org-left">ZILMM</td>
<td class="org-left">Yes</td>
<td class="org-left">Yes</td>
<td class="org-left">Yes</td>
<td class="org-left">Aqueduct</td>
</tr>
</tbody>
</table>

<p>
Note:
</p>

<p>
a) Distribution with the complex formula required by R-CFMM is viable but not necessarily desirable.
</p>

<p>
Each design has its pros and cons, and it is beyond the purpose of this article to dive into them.
</p>

<p>
However, Superfluid money demonstrably enlarged the design surface of AMM. I believe it should be a safe bet that
innovations enabled by Superfluid money are not restricted to AMM and other types of financial contracts such as
options, futures, interest rate swaps, etc., should have unique Superfluid money enabled designs too.
</p>

<p>
While reactive exchanges accurately reflects the underlying technology, a more playful term could be <i>SLAMM (Streaming
Liquidity Automatic Market Makers)</i>. I will end the article with a slogan:
</p>

<p>
<b><b>Let's SLAMM dunk it with Superfluid.</b></b>
</p>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Elliott, Conal; Hudak, Paul. <a href="http://conal.net/papers/icfp97/">"Functional Reactive Animation"</a>. Functional Reactive Animation. ICFP ’97. Retrieve
14 July 2018.
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
All deployments of Superfluid protocol can be accessed through <a href="https://app.superfluid.finance/">Superfluid app</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
It should not to be confused with the existing financial term <a href="https://www.investopedia.com/terms/c/continuoustrading.asp">continuous trading</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://www.axo.trade/whitepaper.pdf">https://www.axo.trade/whitepaper.pdf</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview">https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview/super-agreements/instant-distribution-agreement-ida">https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview/super-agreements/instant-distribution-agreement-ida</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://www.investopedia.com/terms/d/dollarcostaveraging.asp">https://www.investopedia.com/terms/d/dollarcostaveraging.asp</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Uniswap v1 Protocol Hayden Adams et al. Novembrer 2018. URL:
<a href="https://docs.uniswap.org/protocol/V1/introduction">https://docs.uniswap.org/protocol/V1/introduction</a>. Accessed on 15/10/2021.
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Uniswap v2 Core Hayden Adams et al. March 2020. URL: <a href="https://uniswap.org/">https://uniswap.org/</a> whitepaper.pdf. Accessed on 15/10/2021.
</p></div></div>


</div>
</div><div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-superfluid.html">superfluid</a> <a href="http://miaozc.me/tag-defi.html">defi</a> <a href="http://miaozc.me/tag-semantic money.html">semantic money</a> </div>
]]></description>
  <category><![CDATA[superfluid]]></category>
  <category><![CDATA[defi]]></category>
  <category><![CDATA[semantic money]]></category>
  <link>http://miaozc.me/2023-01-27-reactive-exchanges.html</link>
  <guid>http://miaozc.me/2023-01-27-reactive-exchanges.html</guid>
  <pubDate>Fri, 27 Jan 2023 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Stop Writing Instructions and Use Nix]]></title>
  <description><![CDATA[
<p>
If you are still writing development environment setup instruction for your project, time to use <a href="https://nixos.org/">Nix</a>!
</p>

<p>
With Nix:
</p>

<ul class="org-ul">
<li>Any developers and CI systems can have reproducible builds and deployments regardless of the platforms (any Linux,
MacOS or even Windows using WSL2) they use, thanks to <a href="https://nixos.org/download.html">Nix: the package manager</a>.</li>
<li>You can access a large collection of packages (over 80,000 as of today) maintained by thousands of contributors,
thanks to <a href="https://github.com/NixOS/nixpkgs">Nixpkgs</a>.</li>
<li>There is even a dedicated Linux distribution using Nixpkgs: NixOS.</li>
</ul>

<p>
More over, you should use <a href="https://nixos.wiki/wiki/Flakes">Nix Flakes</a>. This upcoming new feature of Nix will power-up your build environment with a lock
file that is similar to your <code>yarn.lock/package-json.lock/Cargo.lock/etc.</code>, but for all types of projects.
</p>

<p>
It is a experience changer for many engineering organizations, e.g. at <a href="https://shopify.engineering/what-is-nix">shopify</a>.
</p>

<p>
Personally, each time I want to contribute to an open source project, the first thing I would do is to add a <code>flake.nix</code>
to their project and decorate their CONTRIBUTING.md with a much more concise <i>development environment setup using Nix</i>
section.
</p>

<p>
For more reasons why you should use Nix, I recommend these readings:
</p>

<ul class="org-ul">
<li><a href="https://serokell.io/blog/what-is-nix">Serokell: What Is Nix and Why You Should Use It</a></li>
<li><a href="https://nixos.org/guides/nix-pills/why-you-should-give-it-a-try.html">Nix Pills 1: Why You Should Give it a Try</a></li>
</ul>

<p>
After you are "nix pilled" inevitably, Nix official website has a pretty decent collection of <a href="https://nixos.org/learn.html">learning materials</a> from
getting started to comprehensive references.
</p>

<p>
There are also some good materials done by the community:
</p>

<ul class="org-ul">
<li><a href="https://book.divnix.com/ch00-00-the-nix-package-manager.html">The Nix Package Manager</a></li>
<li><a href="https://nix.dev/tutorials">Nix Tutorials</a></li>
<li><a href="https://www.haskellforall.com/2022/08/stop-calling-everything-nix.html">Stop calling everything "Nix"</a></li>
</ul>

<p>
Further more, Nix Flakes have also its own interesting materials to read:
</p>

<ul class="org-ul">
<li><a href="https://serokell.io/blog/practical-nix-flakes">Serokell: Practical Nix Flakes</a></li>
<li><a href="https://www.tweag.io/blog/2020-05-25-flakes/">TWEAG: Nix Flakes, by Eelco Dolstra</a>. (Eelco Dolstra wrote <a href="https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf">the paper about Nix</a> in 2004)</li>
</ul>

<p>
Happy Nix!
</p>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-nix.html">nix</a> <a href="http://miaozc.me/tag- .html"> </a> <a href="http://miaozc.me/tag-devops.html">devops</a> </div>
]]></description>
  <category><![CDATA[nix]]></category>
  <category><![CDATA[ ]]></category>
  <category><![CDATA[devops]]></category>
  <link>http://miaozc.me/2022-12-11-stop-writing-instructions-and-use-nix.html</link>
  <guid>http://miaozc.me/2022-12-11-stop-writing-instructions-and-use-nix.html</guid>
  <pubDate>Sun, 11 Dec 2022 21:17:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Muh L1s (Layer 1 Blockchains)]]></title>
  <description><![CDATA[
<p>
In the interest of researching the <i>development activeness</i> and <i>stage of development</i> of various layer 1 projects, I
did a quick analysis of their main github repo for:
</p>

<ol class="org-ol">
<li>pull requests counts for the one month,</li>
<li>commit activities since inception,</li>
<li>ethos and narrative extracted from their communication materials,</li>
<li>and cloc (count lines of code) stats.</li>
</ol>

<p>
Warning: the method is extremely rudimentary and overly simplified, it is meant to be used as a starting point for your
own research.
</p>

<div id="outline-container-org5f475ed" class="outline-2">
<h2 id="org5f475ed">GETH (go-ethereum) for Comparison</h2>
<div class="outline-text-2" id="text-org5f475ed">
<ul class="org-ul">
<li>Ethereum Ethos: "infinite garden" (cit. <a href="https://ethereum.foundation/">https://ethereum.foundation/</a>)</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/ethereum/go-ethereum">https://github.com/ethereum/go-ethereum</a></li>
<li><img src="../static/2022-10-28-muh-l1s/geth-github-pulse.png" alt="geth-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/geth-github-contributors.png" alt="geth-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
JSON                            176              9              0         281664
Go                             1201          32231          56848         248455
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org86d7152" class="outline-2">
<h2 id="org86d7152">Solana</h2>
<div class="outline-text-2" id="text-org86d7152">
<ul class="org-ul">
<li>Ethos: "Low cost, fast, forever" (cit. <a href="https://solana.com/">https://solana.com/</a>)</li>
<li>GitHub stats:
<ul class="org-ul">
<li><img src="../static/2022-10-28-muh-l1s/solana-github-pulse.png" alt="solana-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/solana-github-contributors.png" alt="solana-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Rust                            963          36355          39319         373352
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orgb7dd1b6" class="outline-2">
<h2 id="orgb7dd1b6">Cardano</h2>
<div class="outline-text-2" id="text-orgb7dd1b6">
<ul class="org-ul">
<li>Ethos: "A decentralized blockchain based on peer-reviewed research and highly secure Haskell coding language."</li>
<li>Smart contract languages: Plutus, Haskell.</li>
<li>EVM compatibility: Cardano Hydra (Layer-2)</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/input-output-hk/cardano-node/">https://github.com/input-output-hk/cardano-node/</a></li>
<li><img src="../static/2022-10-28-muh-l1s/cardano-github-pulse.png" alt="cardano-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/cardano-github-contributors.png" alt="cardano-github-contributors.png"></li>
</ul></li>
<li>cloc:</li>
</ul>
<div class="org-src-container">
<pre class="src src-txt">--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Haskell                         550          14268           7874          89455
</pre>
</div>
</div>
</div>
<div id="outline-container-orgedfeeae" class="outline-2">
<h2 id="orgedfeeae">Near Protocol</h2>
<div class="outline-text-2" id="text-orgedfeeae">
<ul class="org-ul">
<li>Ethos: "All-purpose platform. Community-operated cloud. Sharding, doomslug consensus. PoS."</li>
<li>Smart contract languages: Rust, JS SDKs.</li>
<li>EVM compatibility: Aurora Chain.</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/near/nearcore/">https://github.com/near/nearcore/</a></li>
<li><img src="../static/2022-10-28-muh-l1s/nearcore-github-pulse.png" alt="nearcore-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/nearcore-github-contributors.png" alt="nearcore-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Rust                           605          16001          19672         151573
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org5fa48f6" class="outline-2">
<h2 id="org5fa48f6">Polkadot</h2>
<div class="outline-text-2" id="text-org5fa48f6">
<ul class="org-ul">
<li>Ethos: "From Gavin Woods, spokesman of Real Web3 /jk. Multichain vision for Web3."</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/paritytech/polkadot/">https://github.com/paritytech/polkadot/</a></li>
<li><img src="../static/2022-10-28-muh-l1s/polkadot-github-pulse.png" alt="polkadot-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/polkadot-github-contributors.png" alt="polkadot-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Rust                            648          24372          38707         148408
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org1c6f648" class="outline-2">
<h2 id="org1c6f648">Algorand</h2>
<div class="outline-text-2" id="text-org1c6f648">
<ul class="org-ul">
<li>Ethos: "MIT. Silvio Micali. Transparency."</li>
<li>Smart contract languages: Python/Reach</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/algorand/go-algorand">https://github.com/algorand/go-algorand</a></li>
<li><img src="../static/2022-10-28-muh-l1s/algorand-github-pulse.png" alt="algorand-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/algorand-github-contributors.png" alt="algorand-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">github.com/AlDanial/cloc v 1.92  T=1.93 s (1197.2 files/s, 414461.9 lines/s)
---------------------------------------------------------------------------------------
Language                             files          blank        comment           code
---------------------------------------------------------------------------------------
JSON                                   243             16              0         308578
Go                                    1031          41548          44221         265630
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-orgafd2a86" class="outline-2">
<h2 id="orgafd2a86">Avalanche</h2>
<div class="outline-text-2" id="text-orgafd2a86">
<ul class="org-ul">
<li>Ethos: "Unified global market. Legal compliance. Plug into one universal network. Avalanche consensus.
Customizability".</li>
<li>EVM compatibility: C-Chain EVM.</li>
<li>GitHub stats:
<ul class="org-ul">
<li><a href="https://github.com/ava-labs/avalanchego">https://github.com/ava-labs/avalanchego</a></li>
<li><img src="../static/2022-10-28-muh-l1s/avalanchego-github-pulse.png" alt="avalanchego-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/avalanchego-github-contributors.png" alt="avalanchego-github-contributors.png"></li>
<li><a href="https://github.com/ava-labs/subnet-evm">https://github.com/ava-labs/subnet-evm</a></li>
<li><img src="../static/2022-10-28-muh-l1s/avalancherosetta-github-pulse.png" alt="avalancherosetta-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/avalancherosetta-github-contributors.png" alt="avalancherosetta-github-contributors.png"></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Go                            1253          33614          19560         192769
JSON                             9              2              0         176355
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgf6fc50c" class="outline-2">
<h2 id="orgf6fc50c">Kadena</h2>
<div class="outline-text-2" id="text-orgf6fc50c">
<ul class="org-ul">
<li>Ethos: "Real business use. Speed, Scalable, Security. Private blockchain first, now democratizing. ChainWeb".</li>
<li><p>
Github stats:
</p>
<ul class="org-ul">
<li><img src="../static/2022-10-28-muh-l1s/kadena-github-pulse.png" alt="kadena-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/kadena-github-contributors.png" alt="kadena-github-contributors.png"></li>
</ul>
<ul class="org-ul">
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Haskell                        268          10599          12534          52340
</pre>
</div></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-orgd231764" class="outline-2">
<h2 id="orgd231764">Fuel VM</h2>
<div class="outline-text-2" id="text-orgd231764">
<ul class="org-ul">
<li>GitHub stats:
<ul class="org-ul">
<li><img src="../static/2022-10-28-muh-l1s/fuel-github-pulse.png" alt="fuel-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/fuel-github-contributors.png" alt="fuel-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Rust                           217           4139           2005          32650
</pre>
</div></li>
</ul>
</div>
</div>
<div id="outline-container-org87f5774" class="outline-2">
<h2 id="org87f5774">Flow</h2>
<div class="outline-text-2" id="text-org87f5774">
<ul class="org-ul">
<li>Cadence: "Cadence is the resource-oriented programming language for developing smart contracts on the Flow
Blockchain."</li>
<li>Github stats:
<ul class="org-ul">
<li><a href="https://github.com/onflow/flow-go.git">https://github.com/onflow/flow-go.git</a></li>
<li><img src="../static/2022-10-28-muh-l1s/flow-github-pulse.png" alt="flow-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/flow-github-contributors.png" alt="flow-github-contributors.png"></li>
</ul></li>
<li><p>
cloc:
</p>
<div class="org-src-container">
<pre class="src src-txt">-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Go                            2234          59473          43399         259290
</pre>
</div></li>
</ul>
</div>
</div>

<div id="outline-container-orgcefa247" class="outline-2">
<h2 id="orgcefa247">Sui</h2>
<div class="outline-text-2" id="text-orgcefa247">
<ul class="org-ul">
<li>Ethos: " Sui, a next-generation smart contract platform with high throughput, low latency, and an asset-oriented
programming model powered by the Move programming language."</li>
<li>GitHub stats:
<ul class="org-ul">
<li><img src="../static/2022-10-28-muh-l1s/sui-github-pulse.png" alt="sui-github-pulse.png"></li>
<li><img src="../static/2022-10-28-muh-l1s/sui-github-contributors.png" alt="sui-github-contributors.png"></li>
</ul></li>
<li>cloc:</li>
</ul>
<div class="org-src-container">
<pre class="src src-txt">--------------------------------------------------------------------------------
Language                      files          blank        comment           code
--------------------------------------------------------------------------------
Rust                            427          13872          12224         105772
</pre>
</div>
</div>
</div>
<div id="outline-container-org6edba58" class="outline-2">
<h2 id="org6edba58">Others</h2>
<div class="outline-text-2" id="text-org6edba58">
<p>
I am running out of time and ignoring these for now&#x2026;
</p>

<ul class="org-ul">
<li>Quant (QNT)
<ul class="org-ul">
<li>Ethos: "The project is built as an operating system distributed ledger technology — and Overledger Network — for
connecting different blockchain networks."</li>
</ul></li>
<li>Tezos</li>
<li>Aptos</li>
<li>VeChain</li>
<li>Hedera</li>
</ul>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-blockchain.html">blockchain</a> </div>
]]></description>
  <category><![CDATA[blockchain]]></category>
  <link>http://miaozc.me/2022-10-28-muh-l1s.html</link>
  <guid>http://miaozc.me/2022-10-28-muh-l1s.html</guid>
  <pubDate>Fri, 28 Oct 2022 14:33:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[First Yellowpaper About Superfluid Protocol, the Beginning of Something Greater]]></title>
  <description><![CDATA[

<div id="outline-container-orgf93c2aa" class="outline-2">
<h2 id="orgf93c2aa">Where Are We</h2>
<div class="outline-text-2" id="text-orgf93c2aa">
<p>
We, builders of the Superfluid Protocol, have come a long way.
</p>

<p>
<a href="https://github.com/superfluid-finance/protocol-monorepo/">EVMv1</a> of Superfluid Protocol has been live on Polygon (then Matic Network) since a year and a half ago (<a href="https://polygonscan.com/tx/0xa9868d7788a36e1968326ef51fef7d18ed93fba212803b7a365ccbc588abb659">May 2021</a>). Since
then, we have been live in <a href="https://docs.superfluid.finance/superfluid/developers/networks">5 more networks</a>, including Gnosis Chain (then xDAI Chain), Optimism, Arbitrum, Avalanche, and
BNB Chain.
</p>

<p>
The significant features of the protocol are:
</p>

<ul class="org-ul">
<li><a href="https://eips.ethereum.org/EIPS/eip-20">ERC-20</a>/<a href="https://eips.ethereum.org/EIPS/eip-777">ERC-777</a> (1to1 instant payment primitive) compatible <a href="https://docs.superfluid.finance/superfluid/developers/super-tokens">super token</a>,</li>
<li><a href="https://docs.superfluid.finance/superfluid/developers/constant-flow-agreement-cfa">1to1 constant flow payment primitive</a>,</li>
<li><a href="https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview/super-agreements/instant-distribution-agreement-ida">1toN instant distribution payment primitive</a>,</li>
<li>a <a href="https://docs.superfluid.finance/superfluid/protocol-overview/in-depth-overview/super-agreements/constant-flow-agreement-cfa#solvency-and-sentinels">buffer-based solvency framework</a>,</li>
<li>a multi-roles-and-continuous auction system for it called "<a href="https://docs.superfluid.finance/superfluid/sentinels/liquidations-and-toga">TOGA</a>,"</li>
<li>a callbacks-based compositional framework called "<a href="https://docs.superfluid.finance/superfluid/developers/super-apps">Super Apps</a>,"</li>
<li>a <a href="https://docs.superfluid.finance/superfluid/developers/batch-calls">super-token-native batch call</a> before it was cool.</li>
</ul>

<p>
We have had many new product announcements, community project launches, and hackathon winners — all of which you can
read about on the <a href="https://medium.com/superfluid-blog">Superfluid medium blog</a>.
</p>

<p>
We are fully committed to building products that expand the reach and adoption of the EVMv1 of Superfluid Protocol. For
this, we invite everyone to participate in our <a href="https://superfluid.canny.io/">roadmap public board</a>, helping us shape them together.
</p>
</div>
</div>

<div id="outline-container-orgd8843e1" class="outline-2">
<h2 id="orgd8843e1">Something Greater</h2>
<div class="outline-text-2" id="text-orgd8843e1">
<p>
First of all, the reason why we are here is that there is a central observation guiding us; consequently, we are
motivated by a strong belief in how payment systems can become:
</p>

<blockquote>
<p>
Payment systems in the information age are still modeled after their analog predecessors. We can modernize it.
</p>
</blockquote>

<p>
Meanwhile, we are planning for an extended period of focused building for this cycle. Namely, we want to expand the
depth and breadth of the idea behind the Superfluid Protocol.
</p>
</div>
</div>

<div id="outline-container-orge6aacc3" class="outline-2">
<h2 id="orge6aacc3">More Depth</h2>
<div class="outline-text-2" id="text-orge6aacc3">
</div>
<div id="outline-container-orge63236f" class="outline-3">
<h3 id="orge63236f">Yellowpapers &amp; Stronger Foundation</h3>
<div class="outline-text-3" id="text-orge63236f">
<p>
As the first step to expand the depth of the protocol, I am happy to announce that the first yellowpaper of its series
about the most fundamental part of the Superfluid idea is now available: "<a href="https://semantic.money/assets/semantic-money-yellowpaper1.pdf">Denotational Semantics of General Payment
Primitives, and Its Payment System</a>."
</p>

<blockquote>
<p>
The paper first explores the foundation of modern payment systems, which consists of a money distribution model, payment
primitives, payment execution systems of financial contracts, and different forms of money mediums. Then the paper uses
<i>denotational semantics</i> to formally define <i>payment primitives for modern payment systems</i>. Lastly, this paper also
includes an overview of the Superfluid Protocol, a reference implementation of the payment primitives, and its payment
system.
</p>
</blockquote>

<p>
Here are some of the topics future yellowpapers will explore:
</p>

<ul class="org-ul">
<li>Composing payment primitives of modern payment systems.</li>
<li>A deterministic buffer-less modern payment execution environment.</li>
<li>A note (EUTXO) based modern payment execution environment.</li>
</ul>

<p>
These are some cross-cutting concerns of modern payment systems; they form a stronger foundation to build future
Superfluid Protocol implementations.
</p>
</div>
</div>

<div id="outline-container-orgb0d2360" class="outline-3">
<h3 id="orgb0d2360">Next Generation Architecture</h3>
<div class="outline-text-3" id="text-orgb0d2360">
<p>
Here is a sneak peek into how that next generation Superfluid Protocol implementation could look like:
</p>


<figure id="org6a32d8e">
<img src="../static/2022-10-20-first-yellowpaper-about-superfluid-protocol/superfluid-protocol-ng.png" alt="superfluid-protocol-ng.png">

</figure>
</div>

<div id="outline-container-org0f4e8ee" class="outline-4">
<h4 id="org0f4e8ee">Execution-Layer Agnostic</h4>
<div class="outline-text-4" id="text-org0f4e8ee">
<p>
The architecture is deliberately execution-layer agnostic to prepare for a many-chains world.
</p>

<p>
That means deferring the decisions related to the specificity of the execution layer towards as much edge as possible,
such as "dev experience overlay," "data availability," etc.
</p>
</div>
</div>

<div id="outline-container-orge6b0ca6" class="outline-4">
<h4 id="orge6b0ca6">Functional Core &amp; Data Availability</h4>
<div class="outline-text-4" id="text-orge6b0ca6">
<p>
A <i>functional core</i> means that we apply the functional programming style to the core part of the protocol, namely (a)
using denotational semantics to define payment primitives, (b) pushing data availability out of the core, (c) and
composing payment primitives through combinators.
</p>

<p>
The advantages of such architecture are that:
</p>

<ul class="org-ul">
<li>It ensures we can better reason the system's security,</li>
<li>abstracting data availability so that we can try new methods such as gas-optimizing data serializations, ad-hoc merkle
tree data rollups, ZK Proofs, FHE (Fully Homomorphic Encryption), etc.,</li>
<li>thinking in combinators enables powerful compositionality.</li>
</ul>
</div>
</div>

<div id="outline-container-orgbce6bb9" class="outline-4">
<h4 id="orgbce6bb9">Overlay &amp; Tooling for Dev Experience</h4>
<div class="outline-text-4" id="text-orgbce6bb9">
<p>
From our experience in EVMv1, a distinct separation between core and peripherals (including dev experience overlay)
should unshackle creativity in token/note interface design.
</p>

<p>
In the off-chain world, data indexers and SDKs are the critical pieces to unlock the complete development experience for the dapp
developers.
</p>
</div>
</div>

<div id="outline-container-org621e8ae" class="outline-4">
<h4 id="org621e8ae">Super Apps Power-Ups</h4>
<div class="outline-text-4" id="text-org621e8ae">
<p>
Super Apps will also get power-ups from the more sound core and the better dev experience overlay, so developers should
expect to build safer Super Apps easier.
</p>
</div>
</div>

<div id="outline-container-org8d7d1bb" class="outline-4">
<h4 id="org8d7d1bb">Automation</h4>
<div class="outline-text-4" id="text-org8d7d1bb">
<p>
Unlike EVMv1, where we added the <a href="https://medium.com/superfluid-blog/automated-money-streams-are-here-introducing-the-access-control-list-7b328333d0d">ACL feature for automation</a> later, the off-chain automation system will be part of the
integral design of the system from day 1.
</p>
</div>
</div>
</div>
</div>

<div id="outline-container-org4541244" class="outline-2">
<h2 id="org4541244">More Breadth</h2>
<div class="outline-text-2" id="text-org4541244">
</div>
<div id="outline-container-orgb98f8e3" class="outline-3">
<h3 id="orgb98f8e3">Superfluid Protocol EVMv2</h3>
<div class="outline-text-3" id="text-orgb98f8e3">
<p>
We will still maintain our strong focus on EVM blockchains and start to work towards the EVMv2 Superfluid Protocol.
</p>
</div>
</div>

<div id="outline-container-org6cb262b" class="outline-3">
<h3 id="org6cb262b">Non-EVM Prototypes</h3>
<div class="outline-text-3" id="text-org6cb262b">
<p>
At the same time, bringing ideas behind the Superfluid Protocol everywhere is our longer-term dream. Therefore, to avoid
the risk of premature favoritism, we shall not mention any particular blockchains; nonetheless, it suffices to say that
a grant-seeking approach will be favored when exploring other chain implementations.
</p>
</div>
</div>
</div>

<div id="outline-container-org502d411" class="outline-2">
<h2 id="org502d411">Get Involved</h2>
<div class="outline-text-2" id="text-org502d411">
<p>
We’re excited to launch our yellowpaper series, and hope it helps evolve the discussion around what a modern payment
system could and should look like. We have yet to publicize any research-related job posts, but if our yellowpaper
series interests you and you’d like to be part of it, please visit <a href="http://jobs.superfluid.fiance">http://jobs.superfluid.fiance</a> or send your CV to
jobs@superfluid.finance!
</p>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-superfluid.html">superfluid</a> <a href="http://miaozc.me/tag-semantic money.html">semantic money</a> </div>
]]></description>
  <category><![CDATA[superfluid]]></category>
  <category><![CDATA[semantic money]]></category>
  <link>http://miaozc.me/2022-10-20-first-yellowpaper-about-superfluid-protocol.html</link>
  <guid>http://miaozc.me/2022-10-20-first-yellowpaper-about-superfluid-protocol.html</guid>
  <pubDate>Mon, 24 Oct 2022 20:00:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[Superfluid Tech Deep Dives - Maths of Generalized Distribution Agreements]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgc72ecd9">1. Generalized Distribution Payment Semantics</a></li>
<li><a href="#org2d778c1">2. General Constructions</a>
<ul>
<li><a href="#org9af7347">2.1. Proportional Distribution and Units</a></li>
<li><a href="#orgff8423e">2.2. Distribution Curve</a></li>
<li><a href="#org94a3d99">2.3. Computation Complexity</a></li>
<li><a href="#orgbefe995">2.4. General Principles</a></li>
</ul>
</li>
<li><a href="#org59484e8">3. Instant Distribution Operations</a>
<ul>
<li><a href="#org9b00403">3.1. Publisher Balance Function</a></li>
<li><a href="#org93d6461">3.2. Subscriber Balance Function</a></li>
<li><a href="#org6e833ab">3.3. Example</a></li>
</ul>
</li>
<li><a href="#org0f60413">4. Constant Flow Distribution</a>
<ul>
<li><a href="#orgf5b05d1">4.1. Constant Flow Formula and Its Lenses</a></li>
<li><a href="#org33da5d7">4.2. Publisher Balance Function</a></li>
<li><a href="#org78ad16a">4.3. Subscriber Balance Function</a></li>
<li><a href="#org2378839">4.4. Example</a></li>
</ul>
</li>
<li><a href="#orgeaf80c5">5. Inductively Covering All Cases</a></li>
<li><a href="#org538b7ce">6. What Is Next</a></li>
</ul>
</div>
</nav>

<div id="outline-container-orgc72ecd9" class="outline-2">
<h2 id="orgc72ecd9"><span class="section-number-2">1.</span> Generalized Distribution Payment Semantics</h2>
<div class="outline-text-2" id="text-1">
<p>
Think of the following hypothetical payment requests:
</p>

<ul class="org-ul">
<li>Microsoft requests to send <span class="underline">$0.42 per share</span> to <span class="underline">all its share holders</span> <i>on the next ex-dividend date</i>.</li>
<li>Elon Musk requests to send a <span class="underline">constant flow of money</span> at €4.2B per 360 days <span class="underline">to all its share holders</span> with individual
flow rates <span class="underline">proportional</span> to their number of share units, <i>from 20st April</i>.</li>
</ul>

<p>
How do we perform these payment requests in a payment system in a way that there are as least amount messages
(transactions) happening as possible?
</p>

<p>
And this is the central question to the design of the generalized distribution agreements, and those are the examples of
its payment semantics<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
In this article we will go through some maths in its specification.
</p>
</div>
</div>
<div id="outline-container-org2d778c1" class="outline-2">
<h2 id="org2d778c1"><span class="section-number-2">2.</span> General Constructions</h2>
<div class="outline-text-2" id="text-2">
<p>
The key concepts of a distribution agreement are: <i>publishers</i>, <i>subscribers</i> and <i>indexes</i>, whereby:
</p>
<ul class="org-ul">
<li>A publisher distributes money through a index to the subscribers of the index.</li>
<li>An index records proportions of distributions at which each of its subscribers should receive.</li>
</ul>
</div>
<div id="outline-container-org9af7347" class="outline-3">
<h3 id="org9af7347"><span class="section-number-3">2.1.</span> Proportional Distribution and Units</h3>
<div class="outline-text-3" id="text-2-1">
<p>
For the purpose of this article, the index is limited to being <i>proportional distribution index</i>. In this form, each
subscriber subscribes to a number of <i>units</i> of the index. And number of units determines the proportional amounts
subscribers should receive from the distributions. You can think of dividend payments from Microsoft to its share
holders is such example, where the number of shares at ex-div date determines your dividend payout amount at the payout
date.
</p>

<p>
The name of the semantic function for subscribers is <code>updateSubscription</code>.
</p>
</div>
</div>
<div id="outline-container-orgff8423e" class="outline-3">
<h3 id="orgff8423e"><span class="section-number-3">2.2.</span> Distribution Curve</h3>
<div class="outline-text-3" id="text-2-2">
<p>
The function of which how the publisher distributes money is the <i>distribution curve</i>.
</p>

<p>
Distribution curve can be any arbitrary continuous function, but for a practical solvency response system (in this case,
a system that can check if the publisher still have positive balance left), it is desirable to have a distribution
curve that is monotonically non-decreasing.
</p>

<p>
However, instant distribution is a special case even though it is not a continuous function. It can still work because
it doesn't have a curve at all hence some specialization in implementation could be done to accommodate that fact. The
name of the semantic function for the publisher of a instant distribution index is <code>distributeValue</code>.
</p>

<p>
For the purpose of this article, we will also explore the constant flow distribution curve, where publisher distribute
one big flow at a constant flow rate to all its subscribers, where subscribers proportionally gets smaller flows
according to their number of units. The name of the semantic function for the publisher of a constant flow distribution
index is <code>updateConstantFlowDistributionRate</code>.
</p>
</div>
</div>
<div id="outline-container-org94a3d99" class="outline-3">
<h3 id="org94a3d99"><span class="section-number-3">2.3.</span> Computation Complexity</h3>
<div class="outline-text-3" id="text-2-3">
<p>
On a note of space complexity, for a publisher, the cost of storing its indexes is constant <code>O(1).</code> But for the
subscribers, it is rather of linear <code>O(N)</code>, for reasons this article will not elaborate more on.
</p>

<p>
Since to calculate current balance of a subscriber, it is necessary to iterate through all its subscriptions, the time
complexity story is the same for subscribers.
</p>
</div>
</div>
<div id="outline-container-orgbefe995" class="outline-3">
<h3 id="orgbefe995"><span class="section-number-3">2.4.</span> General Principles</h3>
<div class="outline-text-3" id="text-2-4">
<p>
<b>Common variables</b>
</p>

<ul class="org-ul">
<li><code>t_s</code>: settled at</li>
<li><code>sv</code>: settled value</li>
</ul>

<p>
<b>Variables for publisher</b>
</p>

<ul class="org-ul">
<li><code>vpu</code>: value per unit (of the index).</li>
</ul>

<p>
<b>Variable For subscriber</b>
</p>

<ul class="org-ul">
<li><code>svpu</code>: settled value per unit (of each subscriber).</li>
</ul>

<p>
How these variables are updated:
</p>

<ol class="org-ol">
<li>Publisher <code>vpu</code> is always updated for either a publisher operation (<code>distributeFlow</code>, or <code>updateConstantFlowDistribution</code>)
or a subscriber operation (<code>updateSubscription</code> units).</li>
<li>Publisher's balance curve is indistinguishable between sending to 1 participant to N subscribers. This observation
also leads to the design of using "lens abstraction"<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> when defining the specification.</li>
<li>A subscriber's <code>svpu</code> is updated only when a subscriber operation applied to it.</li>
</ol>
</div>
</div>
</div>
<div id="outline-container-org59484e8" class="outline-2">
<h2 id="org59484e8"><span class="section-number-2">3.</span> Instant Distribution Operations</h2>
<div class="outline-text-2" id="text-3">
<p>
Let's first have a look how the instant distribution index work for its operations (<code>updateSubscription</code> &amp;
<code>distributeValue</code>). This will solve the puzzle of how can Microsoft sends dividends to all its shareholders using the
least amount of transactions.
</p>
</div>
<div id="outline-container-org9b00403" class="outline-3">
<h3 id="org9b00403"><span class="section-number-3">3.1.</span> Publisher Balance Function</h3>
<div class="outline-text-3" id="text-3-1">
<p>
Per principle (2), balance function for publisher is the same as a simple 1 to 1 instant transfer, which is simply
a constant function of a fixed value settled per principle (1).
</p>
</div>
</div>
<div id="outline-container-org93d6461" class="outline-3">
<h3 id="org93d6461"><span class="section-number-3">3.2.</span> Subscriber Balance Function</h3>
<div class="outline-text-3" id="text-3-2">
<p>
Balance function for subscriber is:
</p>

<div class="org-src-container">
<pre class="src src-haskell">sv <span style="color: #fce94f;">+</span> floor (u <span style="color: #fcaf3e;">*</span> fromIntegral (vpu <span style="color: #fcaf3e;">-</span> svpu))
</pre>
</div>
</div>
</div>
<div id="outline-container-org6e833ab" class="outline-3">
<h3 id="org6e833ab"><span class="section-number-3">3.3.</span> Example</h3>
<div class="outline-text-3" id="text-3-3">
<p>
Here is an illustrate an example case per principle (1):
</p>


<figure id="orgc0b6b6e">
<img src="../static/2022-08-18-superfluid-gda/ida-example1.png" alt="ida-example1.png">

</figure>
</div>
</div>
</div>
<div id="outline-container-org0f60413" class="outline-2">
<h2 id="org0f60413"><span class="section-number-2">4.</span> Constant Flow Distribution</h2>
<div class="outline-text-2" id="text-4">
<p>
Now let's have a look of a more complex case, the constant flow distribution operations (<code>updateSubscription</code> &amp;
<code>updateConstantFlowDistribution</code>). This will solve the puzzle of how can Elon Musk sends a flow of dividends to all of his
"followers".
</p>
</div>
<div id="outline-container-orgf5b05d1" class="outline-3">
<h3 id="orgf5b05d1"><span class="section-number-3">4.1.</span> Constant Flow Formula and Its Lenses</h3>
<div class="outline-text-3" id="text-4-1">
<p>
First of all, the constant flow formula are provided through the lens abstraction, it is just a fancy way of saying some
of the values of the formula are provided are a set of functions themselves:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #73d216;">-- </span><span style="color: #73d216;">... (omitted noisy details)</span>
    settledAt          <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Lens'</span> amuLs (<span style="color: #8cc4ff;">SFT_TS</span> sft)
    settledValue       <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Lens'</span> amuLs (<span style="color: #8cc4ff;">UntappedValue</span> (<span style="color: #8cc4ff;">SFT_MVAL</span> sft))
    netFlowRate        <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Lens'</span> amuLs (<span style="color: #8cc4ff;">SFT_MVAL</span> sft)
<span style="color: #73d216;">-- </span><span style="color: #73d216;">... (omitted noisy details)</span>
    balanceProvided (<span style="color: #8cc4ff;">MkMonetaryUnitData</span> a) t <span style="color: #fcaf3e;">=</span>
        <span style="color: #b4fa70;">let</span> b <span style="color: #fcaf3e;">=</span> sv <span style="color: #fcaf3e;">+</span> coerce (fr <span style="color: #fcaf3e;">*</span> fromIntegral (t <span style="color: #fcaf3e;">-</span> t_s))
        <span style="color: #b4fa70;">in</span>  <span style="color: #73d216;">-- </span><span style="color: #73d216;">... (omitted noisy details)</span>
        <span style="color: #73d216;">-- </span><span style="color: #73d216;">(.^) is the lens accessor/getter function, similar to "." in OO languages.</span>
        <span style="color: #b4fa70;">where</span> t_s <span style="color: #fcaf3e;">=</span> a<span style="color: #fcaf3e;">^.</span>settledAt
              sv  <span style="color: #fcaf3e;">=</span> a<span style="color: #fcaf3e;">^.</span>settledValue
              fr  <span style="color: #fcaf3e;">=</span> a<span style="color: #fcaf3e;">^.</span>netFlowRate
</pre>
</div>

<p>
What really matters above is the formula in <b>b</b>, and knowing that it needs three set of lenses: <code>settledAt</code>, <code>settledValue</code>
and <code>netFlowRate</code> to be able to compute.
</p>
</div>
</div>
<div id="outline-container-org33da5d7" class="outline-3">
<h3 id="org33da5d7"><span class="section-number-3">4.2.</span> Publisher Balance Function</h3>
<div class="outline-text-3" id="text-4-2">
<p>
Per principle (2), balance function for publisher is the same as the 1 to 1 constant flow, hence its lenses are trivial:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #73d216;">-- </span><span style="color: #73d216;">... the data record for publisher</span>
<span style="color: #b4fa70;">data</span> <span style="color: #8cc4ff;">PublisherData</span> sft <span style="color: #fcaf3e;">=</span> <span style="color: #8cc4ff;">PublisherData</span>
    { pub_settled_at      <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">SFT_TS</span> sft
    , pub_settled_value   <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">UntappedValue</span> (<span style="color: #8cc4ff;">SFT_MVAL</span> sft)
    , pub_total_flow_rate <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">SFT_MVAL</span> sft
    }
<span style="color: #73d216;">-- </span><span style="color: #73d216;">... use field template to generated lenses</span>
    settledAt    <span style="color: #fcaf3e;">=</span> <span style="color: #fcaf3e;">$</span>(field 'pub_settled_at)
    settledValue <span style="color: #fcaf3e;">=</span> <span style="color: #fcaf3e;">$</span>(field 'pub_settled_value)
    netFlowRate  <span style="color: #fcaf3e;">=</span> <span style="color: #fcaf3e;">$</span>(field 'pub_total_flow_rate)
</pre>
</div>
</div>
</div>
<div id="outline-container-org78ad16a" class="outline-3">
<h3 id="org78ad16a"><span class="section-number-3">4.3.</span> Subscriber Balance Function</h3>
<div class="outline-text-3" id="text-4-3">
<p>
Balance function for subscriber is a tad more complex but still succinct. It is also provided through a set of constant
flow lenses:
</p>

<div class="org-src-container">
<pre class="src src-haskell">    settledAt     <span style="color: #fcaf3e;">=</span> readOnlyLens
        (<span style="color: #fcaf3e;">\</span>(<span style="color: #73d216;">-- </span><span style="color: #73d216;">... syntaticcal pattern matching noise omitted</span>
          ) <span style="color: #fcaf3e;">-&gt;</span> s_t)

    netFlowRate   <span style="color: #fcaf3e;">=</span> readOnlyLens
        (<span style="color: #fcaf3e;">\</span>(( <span style="color: #73d216;">-- </span><span style="color: #73d216;">... syntaticcal pattern matching noise omitted</span>
           ) <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #b4fa70;">if</span> tu <span style="color: #fcaf3e;">/=</span> 0 <span style="color: #b4fa70;">then</span> floor <span style="color: #fcaf3e;">$</span> fromIntegral dcfr <span style="color: #fcaf3e;">*</span> u <span style="color: #fcaf3e;">/</span> tu <span style="color: #b4fa70;">else</span> 0)

    settledValue <span style="color: #fcaf3e;">=</span> readOnlyLens
        (<span style="color: #fcaf3e;">\</span>( <span style="color: #73d216;">-- </span><span style="color: #73d216;">... syntaticcal pattern matching noise omitted</span>
          ) <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #b4fa70;">let</span> compensated&#916; <span style="color: #fcaf3e;">=</span> dcfr <span style="color: #fcaf3e;">*</span> fromIntegral (t_dc <span style="color: #fcaf3e;">-</span> t_sc)
                   compensatedVpu&#916; <span style="color: #fcaf3e;">=</span> <span style="color: #b4fa70;">if</span> tu <span style="color: #fcaf3e;">/=</span> 0 <span style="color: #b4fa70;">then</span> floor <span style="color: #fcaf3e;">$</span> fromIntegral compensated&#916; <span style="color: #fcaf3e;">/</span> tu <span style="color: #b4fa70;">else</span> 0
               <span style="color: #b4fa70;">in</span>  sv <span style="color: #fcaf3e;">+</span> floor (u <span style="color: #fcaf3e;">*</span> fromIntegral (vpu <span style="color: #fcaf3e;">-</span> svpu <span style="color: #fcaf3e;">-</span> compensatedVpu&#916;)))
</pre>
</div>

<p>
In addition to the common variables:
</p>

<ul class="org-ul">
<li>Let <code>fpu</code> be flow per unit, then <code>dcfr</code> is the distribution flow rate of the index: <code>dcfr = fpu * total_units</code>.</li>
<li>In <code>settledValue</code> function, <code>t_dc</code> is the <code>s_t</code> of the publisher side, while <code>t_sc</code> is the <code>s_t</code> of the subscriber side.</li>
</ul>

<p>
The following visual example should show you how all these formulas compose together nicely.
</p>
</div>
</div>
<div id="outline-container-org2378839" class="outline-3">
<h3 id="org2378839"><span class="section-number-3">4.4.</span> Example</h3>
<div class="outline-text-3" id="text-4-4">
<p>
Here is an illustrate an example case per principle (1):
</p>


<figure id="org4198f41">
<img src="../static/2022-08-18-superfluid-gda/cfda-example1.png" alt="cfda-example1.png">

</figure>

<p>
It should show why <code>compensatedVpuΔ</code> was needed behind the lens abstraction in the "bar sticks algebra" on the bottom
right side.
</p>
</div>
</div>
</div>
<div id="outline-container-orgeaf80c5" class="outline-2">
<h2 id="orgeaf80c5"><span class="section-number-2">5.</span> Inductively Covering All Cases</h2>
<div class="outline-text-2" id="text-5">
<p>
Now that we seem to have the basic formulas for both Instant Distribution and Constant Flow Distributions figured
out, how do we know it can work for all cases?
</p>

<p>
Like many formal proofs, we need to use inductions and come up with base cases.
</p>

<p>
Using constant flow distribution as the example, there are two base cases:
</p>

<ul class="org-ul">
<li>A publisher the distribute constant flow to two subscribers.</li>
<li>A subscriber receives constant flow distributions from two publishers.</li>
</ul>

<p>
Along with the following laws that need to be satisfied:
</p>

<ul class="org-ul">
<li>Publisher data forms a semigroup. That means it has a binary operator (for combining publisher data) and it should be
associative.</li>
<li>Each base case always yields zero balance in total, that means all balances sent from publisher should go to the
subscribers, no more no less (apart from precision errors may rise from the actual float data type).</li>
</ul>

<p>
As a lazy engineer we sometimes do, omitting all the actual formal proof steps, the claim is that with two base cases
and assuming the above laws are satisfied, then we can inductively covering all the cases of constant flow distribution
agreement.
</p>

<p>
To make things even more informal, noting that we are still assuming those laws are actually satisfied. Since the
specification does not use dependently typed languages such as Agda nor dependently-typed haskell, there is no way to
prove the laws using types.
</p>

<p>
In the end we will need to resort to using the technique such as quickcheck<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> for fuzzing as many cases as
possible to get higher confidence on the correctness of implementation. For example this algebraic type would allow you
to tell quickcheck to test a random combinations of all these operations and hence test the desired laws through the
properties:
</p>

<div class="org-src-container">
<pre class="src src-haskell"><span style="color: #73d216;">-- </span><span style="color: #73d216;">algebraic type of all possible operations</span>
<span style="color: #b4fa70;">data</span> <span style="color: #8cc4ff;">TestOperations</span> <span style="color: #fcaf3e;">=</span> <span style="color: #8cc4ff;">Nop</span> <span style="color: #8cc4ff;">()</span>
                    <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">PubOp1</span> <span style="color: #8cc4ff;">T_CFDAPublisherOperation</span>
                    <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">PubOp2</span> <span style="color: #8cc4ff;">T_CFDAPublisherOperation</span>
                    <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">SubOp1</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>
                    <span style="color: #fcaf3e;">|</span> <span style="color: #8cc4ff;">SubOp2</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>
                    <span style="color: #b4fa70;">deriving</span> <span style="color: #8cc4ff;">Show</span>

<span style="color: #73d216;">-- </span><span style="color: #73d216;">Testing 1 pub 2 subs scenario</span>
<span style="color: #b4fa70;">newtype</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #fcaf3e;">=</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #8cc4ff;">TestOperations</span> <span style="color: #b4fa70;">deriving</span> <span style="color: #8cc4ff;">Show</span>
<span style="color: #b4fa70;">instance</span> <span style="color: #8cc4ff;">Arbitrary</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #b4fa70;">where</span>
    arbitrary <span style="color: #fcaf3e;">=</span> oneof [ (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">()</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">Nop</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_CFDAPublisherOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">PubOp1</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">SubOp1</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_1Pub2Subs</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">SubOp2</span>
                      ]
<span style="color: #fce94f;">ao_1pub2subs_zero_sum_balance</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">T_Timestamp</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">NonEmptyList</span> (<span style="color: #8cc4ff;">TO_1Pub2Subs</span>, <span style="color: #8cc4ff;">T_Timestamp</span>) <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">Bool</span>

<span style="color: #73d216;">-- </span><span style="color: #73d216;">testing 2 pubs 1 sub scenario</span>
<span style="color: #b4fa70;">newtype</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">=</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #8cc4ff;">TestOperations</span> <span style="color: #b4fa70;">deriving</span> <span style="color: #8cc4ff;">Show</span>
<span style="color: #b4fa70;">instance</span> <span style="color: #8cc4ff;">Arbitrary</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #b4fa70;">where</span>
    arbitrary <span style="color: #fcaf3e;">=</span> oneof [(arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">()</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">Nop</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_CFDAPublisherOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">PubOp1</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_CFDAPublisherOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">PubOp2</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">SubOp1</span>
                      , (arbitrary <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">Gen</span> <span style="color: #8cc4ff;">T_PDIDXSubscriberOperation</span>) <span style="color: #fcaf3e;">&lt;&amp;&gt;</span> <span style="color: #8cc4ff;">TO_2Pubs1Sub</span> <span style="color: #fcaf3e;">.</span> <span style="color: #8cc4ff;">SubOp2</span>
                      ]
<span style="color: #fce94f;">ao_2pubs1sub_zero_sum_balance</span> <span style="color: #fcaf3e;">::</span> <span style="color: #8cc4ff;">T_Timestamp</span> <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">NonEmptyList</span> (<span style="color: #8cc4ff;">TO_2Pubs1Sub</span>, <span style="color: #8cc4ff;">T_Timestamp</span>) <span style="color: #fcaf3e;">-&gt;</span> <span style="color: #8cc4ff;">Bool</span>

<span style="color: #73d216;">-- </span><span style="color: #73d216;">...</span>
<span style="color: #fce94f;">tests</span> <span style="color: #fcaf3e;">=</span> describe <span style="color: #e9b96e;">"ConstantFlowDistributionAgreement properties"</span> <span style="color: #fcaf3e;">$</span> <span style="color: #b4fa70;">do</span>
    it <span style="color: #e9b96e;">"CFDA semigroup Publisher MUD associativity"</span>                       <span style="color: #fcaf3e;">$</span> property semigroup_pubmud_associativity
    it <span style="color: #e9b96e;">"CFDA semigroup Publisher MUD settles pi"</span>                          <span style="color: #fcaf3e;">$</span> property semigroup_pubmud_settles_pi
    it <span style="color: #e9b96e;">"CFDA operations produces zero balance sum between 1 pub &amp; 2 subs"</span> <span style="color: #fcaf3e;">$</span> property ao_1pub2subs_zero_sum_balance
    it <span style="color: #e9b96e;">"CFDA operations produces zero balance sum between 2 pubs &amp; 1 sub"</span> <span style="color: #fcaf3e;">$</span> property ao_2pubs1sub_zero_sum_balance
</pre>
</div>
</div>
</div>
<div id="outline-container-org538b7ce" class="outline-2">
<h2 id="org538b7ce"><span class="section-number-2">6.</span> What Is Next</h2>
<div class="outline-text-2" id="text-6">
<p>
The maths covered here form the foundation of how general distribution can work in practice, hence enabling new payment
semantics that can be performed efficiently in superfluid-style payment system.
</p>

<p>
There is still much to be said about how the agreement should be structured in general, for example what does it mean
that the publisher data need to have the semigroup structure? This will be explained in a future article answering the
question "what makes an agreement a well behaved agreement?".
</p>

<p>
The specification of these new payment semantics will be ported to the current EVM implementation too. For both the EVM
implementation and the work-in-progress Haskell specification, you can find them at:
<a href="https://github.com/superfluid-finance/protocol-monorepo/">https://github.com/superfluid-finance/protocol-monorepo/</a>.
</p>


<p>
Other Useful Links:
</p>

<ul class="org-ul">
<li>Build with Superfluid, <a href="http://docs.superfluid.finance/">read our docs</a> and <a href="http://discord.superfluid.finance/">join the conversation</a>.</li>
<li>Visit our <a href="https://www.superfluid.finance/">Website</a> or <a href="https://github.com/superfluid-finance">GitHub</a>, follow us on <a href="https://twitter.com/intent/follow?screen_name=Superfluid_HQ">Twitter</a>, <a href="http://discord.superfluid.finance/">Discord</a> or <a href="https://www.linkedin.com/company/superfluid/">LinkedIn</a>.</li>
</ul>

<p>
Article source code:
<a href="https://raw.githubusercontent.com/wiki/superfluid-finance/protocol-monorepo/Presentation-denotational-payment/index.org">https://raw.githubusercontent.com/wiki/superfluid-finance/protocol-monorepo/Presentation-denotational-payment/index.org</a>
</p>

<hr>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Elliott, Conal. "Denotational design with type class morphisms." extended version), LambdaPix
(2009).
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://golem.ph.utexas.edu/category/2020/01/profunctor_optics_the_categori.html">https://golem.ph.utexas.edu/category/2020/01/profunctor_optics_the_categori.html</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
<a href="https://en.wikipedia.org/wiki/QuickCheck">https://en.wikipedia.org/wiki/QuickCheck</a>
</p></div></div>


</div>
</div><div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-superfluid.html">superfluid</a> </div>
]]></description>
  <category><![CDATA[superfluid]]></category>
  <link>http://miaozc.me/2022-08-18-superfluid-gda.html</link>
  <guid>http://miaozc.me/2022-08-18-superfluid-gda.html</guid>
  <pubDate>Thu, 18 Aug 2022 00:00:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[[翻译] (Unfinished) 国家民粹主义对比民主]]></title>
  <description><![CDATA[
<p>
原文：<a href="http://www.eurozine.com/articles/2008-06-19-todorovantony-en.html">http://www.eurozine.com/articles/2008-06-19-todorovantony-en.html</a>
</p>

<p>
作者：Antony Todorov
</p>

<p>
民粹主义运动的威胁不是他们呼吁的直接民主制，而是他们鼓吹仇外的民族主义， Antony Todorov 写道。在20世纪左翼失败的背景下，
可以说极右翼民粹主义在中东欧的新兴民主国家中比在西欧国家中更加的反民主。那么民粹主义可以说等价于民主的危机还是只是这个危
机的一个症状？在最近些年里“新民粹主义“已经是很多研究和分析的主题。尽管方式差异很大，他们的目的或许仍可以总结为：定义民粹
主义和他们的形式；确定当代世界新形式的民粹主义；并分析当今民粹主义所呈现的风险。很长一段时间以来，民粹主义已经是政治科学
家的一个研究主题。历史上，他与出现在世界各地不同时期的一些现象相联系：民粹主义党在十九世纪后期和二十世纪早期的北美；同时
期的俄国民粹派（Narodniki）；以及十九世纪德国浪漫主义的völkisch意识形态。民粹主义在二十实际也有过几次表现，比如在世界大
战时期欧洲的均地主义；在意大利和德国的纳粹所用的民粹式语言；亦或者二战后在阿根廷出现的庇隆主义（Peronism）。在他的当代形
式里，民粹主义从委内瑞拉的左翼Hugo Chavez(查维斯）到欧洲的极右翼们（奥地利的Haider， 法国的Le Pen， 或者保加利亚的
Siderov)。考虑到这些现象在血统和历史背景上是如此的混杂，那么问题是：我们能找到哪种程度的共同准则和结构使我们能定义民粹主
义？在后共产主义时期的保加利亚一个关于这个主题的最初的研究里， Evelina Ivanova 写道：一个理论上的关于典型理想的民粹主义
构造的尝试或许可以确定几个主要的原则。Edward Shils，一个北美民粹运动的学者指出卓越的人民意愿超越传统机构的领导人和任何社
会阶层的意愿，并且指出建立不经过机构调解的人民和统治精英的“直接”关系的愿望。Worsley 补充了“大众参与”的多种形式，包括伪参
与(pseudo-participation)。民粹主义经常预先假定（宣传和要求）极端形式的民主，并且通过“人民”为政治职位、政治行动和政治手段
的合法化提供合适的形式。它代表了通过不同形式的直接民主建立与人民大众直接接触的理想目标。
</p>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-politics.html">politics</a> </div>
]]></description>
  <category><![CDATA[politics]]></category>
  <link>http://miaozc.me/2010-05-04-national-populism-vs-democracy.html</link>
  <guid>http://miaozc.me/2010-05-04-national-populism-vs-democracy.html</guid>
  <pubDate>Tue, 04 May 2010 11:11:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[[PAPER] Non-Blocking Algorithms]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgacff80e">1. Introduction</a>
<ul>
<li><a href="#org39bc0a6">1.1. Non-Blocking Algorithm Introduction</a></li>
</ul>
</li>
<li><a href="#orgf29ba84">2. Fixed-size Slots Management</a>
<ul>
<li><a href="#orgeb62bac">2.1. Problem</a></li>
<li><a href="#org323e924">2.2. Primitive CAS</a></li>
<li><a href="#org279fe0a">2.3. First Algorithm (with mistakes)</a></li>
<li><a href="#orgcfdf3e6">2.4. ABA Problem</a></li>
<li><a href="#orge9f5b7b">2.5. Use Pointer Tag to Avoid ABA Problem</a></li>
<li><a href="#orga208e24">2.6. Wider CAS</a></li>
<li><a href="#org95dff6f">2.7. Load-Link and Store-Conditional(LL/SC)</a></li>
<li><a href="#orgb739979">2.8. Realistic Limitations</a></li>
<li><a href="#orgb8e6220">2.9. Conclusion</a></li>
</ul>
</li>
<li><a href="#orgae5756b">3. FIFO Queue</a>
<ul>
<li><a href="#org337f02f">3.1. Problem</a></li>
<li><a href="#org6955653">3.2. Link-List Structure</a></li>
<li><a href="#org05672fd">3.3. Dequeue Data, first thought</a></li>
<li><a href="#orge6c6f02">3.4. Enqueue Data</a></li>
<li><a href="#org2439573">3.5. Algorithm</a></li>
<li><a href="#org2ebdcd1">3.6. Array Based Algorithm</a></li>
<li><a href="#org03835bd">3.7. Conclusion</a></li>
</ul>
</li>
</ul>
</div>
</nav>

<div id="outline-container-orgacff80e" class="outline-2">
<h2 id="orgacff80e"><span class="section-number-2">1.</span> Introduction</h2>
<div class="outline-text-2" id="text-1">
</div>
<div id="outline-container-org39bc0a6" class="outline-3">
<h3 id="org39bc0a6"><span class="section-number-3">1.1.</span> Non-Blocking Algorithm Introduction</h3>
<div class="outline-text-3" id="text-1-1">
<blockquote>
<p>
In computer science, non-blocking synchronization ensures that threads competing for a shared resource do not have their
execution indefinitely postponed by mutual exclusion. A non-blocking algorithm is lock-free if there is guaranteed
system-wide progress; wait-free if there is also guaranteed per-thread progress<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</blockquote>

<p>
This simple diagram shows more clearly the idea:
</p>

<pre class="example" id="org4c11f30">
    +------------------------------+--------------------------------+
    |                              |                                |
    |      Mutual Exclusion        |  Non-Blocking                  |
    |                              |                                |
    |                              |    +-------------------------+ |
    |          |     |             |    |                         | |
    |          |  H  |             |    |   Lock-Freedom          | |
    |          |  y  |             |    |                         | |
    |          |  b  |             |    |    +------------------+ | |
    | Blocking |  r  | Busy-Waiting|    |    |                  | | |
    |          |  i  |  (Polling)  |    |    |   Wait-Freedom   | | |
    |          |  d  |             |    |    |                  | | |
    |          |  s  |             |    |    +------------------+ | |
    |          |     |             |    |                         | |
    |                              |    +-------------------------+ |
    |                              |                                |
    +------------------------------+--------------------------------+
</pre>

<p>
Using mutual exclusion is the most instinctive and easiest way to protect data from corruption in concurrent
multi-threaded programming, which simply creates a critical region around the operations of data structure. It works
fine most of the situations, but in some situations, lock is just too expensive or even not available. One example is
for some ISR(Interrupt Service Routines), if it disables the interruption, then the scheduler will not be run until they
open the interruption again, if it also waits for some resources which is hold by some task, then it will never
available because scheduler stops. Another example is in RTOS, higher priority wait for the lower priority task to
release the resource, then it causes priority-inversion. So, non-blocking algorithms are born to solve these problem
without using mutual exclusions.
</p>

<p>
Valois published his most cited paper talking about lock-free data structure at 1995<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>. But unfortunately, there are
some mistakes with the memory management method introduced by Valois<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.
</p>

<p>
But algorithms from Valois needs special memory management, and it's just too complicated to use. Michael and Scott
published their own algorithms based on the idea of cooperative task from Valois<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
There's another more detailed notes on lock-free and wait-free algorithms area from Internet<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>.
</p>
</div>
</div>
</div>

<div id="outline-container-orgf29ba84" class="outline-2">
<h2 id="orgf29ba84"><span class="section-number-2">2.</span> Fixed-size Slots Management</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-orgeb62bac" class="outline-3">
<h3 id="orgeb62bac"><span class="section-number-3">2.1.</span> Problem</h3>
<div class="outline-text-3" id="text-2-1">
<p>
Provide a non-blocking algorithm that maintains an array of fixed-size slots with the following interface:
</p>

<ul class="org-ul">
<li><p>
void InitSlots(void)
</p>

<p>
Slots initialization.
</p></li>

<li><p>
SLOTID GetSlot(void)
</p>

<p>
Exclusively get an id of one free slot, and prevent other user to get this
slot.
</p></li>

<li><p>
void PutSlot(SLOTID id)
</p>

<p>
Reclaim a slot returned by GetSlot, and make it free to get again.
</p></li>

<li><p>
DATA* DecodeSlotID(SLOTID id)
</p>

<p>
Decode a id of slot, and return the memory address of that slot.
</p></li>
</ul>
</div>
</div>

<div id="outline-container-org323e924" class="outline-3">
<h3 id="org323e924"><span class="section-number-3">2.2.</span> Primitive CAS</h3>
<div class="outline-text-3" id="text-2-2">
<p>
Atomic operation CAS(compare-and-swap) atomically compares the contents of a memory location to a given value and, if
they are the same, modifies the contents of that memory location to a given new value<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>. The following algorithm assume
that CAS is available on the target hardware.
</p>
</div>
</div>

<div id="outline-container-org279fe0a" class="outline-3">
<h3 id="org279fe0a"><span class="section-number-3">2.3.</span> First Algorithm (with mistakes)</h3>
<div class="outline-text-3" id="text-2-3">
<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">struct</span>
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">next</span>;
    <span style="color: #8cc4ff;">DATA</span> <span style="color: #fcaf3e;">data</span>;
}<span style="color: #8cc4ff;">Node</span>;

<span style="color: #8cc4ff;">Node</span> <span style="color: #fcaf3e;">Slots</span>[MAX_SLOT_NUM];

<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">head</span>;

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">InitSlots</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">i</span>;

    <span style="color: #b4fa70;">for</span> (i = 0; i &lt; MAX_SLOT_NUM - 1; ++i)
    {
        Slots[i].next = i+1;
    }
    Slots[i].next = NULL_ID;
    head = 0;
}

<span style="color: #8cc4ff;">int</span> <span style="color: #fce94f;">GetSlot</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">oldhead</span>;
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">next</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead  = head;
        <span style="color: #b4fa70;">if</span> (oldhead == NULL_ID)
        {
            <span style="color: #b4fa70;">return</span> NULL_ID;
        }
        <span style="color: #b4fa70;">else</span>
        {
            next = Slots[oldhead].next;
        }
    } <span style="color: #b4fa70;">while</span>(!CAS(&amp;head, oldhead, next));

    <span style="color: #b4fa70;">return</span> oldhead;
}

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">PutSlot</span>(<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">id</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">oldhead</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead = head;
        Slots[id].next = oldhead;
    } <span style="color: #b4fa70;">while</span>(!CAS(&amp;head, oldhead, id));
}

<span style="color: #8cc4ff;">DATA</span>* <span style="color: #fce94f;">DecodeSlotID</span>(<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">id</span>)
{
  <span style="color: #b4fa70;">return</span> &amp;Slots[id].data;
}
</pre>
</div>

<p>
The idea of this algorithm is to use CAS to check when modify the head, if it's still the old value. This is commonly
called read-modify-write. But this arises the well-known ABA problem.
</p>
</div>
</div>

<div id="outline-container-orgcfdf3e6" class="outline-3">
<h3 id="orgcfdf3e6"><span class="section-number-3">2.4.</span> ABA Problem</h3>
<div class="outline-text-3" id="text-2-4">
<p>
The above algorithm has a subtle problem, it assumes that if the id didn't change, then the list remains the same
also. But it's very common to happen that other tasks takes head and head.next and then returns the head, now the
head.next actually changed. This problem is known as ABA problem<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>.
</p>

<p>
There are several ways to solve it. Valois gave a methodology of memory management which tracks use count of
pointers<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup>. This way assures that a pointer possessing by some one will never be allocated until no one has a copy of
the pointer, thus avoiding the ABA problem to happen. Michael and Scott publishes their fixes on Valois's memory
management mistakes<sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>.
</p>

<p>
Another way is to use pointer tag, which adds an extra "tag" bits to the pointer. The "tag" usually increments itself on
every copy operation. Because of this, the next compare-and-swap will fail, even if the addresses are the same, because
the tag bits will not match. This does not completely solve the problem, as the tag bits will eventually wrap around,
but helps to avoid it.
</p>
</div>
</div>

<div id="outline-container-orge9f5b7b" class="outline-3">
<h3 id="orge9f5b7b"><span class="section-number-3">2.5.</span> Use Pointer Tag to Avoid ABA Problem</h3>
<div class="outline-text-3" id="text-2-5">
<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">union</span>
{
    /** to write */
    uint_t Value;

    /** to write */
    <span style="color: #b4fa70;">struct</span>
    {
        /** to write */
        uhalfint_t Counter;
        /** to write */
        uhalfint_t Index;
    } Data;
} <span style="color: #8cc4ff;">SLOTID</span>;
</pre>
</div>

<p>
Type "uhalfint<sub>t</sub>" is half length of uint<sub>t</sub>, uint<sub>t</sub> is unsigned integer type. The "Counter" here is the "tag" of the
pointer.
</p>


<p>
Now the algorithm looks like this:
</p>

<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">struct</span>
{
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">next</span>;
    <span style="color: #8cc4ff;">DATA</span> <span style="color: #fcaf3e;">data</span>;
}<span style="color: #8cc4ff;">Node</span>;

<span style="color: #8cc4ff;">Node</span> <span style="color: #fcaf3e;">Slots</span>[MAX_SLOT_NUM];

<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">head</span>;

<span style="color: #b4fa70;">static</span> <span style="color: #b4fa70;">inline</span>
<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fce94f;">NewSLOTID</span>(<span style="color: #8cc4ff;">uhalfint_t</span> <span style="color: #fcaf3e;">index</span>)
{
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">id</span>;

    id.Data.Counter = 0;
    id.Data.Index = index;

    <span style="color: #b4fa70;">return</span> id;
}

<span style="color: #b4fa70;">static</span> <span style="color: #b4fa70;">inline</span>
<span style="color: #8cc4ff;">bool</span> <span style="color: #fce94f;">SLOTID_CAS</span>(<span style="color: #8cc4ff;">SLOTID</span> *<span style="color: #fcaf3e;">id</span>, <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">oldid</span>, <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">newid</span>)
{
    /* Increae the counter to avoid ABA problem */
    ++newid.Data.Counter;

    <span style="color: #b4fa70;">return</span> CAS(&amp;id-&gt;Value,  oldid.Value, newid.Value);
}

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">InitSlots</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">i</span>;

    <span style="color: #b4fa70;">for</span> (i = 0; i &lt; MAX_SLOT_NUM - 1; ++i)
    {
        Slots[i].next = NewSLOTID(i+1);
    }
    Slots[i].next = NewSLOTID(NULL_ID);
    head = NewSLOTID(0);
}

<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fce94f;">GetSlot</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">oldhead</span>;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">next</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead  = head;
        <span style="color: #b4fa70;">if</span> (oldhead == NULL_ID)
        {
            <span style="color: #b4fa70;">return</span> NULL_ID;
        }
        <span style="color: #b4fa70;">else</span>
        {
            next = Slots[oldhead.Data.Index].next;
        }
    } <span style="color: #b4fa70;">while</span>(!SLOTID_CAS(&amp;head, oldhead, next));

    <span style="color: #b4fa70;">return</span> oldhead;
}

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">PutSlot</span>(<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">id</span>)
{
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">oldhead</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead = head;
        Slots[id.Data.Index].next = oldhead;
    } <span style="color: #b4fa70;">while</span>(!SLOTID_CAS(&amp;head, oldhead, id));
}

<span style="color: #8cc4ff;">DATA</span>* <span style="color: #fce94f;">DecodeSlotID</span>(<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">id</span>)
{
  <span style="color: #b4fa70;">return</span> &amp;Slots[id.Data.Index].data;
}
</pre>
</div>

<p>
The key algorithm is the SLOTID<sub>CAS</sub> operation: every time it's going to change the SLOTID, it uses SLOTID<sub>CAS</sub>, which
increase the Counter then CAS. This makes the ABA like ABA'. The index can be the same, but the counter is unlikely the
same, the wider range of Counter is, the lesser possibility ABA will happen. On a 32-bit machine, range of Counter is
[0..2<sup>16</sup>].
</p>
</div>
</div>

<div id="outline-container-orga208e24" class="outline-3">
<h3 id="orga208e24"><span class="section-number-3">2.6.</span> Wider CAS</h3>
<div class="outline-text-3" id="text-2-6">
<p>
The problem of packing counter and index into a integer is obvious: the limitation number of array elements on a 32-bit
machine is 2<sup>16</sup>. And the counter limitation is 2<sup>16</sup>, after that it wraps to 0. 2<sup>16</sup> is not a big enough value to soothe
the skeptics, so on some architecture wider CAS is provided. Wider CAS is different from Multi CAS, the former can CAS
on an adjacent memory fields thus be called wider, but the latter can CAS on unrelated memory fields.
</p>

<p>
On later inter x86 processor, it provides an instruction called CMPXCHG8B, which compare-and-swap-8-bytes<sup><a id="fnr.10" class="footref" href="#fn.10" role="doc-backlink">10</a></sup>. By this
instruction, we can operate on a normal memory pointer instead of a memory pointer, and its "tag" which has a range as
large as 2<sup>32</sup>.
</p>

<p>
CAS2 is a realistic existence of Multi CAS, but only on some Motorola 680x0 processors.
</p>
</div>
</div>

<div id="outline-container-org95dff6f" class="outline-3">
<h3 id="org95dff6f"><span class="section-number-3">2.7.</span> Load-Link and Store-Conditional(LL/SC)</h3>
<div class="outline-text-3" id="text-2-7">
<blockquote>
<p>
In computer science, load-link (LL, also known as "load-linked" or "load and reserve") and store-conditional (SC) are a
pair of instructions that together implement a lock-free atomic read-modify-write operation.
</p>

<p>
Load-link returns the current value of a memory location. A subsequent store-conditional to the same memory location
will store a new value only if no updates have occurred to that location since the load-link. If any updates have
occurred, the store-conditional is guaranteed to fail, even if the value read by the load-link has since been
restored. As such, an LL/SC pair is stronger than a read followed by a compare-and-swap (CAS), which will not detect
updates if the old value has been restored.<sup><a id="fnr.11" class="footref" href="#fn.11" role="doc-backlink">11</a></sup>
</p>
</blockquote>

<p>
LL/SC can finally make skeptics happy, it doesn't just make ABA problem look like ABA', but solve it in another say. The
algorithm with LL/SC can be:
</p>

<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">struct</span>
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">next</span>;
    <span style="color: #8cc4ff;">DATA</span> <span style="color: #fcaf3e;">data</span>;
}<span style="color: #8cc4ff;">Node</span>;

<span style="color: #8cc4ff;">Node</span> <span style="color: #fcaf3e;">Slots</span>[MAX_SLOT_NUM];

<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">head</span>;

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">InitSlots</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">i</span>;

    <span style="color: #b4fa70;">for</span> (i = 0; i &lt; MAX_SLOT_NUM - 1; ++i)
    {
        Slots[i].next = i+1;
    }
    Slots[i].next = NULL_ID;
    head = 0;
}

<span style="color: #8cc4ff;">int</span> <span style="color: #fce94f;">GetSlot</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">oldhead</span>;
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">next</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead  = LL(&amp;head);
        <span style="color: #b4fa70;">if</span> (oldhead == NULL_ID)
        {
            <span style="color: #b4fa70;">return</span> NULL_ID;
        }
        <span style="color: #b4fa70;">else</span>
        {
            next = Slots[oldhead].next;
        }
    } <span style="color: #b4fa70;">while</span>(!SC(&amp;head, next));

    <span style="color: #b4fa70;">return</span> oldhead;
}

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">PutSlot</span>(<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">id</span>)
{
    <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">oldhead</span>;

    <span style="color: #b4fa70;">do</span> {
        oldhead = LL(&amp;head);
        Slots[id].next = oldhead;
    } <span style="color: #b4fa70;">while</span>(!SC(&amp;head, id));
}

<span style="color: #8cc4ff;">DATA</span>* <span style="color: #fce94f;">DecodeSlotID</span>(<span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">id</span>)
{
  <span style="color: #b4fa70;">return</span> &amp;Slots[id].data;
}
</pre>
</div>

<p>
To use the above algorithm, the users have to also use LL/SC to load and store the slot id because of the ABA
problem. But since realistic LL/SC implementations all have limitations, actually LL/SC version algorithm is more
difficult to use than the CAS version.
</p>
</div>
</div>

<div id="outline-container-orgb739979" class="outline-3">
<h3 id="orgb739979"><span class="section-number-3">2.8.</span> Realistic Limitations</h3>
<div class="outline-text-3" id="text-2-8">
<p>
Real implementations of LL/SC can be found on Alpha, PowerPC<sup><a id="fnr.12" class="footref" href="#fn.12" role="doc-backlink">12</a></sup>, MIPS, ARMv6(or above). But they're all Weak LL/SC, SC
can fail even if there's no update between LL and corresponding SC, for example:
</p>

<ul class="org-ul">
<li>The CPU can only reserves a memory region at a time.</li>

<li>A context switching between them can cause the SC fail.</li>
</ul>

<p>
The first limitation can cause a lot of ideal algorithms based on LL/SC fail. So CAS version algorithm is still
preferable.
</p>
</div>
</div>

<div id="outline-container-orgb8e6220" class="outline-3">
<h3 id="orgb8e6220"><span class="section-number-3">2.9.</span> Conclusion</h3>
<div class="outline-text-3" id="text-2-9">
<p>
Wait-Free Fix-size Slots Management is a simple version of non-blocking memory management implementation, it only manage
fix-size slots. But it already make a lot of Non-Blocking algorithm common problems and tricks emerging. Later we'll see
a implementation of Wait-Free Fifo Queue based on this Slots Management.
</p>
</div>
</div>
</div>

<div id="outline-container-orgae5756b" class="outline-2">
<h2 id="orgae5756b"><span class="section-number-2">3.</span> FIFO Queue</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-org337f02f" class="outline-3">
<h3 id="org337f02f"><span class="section-number-3">3.1.</span> Problem</h3>
<div class="outline-text-3" id="text-3-1">
<p>
Provide a non-blocking algorithm that provides a FIFO Queue with the following interface:
</p>

<ul class="org-ul">
<li><p>
void InitFIFO(void)
</p>

<p>
FIFO queue initialization.
</p></li>

<li><p>
bool Enqueue(DATA data)
</p>

<p>
Push a data into the FIFO queue. Return TRUE if success, return FALSE only if
the FIFO is full.
</p></li>

<li><p>
bool Dequeue(DATA* pdata)
</p>

<p>
Pull a data from the FIFO queue. Return TRUE if success, return FALSE only if
the FIFO is empty.
</p></li>
</ul>
</div>
</div>

<div id="outline-container-org6955653" class="outline-3">
<h3 id="org6955653"><span class="section-number-3">3.2.</span> Link-List Structure</h3>
<div class="outline-text-3" id="text-3-2">
<p>
The algorithm introduced here is based on a link-list structure<sup><a id="fnr.13" class="footref" href="#fn.13" role="doc-backlink">13</a></sup>. It's a single link-list with head and tail
pointers. It looks like:
</p>

<pre class="example" id="org36509bb">
   +-------+     +-------+     +-------+     +-------+
   |       |     |       |     |       |     |       |
   |      -+----&gt;|      -+----&gt;|      -+----&gt;|      -+----&gt;NULL
   |       |     |       |     |       |     |       |
   +---^---+     +-------+     +-------+     +---^---+
       |                                         |
       |                                         |
       |                                         |
      HEAD                                      TAIL
</pre>

<p>
New data is pushed to the tail, and old data is pulled from head.
</p>
</div>
</div>

<div id="outline-container-org05672fd" class="outline-3">
<h3 id="org05672fd"><span class="section-number-3">3.3.</span> Dequeue Data, first thought</h3>
<div class="outline-text-3" id="text-3-3">
<p>
To dequeue a data, first read the HEAD value, and use CAS to swap the HEAD pointer to it's next pointer. And the old
HEAD value is the data that dequeued. To avoid ABA problem<sup><a id="fnr.14" class="footref" href="#fn.14" role="doc-backlink">14</a></sup>, we should use SLOTID<sub>CAS</sub> which described in the
"Fix-size Slots Management"<sup><a id="fnr.15" class="footref" href="#fn.15" role="doc-backlink">15</a></sup>.
</p>

<pre class="example" id="orgf3d01e6">
   +-------+     +-------+     +-------+     +-------+
   |       |     |       |     |       |     |       |
   |      -+----&gt;|      -+----&gt;|      -+----&gt;|      -+----&gt; NULL
   |       |     |       |     |       |     |       |
   +-------+     +---^---+     +-------+     +---^---+
                     |                           |
                     |                           |
                     |                           |
                    HEAD                        TAIL
</pre>
</div>
</div>

<div id="outline-container-orge6c6f02" class="outline-3">
<h3 id="orge6c6f02"><span class="section-number-3">3.4.</span> Enqueue Data</h3>
<div class="outline-text-3" id="text-3-4">
<p>
Enqueue operation is more complicated than dequeue operation, because it has to change two state: the next pointer of
the tail slot, and the tail pointer. If we have MCAS(Multi CAS) or at least Double CAS<sup><a id="fnr.16" class="footref" href="#fn.16" role="doc-backlink">16</a></sup>, then the problem is easy
to solve. But since DCAS is not widely available in computer system, so a so-called cooperative method is introduced
firstly by Valois<sup><a id="fnr.17" class="footref" href="#fn.17" role="doc-backlink">17</a></sup>.
</p>

<p>
In cooperative method, enqueue operation first allocates a new slot, and sets next pointer of tail slot to the new
slot. Then set tail pointer to new slot. All theses set operation use SLOTID<sub>CAS</sub>, so the second step can fail, if
someone others enters in, and set the tail pointer. Which leaves the FIFO in a intermediate state:
</p>

<pre class="example" id="orge2b87d0">
   +-------+     +-------+     +-------+     +-------+
   |       |     |       |     |       |     |       |
   |      -+----&gt;|      -+----&gt;|      -+----&gt;|      -+----&gt;NULL
   |       |     |       |     |       |     |       |
   +---^---+     +-------+     +---^---+     +-------+
       |                           |
       |                           |
       |                           |
      HEAD                        TAIL
</pre>

<p>
To complete the intermediate state:
</p>

<ol class="org-ol">
<li>The next enqueue operation should try to move the TAIL forward, until the TAIL at the end, the enqueue operation
should not change the TAIL slot next pointer.</li>

<li>The next dequeue operation should also try to move the TAIL forward when the head meets the tail pointer.</li>
</ol>
</div>
</div>

<div id="outline-container-org2439573" class="outline-3">
<h3 id="org2439573"><span class="section-number-3">3.5.</span> Algorithm</h3>
<div class="outline-text-3" id="text-3-5">
<p>
This algorithm uses CAS version of "Fix-size Slots Management"<sup><a id="fnr.15.100" class="footref" href="#fn.15" role="doc-backlink">15</a></sup>.
</p>

<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">struct</span>
{
    <span style="color: #8cc4ff;">DATA</span> <span style="color: #fcaf3e;">data</span>;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">next</span>;
} <span style="color: #8cc4ff;">Node</span>;

<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">head</span>;
<span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">tail</span>;

<span style="color: #8cc4ff;">void</span> <span style="color: #fce94f;">InitFIFO</span>(<span style="color: #8cc4ff;">void</span>)
{
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">sentinel</span>;

    /* This algorithm relies on the fix-size slots management */
    InitSlots();

    /* Sentinel slots */
    head = tail = GetSlot();
    sentinel = DecodeSlotID(head);
    sentinel-&gt;next = NULL_ID;
}

/*
  Origin Algorithm:
  E01: node = new node()
  E02: node-&gt;value = value
  E03: node-&gt;next.ptr = <span style="color: #e9b2e3;">NULL</span>
  E04: loop
  E05:   tail = Q-&gt;Tail
  E06:   next = tail.ptr-&gt;next
  E07:   <span style="color: #b4fa70;">if</span> tail == Q-&gt;Tail
  E08:     <span style="color: #b4fa70;">if</span> next.ptr == <span style="color: #e9b2e3;">NULL</span>
  E09:       <span style="color: #b4fa70;">if</span> CAS(&amp;tail.ptr-&gt;next, next, &lt;node, next.count+1&gt;)
  E10:         <span style="color: #b4fa70;">break</span>
  E11:       endif
  E12:     <span style="color: #b4fa70;">else</span>
  E13:       CAS(&amp;Q-&gt;Tail, tail, &lt;next.ptr, tail.count+1&gt;)
  E14:     endif
  E15:   endif
  E16: endloop
  E17: CAS(&amp;Q-&gt;Tail, tail, &lt;node, tail.count+1&gt;)
*/
bool Enqueue(<span style="color: #8cc4ff;">DATA</span> <span style="color: #fcaf3e;">data</span>)
{
    SLOTID newid;
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">newnode</span>;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">oldtail</span>;
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">oldtailnode</span>;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">nextid</span>;
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">nextnode</span>;

    /* E01 */
    newid = GetSlot();
    newnode = DecodeSlotID(newid);
    <span style="color: #b4fa70;">if</span> (newnode == <span style="color: #e9b2e3;">NULL</span>) <span style="color: #b4fa70;">return</span> FALSE;
    /* E02 */
    newnode-&gt;data = data;
    /* E03 */
    newnode-&gt;next = NULL_ID;
    /* E04 */
    <span style="color: #b4fa70;">do</span> {
        /* E05 */
        oldtail = tail;
        oldtailnode = DecodeSlotID(oldtail);
        /* E06 */
        nextid = oldtailnode-&gt;next;
        nextnode = DecodeSlotID(nextid);
        /* E07 */
        <span style="color: #b4fa70;">if</span> (oldtail == tail)
        {
            /* E08 */
            <span style="color: #b4fa70;">if</span> (nextnode == <span style="color: #e9b2e3;">NULL</span>)
            {
                /* E09 */
                <span style="color: #b4fa70;">if</span> (SLOTID_CAS(&amp;oldtailnode-&gt;next, next, newid))
                {
                    /* E10 */
                    <span style="color: #b4fa70;">break</span>;
                /* E11 */
                }
            }
            /* E12 */
            <span style="color: #b4fa70;">else</span>
            {
                /* E13 */
                SLOTID_CAS(&amp;tail, oldtail, next);
            /* E14 */
            }
        /* E15 */
        }
    /* E16 */
    } <span style="color: #b4fa70;">while</span>(1);
    /* E17 */
    SLOTID_CAS(&amp;tail, oldtail, newid);

    <span style="color: #b4fa70;">return</span> TRUE;
}

/*
  Origin Algorithm:
  D01:  loop
  D02:    head = Q-&gt;Head
  D03:    tail = Q-&gt;Tail
  D04:    next = head-&gt;next
  D05:    <span style="color: #b4fa70;">if</span> head == Q-&gt;Head
  D06:      <span style="color: #b4fa70;">if</span> head.ptr == tail.ptr
  D07:        <span style="color: #b4fa70;">if</span> next.ptr == <span style="color: #e9b2e3;">NULL</span>
  D08:          <span style="color: #b4fa70;">return</span> FALSE
  D09:        endif
  D10:        CAS(&amp;Q-&gt;Tail, tail, &lt;next.ptr, tail.count+1&gt;)
  D11:      <span style="color: #b4fa70;">else</span>
  D12:        *pvalue = next.ptr-&gt;value
  D13:        <span style="color: #b4fa70;">if</span> CAS(&amp;Q-&gt;Head, head, &lt;next.ptr, head.count+1&gt;)
  D14:          <span style="color: #b4fa70;">break</span>
  D15:        endif
  D16:      endif
  D17:    endif
  D18:  endloop
  D19:  free(head.ptr)
  D20:  <span style="color: #b4fa70;">return</span> TRUE
*/
bool Dequeue(<span style="color: #8cc4ff;">DATA</span> *<span style="color: #fcaf3e;">pdata</span>)
{
    SLOTID oldhead
    Node *oldheadnode;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">oldtail</span>;
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">oldtailnode</span>;
    <span style="color: #8cc4ff;">SLOTID</span> <span style="color: #fcaf3e;">next</span>;
    <span style="color: #8cc4ff;">Node</span> *<span style="color: #fcaf3e;">nextnode</span>;

    /* D01 */
    <span style="color: #b4fa70;">do</span> {
        /* D02 */
        oldhead = head;
        oldheadnode = DecodeSlotID(oldhead);
        /* D03 */
        oldtail = tail;
        oldtailnode = DecodeSlotID(oldtail);
        /* D04 */
        next = oldhead-&gt;next;
        nextnode = DecodeSlotID(next);
        /* D05 */
        <span style="color: #b4fa70;">if</span> (oldhead == head)
        {
            /* D06 */
            <span style="color: #b4fa70;">if</span> (headnode == tailnode)
            {
                /* D07 */
                <span style="color: #b4fa70;">if</span> (nextnode == <span style="color: #e9b2e3;">NULL</span>)
                {
                    /* D08 */
                    <span style="color: #b4fa70;">return</span> FALSE;
                /* D09 */
                }
                /* D10 */
                SLOTID_CAS(&amp;tail, oldtail, next);
            }
            /* D11 */
            <span style="color: #b4fa70;">else</span>
            {
                /* D12 */
                *pdata = nextnode-&gt;data;
                /* D13 */
                <span style="color: #b4fa70;">if</span> (SLOTID_CAS(&amp;head, oldhead, next)
                {
                    /* D14 */
                    <span style="color: #b4fa70;">break</span>;
                /* D15 */
                }
            /* *D16 /
            }
        /* D17 */
        }
    /* D18 */
    }
    /* D19 */
    PutSlot(oldhead);
    /* D20 */
    <span style="color: #b4fa70;">return</span> TRUE;
}
</pre>
</div>

<p>
In enqueue, E13 is the cooperative operation.
</p>

<p>
In dequeue, D10 is the cooperative operation.
</p>
</div>
</div>

<div id="outline-container-org2ebdcd1" class="outline-3">
<h3 id="org2ebdcd1"><span class="section-number-3">3.6.</span> Array Based Algorithm</h3>
<div class="outline-text-3" id="text-3-6">
<p>
Valois also introduced a array based Non-Blocking FIFO algorithm<sup><a id="fnr.18" class="footref" href="#fn.18" role="doc-backlink">18</a></sup>, but it's
not feasible on real machine because it requires CAS on unaligned memory region.
</p>
</div>
</div>

<div id="outline-container-org03835bd" class="outline-3">
<h3 id="org03835bd"><span class="section-number-3">3.7.</span> Conclusion</h3>
<div class="outline-text-3" id="text-3-7">
<p>
This article introduces a link-listed based Non-Blocking algorithm for FIFO
queue. It's based on the "Fix-size Slots Management"[2], and feasible on the
platforms that support CAS.
</p>

<hr>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Non-blocking synchronization from Wikipedia
<a href="http://en.wikipedia.org/wiki/Lock-free_and_wait-free_algorithms#Wait-freedom">http://en.wikipedia.org/wiki/Lock-free_and_wait-free_algorithms#Wait-freedom</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
J.D. Valois, Lock-Free Data Structures PhD Thesis, Rensselaer Polytechnic Institute, Department of Computer
Science, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Maged M. Michael, Michael L. Scott Correction of a Memory Management Method for Lock-Free Data Structures,
Department of Computer Science University of Rochester, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Maged M. Michael Michael L. Scott, Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue
Algorithms,, Department of Computer Science University of Rochester, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Some notes on lock-free and wait-free algorithms <a href="http://www.audiomulch.com/~rossb/code/lockfree">http://www.audiomulch.com/~rossb/code/lockfree</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Compare-and-swap from Wikipedia <a href="http://en.wikipedia.org/wiki/Compare-and-swap">http://en.wikipedia.org/wiki/Compare-and-swap</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
ABA problem from Wikipedia <a href="http://en.wikipedia.org/wiki/ABA_problem">http://en.wikipedia.org/wiki/ABA_problem</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
J.D. Valois, Lock-Free Data Structures PhD Thesis, Rensselaer Polytechnic Institute, Department of Computer
Science, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Maged M. Michael, Michael L. Scott Correction of a Memory Management Method for Lock-Free Data Structures,
Department of Computer Science University of Rochester, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.10" class="footnum" href="#fnr.10" role="doc-backlink">10</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
"Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M"
(PDF). Retrieved on 2007-12-15.
</p></div></div>

<div class="footdef"><sup><a id="fn.11" class="footnum" href="#fnr.11" role="doc-backlink">11</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Load-Link/Store-Conditional from Wikipedia <a href="http://en.wikipedia.org/wiki/Load-Link/Store-Conditional">http://en.wikipedia.org/wiki/Load-Link/Store-Conditional</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.12" class="footnum" href="#fnr.12" role="doc-backlink">12</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
"Power ISA Version 2.05". Power.org (2007-10-23). Retrieved on 2007-12-18.
</p></div></div>

<div class="footdef"><sup><a id="fn.13" class="footnum" href="#fnr.13" role="doc-backlink">13</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Maged M. Michael Michael L. Scott, Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue
Algorithms,, Department of Computer Science University of Rochester, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.14" class="footnum" href="#fnr.14" role="doc-backlink">14</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
ABA problem from Wikipedia <a href="http://en.wikipedia.org/wiki/ABA_problem">http://en.wikipedia.org/wiki/ABA_problem</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.15" class="footnum" href="#fnr.15" role="doc-backlink">15</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
ZC Miao, Non-Blocking Algorithm - Fix-size Slots Management, revision 2008-12-04
</p></div></div>

<div class="footdef"><sup><a id="fn.16" class="footnum" href="#fnr.16" role="doc-backlink">16</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Double Compare And Swap from Wikipedia
<a href="http://en.wikipedia.org/wiki/Double_Compare_And_Swap">http://en.wikipedia.org/wiki/Double_Compare_And_Swap</a>
</p></div></div>

<div class="footdef"><sup><a id="fn.17" class="footnum" href="#fnr.17" role="doc-backlink">17</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
J.D. Valois, Lock-Free Data Structures PhD Thesis, Rensselaer Polytechnic Institute, Department of Computer
Science, 1995.
</p></div></div>

<div class="footdef"><sup><a id="fn.18" class="footnum" href="#fnr.18" role="doc-backlink">18</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
J.D. Valois, Implementing Lock-Free Queues
</p></div></div>


</div>
</div><div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-algorithm.html">algorithm</a> <a href="http://miaozc.me/tag-non-blocking.html">non-blocking</a> </div>
]]></description>
  <category><![CDATA[algorithm]]></category>
  <category><![CDATA[non-blocking]]></category>
  <link>http://miaozc.me/2008-12-05-non-blocking-algorithms.html</link>
  <guid>http://miaozc.me/2008-12-05-non-blocking-algorithms.html</guid>
  <pubDate>Fri, 05 Dec 2008 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Timer In Bash]]></title>
  <description><![CDATA[

<div id="outline-container-orgb8aa0ac" class="outline-2">
<h2 id="orgb8aa0ac">SYNOPSIS</h2>
<div class="outline-text-2" id="text-orgb8aa0ac">
<div class="org-src-container">
<pre class="src src-bash"><span style="color: #73d216;">#</span><span style="color: #73d216;">function : begin_timer HANDLER_NAME MICROSECONDS CMD_ON_TIMEOUT ARGS...</span>
<span style="color: #73d216;"># </span><span style="color: #73d216;">@HANDLER_NAME :  handler of timer</span>
<span style="color: #73d216;"># </span><span style="color: #73d216;">@MICROSECONDS :  micro seconds to wait</span>
<span style="color: #73d216;"># </span><span style="color: #73d216;">@CMD_ON_TIMEOUT ARGS : command and its arguments to run when timeout</span>
<span style="color: #fce94f;">start_timer</span>(){
    [ $<span style="color: #fcaf3e;">#</span> -lt 2 ] &amp;&amp; <span style="color: #b4fa70;">return</span> 1
    <span style="color: #fcaf3e;">HANDLER</span>=$<span style="color: #fcaf3e;">1</span>
    <span style="color: #fcaf3e;">TIMER</span>=$<span style="color: #fcaf3e;">2</span>
    <span style="color: #e090d7;">shift</span> 2
    (
        <span style="color: #b4fa70;">trap exit</span> USR1
        sleep $<span style="color: #fcaf3e;">TIMER</span>
        <span style="color: #e9b96e;">"$@"</span>
        )&amp;
    <span style="color: #e090d7;">eval</span> export $<span style="color: #fcaf3e;">HANDLER</span>=$<span style="color: #fcaf3e;">!</span>
}
<span style="color: #e090d7;">export</span> -f start_timer

<span style="color: #73d216;">#</span><span style="color: #73d216;">function : kill_timer HANDLER_NAME</span>
<span style="color: #73d216;"># </span><span style="color: #73d216;">@HANDLER_NAME : timer handler to indicate which timer to kill</span>
<span style="color: #fce94f;">kill_timer</span>(){
    <span style="color: #e090d7;">kill</span> -USR1 ${<span style="color: #fcaf3e;">!</span>1}
}
<span style="color: #e090d7;">export</span> -f kill_timer
</pre>
</div>
</div>
</div>

<div id="outline-container-org15fb899" class="outline-2">
<h2 id="org15fb899">SAMPLE USAGE</h2>
<div class="outline-text-2" id="text-org15fb899">
</div>
<div id="outline-container-org25fbb7b" class="outline-3">
<h3 id="org25fbb7b">Wait for user input in 5 seconds</h3>
<div class="outline-text-3" id="text-org25fbb7b">
<div class="org-src-container">
<pre class="src src-bash"><span style="color: #73d216;">#</span><span style="color: #73d216;">!/bin/</span><span style="color: #b4fa70;">sh</span>

<span style="color: #b4fa70;">trap exit</span> USR1

<span style="color: #fce94f;">timeout</span>(){
    <span style="color: #e090d7;">echo</span> timeout
    <span style="color: #e090d7;">kill</span> -USR1 $<span style="color: #fcaf3e;">1</span>
}

start_timer HANDLER $(<span style="color: #fa8072;">( 5 * 1000 * 1000 </span>)) timeout $<span style="color: #fcaf3e;">$</span>
<span style="color: #e090d7;">echo</span> -n <span style="color: #e9b96e;">"READ : "</span>
<span style="color: #e090d7;">read</span> F
kill_timer HANDLER
<span style="color: #e090d7;">echo</span> <span style="color: #e9b96e;">"GOT : "</span>$<span style="color: #fcaf3e;">F</span>
</pre>
</div>

<p>
<b>Notice</b>
</p>

<p>
trap TERM HUP QUIT yourself, since if you terminated the process before got any input, timeout event handler will not
terminated automatically. You can call kill<sub>timer</sub> in you trap handler.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-bash.html">bash</a> </div>
]]></description>
  <category><![CDATA[bash]]></category>
  <link>http://miaozc.me/2008-12-04-timer-in-bash.html</link>
  <guid>http://miaozc.me/2008-12-04-timer-in-bash.html</guid>
  <pubDate>Thu, 04 Dec 2008 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Generic Atomic Object (GAO) - A Non-Blocking FIFO Queue]]></title>
  <description><![CDATA[

<div id="outline-container-orga62c9fd" class="outline-2">
<h2 id="orga62c9fd">Problem</h2>
<div class="outline-text-2" id="text-orga62c9fd">
<p>
Implement a FIFO Queue used by concurrent writers and readers, which is lock-free algorithm and with non-blocking
interface.
</p>
</div>
</div>


<div id="outline-container-org64b2cb9" class="outline-2">
<h2 id="org64b2cb9">GAO Based Algorithm</h2>
<div class="outline-text-2" id="text-org64b2cb9">
<p>
Here we use a GAO based algorithm to solve the problem.
</p>
</div>

<div id="outline-container-org9ccb6ba" class="outline-3">
<h3 id="org9ccb6ba">Data Structures</h3>
<div class="outline-text-3" id="text-org9ccb6ba">
<ul class="org-ul">
<li><p>
LINK<sub>NODE</sub>
</p>

<p>
A link node has these data fields:
</p></li>
</ul>

<pre class="example" id="orgc8b559f">
  {
    DATA                 data;
    SHPOINTER&lt;LINK_NODE&gt; next_node;
  }
</pre>

<ul class="org-ul">
<li><p>
FIFO<sub>STATE</sub>
</p>

<p>
FIFO<sub>STATE</sub> is a type of GAO Object that atomically maintains a data structure with these data fields:
</p></li>
</ul>

<pre class="example" id="org823272c">
  {
    SHPOINTER&lt;LINK_NODE&gt; header;
    SHPOINTER&lt;LINK_NODE&gt; tail;
    LINK_NODE            new_node;
  }
</pre>
</div>
</div>

<div id="outline-container-org15872ae" class="outline-3">
<h3 id="org15872ae">Pseudo Code</h3>
<div class="outline-text-3" id="text-org15872ae">
<div class="org-src-container">
<pre class="src src-c++"><span style="color: #73d216;">/* </span><span style="color: #73d216;">Init state</span><span style="color: #73d216;"> */</span>
<span style="color: #8cc4ff;">FIFO_STATE</span> <span style="color: #fcaf3e;">current_state</span> =
{
  .header = <span style="color: #e9b2e3;">NULL</span>;
  .tail   = <span style="color: #e9b2e3;">NULL</span>;
}

<span style="color: #73d216;">/* </span><span style="color: #73d216;">Lambda object for GAO::ReserveAndLoad</span><span style="color: #73d216;"> */</span>
<span style="color: #8cc4ff;">FIFO_STATE</span> <span style="color: #fce94f;">FIFO_STATE_Load</span>(<span style="color: #8cc4ff;">FIFO_STATE</span> <span style="color: #fcaf3e;">data</span>)
{
}

<span style="color: #8cc4ff;">DATA</span> <span style="color: #fce94f;">FIFO_State_Store</span>(<span style="color: #8cc4ff;">FIFO_STATE</span> <span style="color: #fcaf3e;">data</span>)
{
}

<span style="color: #fce94f;">FIFO_Enqueue</span>(<span style="color: #8cc4ff;">Data</span> <span style="color: #fcaf3e;">d</span>)
{
  <span style="color: #8cc4ff;">FIFO_STATE</span> <span style="color: #fcaf3e;">tmp_state</span>;
  <span style="color: #8cc4ff;">TOKEN</span>      <span style="color: #fcaf3e;">r</span>;

  r = current_state.ReserveAndLoad(FIFO_STATE_Load, &amp;tmp_state);
}
</pre>
</div>
</div>
</div>
</div>


<div id="outline-container-org72b9ddb" class="outline-2">
<h2 id="org72b9ddb">See Also</h2>
<div class="outline-text-2" id="text-org72b9ddb">
<ul class="org-ul">
<li>"Implementing lock-free queues" by John D. Valois</li>
</ul>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-algorithm.html">algorithm</a> <a href="http://miaozc.me/tag-non-blocking.html">non-blocking</a> </div>
]]></description>
  <category><![CDATA[algorithm]]></category>
  <category><![CDATA[non-blocking]]></category>
  <link>http://miaozc.me/2008-11-19-generic-atomic-object.html</link>
  <guid>http://miaozc.me/2008-11-19-generic-atomic-object.html</guid>
  <pubDate>Wed, 19 Nov 2008 00:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[使用KGDB调试Linux内核]]></title>
  <description><![CDATA[


<div id="outline-container-org6ff43c3" class="outline-2">
<h2 id="org6ff43c3">简介</h2>
<div class="outline-text-2" id="text-org6ff43c3">
<p>
从 2.6.25 开始，Linux 主干内核开始内置了代码级调试器 kgdb。通过 kgdb，开发者就可以在内核代码中设置断点，单步调试和观察变
量。为了使用 kgdb，你需要有两个系统。一个作为开发系统，一个作为测试系统嗯。两台机器通过串口线连接。需要调试的内核运行在
测试己其上。串口线用于 gdb 连接远程目标。kgdb 已经还可以支持通过以太网连接两台机器，不过目前内核中(2.6.26)还没有这部分代
码。本文通过 qemu 模拟器运行 2.6.26 的 内核作为测试系统，并通过 qemu 的虚拟TCP串口设备功能，使开发系统的 gdb 可以通过连
接本地 tcp 端口调试内核。本文使用的开发系统：Fedora 9, 2.6.25.10-86.fc9.i686 QEMU PC emulator version 0.9.1, Copyright
(c) 2003-2008 Fabrice Bellard GNU gdb Fedora (6.8-11.fc9) gcc (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)注：当使用 qemu 的时
候， 可以直接使用 qemu -s -S 功能调试，不需要 KGDB 的支持，这里的例子是模拟一个类似调试真实平台的例子。
</p>
</div>
</div>

<div id="outline-container-org3b3e2e3" class="outline-2">
<h2 id="org3b3e2e3">配置和启动</h2>
<div class="outline-text-2" id="text-org3b3e2e3">
</div>
<div id="outline-container-org4e21df3" class="outline-3">
<h3 id="org4e21df3">内核选项</h3>
<div class="outline-text-3" id="text-org4e21df3">
<p>
kgdb 选项 ：
</p>

<ul class="org-ul">
<li>CONFIG<sub>KGDB</sub>=y</li>
<li>CONFIG<sub>KGDB</sub><sub>SERIAL</sub><sub>CONSOLE</sub>=y</li>
</ul>

<p>
选项在 Kernel hacking 里可以找到
同时，为了能在系统运行时中断系统并出发远程 gdb，必须打开内核 Magic Sys-Rq 键选项 ：
</p>

<ul class="org-ul">
<li>CONFIG<sub>MAGIC</sub><sub>SYSRQ</sub>=y</li>
</ul>

<p>
打开内核符号调试：
</p>

<ul class="org-ul">
<li>CONFIG<sub>DEBUG</sub><sub>INFO</sub>=y</li>
</ul>

<p>
注意事项：
</p>

<ul class="org-ul">
<li>CONFIG<sub>DEBUG</sub><sub>RODATA</sub> 必须被禁用，否则kgdb讲无法正常使用。</li>
</ul>
</div>
</div>

<div id="outline-container-org1c3c553" class="outline-3">
<h3 id="org1c3c553">启动 qemu</h3>
<div class="outline-text-3" id="text-org1c3c553">
<div class="org-src-container">
<pre class="src src-bash">qemu ${<span style="color: #fcaf3e;">QEMU_ARGS</span>} <span style="color: #e9b96e;">\</span>
    -kernel <span style="color: #e9b96e;">"$VMLINUZ"</span> <span style="color: #e9b96e;">\</span>
    -append <span style="color: #e9b96e;">"${KERNEL_CMDLINE} kgdboc=ttyS0,115200 kgdbwait"</span> <span style="color: #e9b96e;">\</span>
    -serial tcp::${<span style="color: #fcaf3e;">KGDB_TCPPORT</span>},server <span style="color: #e9b96e;">\</span>
    -hda <span style="color: #e9b96e;">"${QEMU_HDA}"</span> &gt;/dev/null &amp;
</pre>
</div>

<p>
qemu 选项中：
</p>

<ul class="org-ul">
<li>-kernel 编译好的内核，压缩过的</li>
<li>-append 传给 kernel 的命令行选项</li>
<li>-serial 使系统的第一个串口与本地的 TCP 端口关联起来，用于模拟终端，这样gdb就可以连接到目标系统而不用串口线了。</li>
<li>-hda 用于运行开发系统的Linux系统qemu硬盘。你也可以在用 nfs root 启动系统，但qemu必须要求你指定至少一个qemu硬盘，你可以使</li>
</ul>
<p>
用空的硬盘，用qemu-img工具创建。
</p>

<p>
kernel 选项中：
</p>

<p>
kgdboc 的意思是 kgdb over console，这里将kgdb连接的console设置为ttyS0，波特率为115200 kgdbwait 使 kernel 在启动过程中等
待 gdb 的连接。
</p>
</div>
</div>

<div id="outline-container-org1acc4ca" class="outline-3">
<h3 id="org1acc4ca">gdb 连接测试系统</h3>
<div class="outline-text-3" id="text-org1acc4ca">
<p>
qemu 启动后会等待 gdb 连接  tcp 端口以启动模拟串口。
</p>

<p>
运行下面的命令启动gdb，如果没设置KGDB<sub>GDB变量</sub>，默认用 gdbtui 启动，其中 VMLINUX 是未压缩的 kernel 文件。
</p>

<pre class="example" id="org247a92e">
${KGDB_GDB:-gdbtui} $VMLINUX
</pre>

<p>
设置波特率
</p>

<pre class="example" id="org5c9bb28">
(gdb) set remotebaud 115200
</pre>

<p>
连接目标
</p>

<pre class="example" id="org14e0949">
(gdb) target remote tcp:localhost:${KGDB_TCPPORT}
</pre>

<p>
连接成功后由于启动了 kgdbwait 选项，kgdb 会在内核启动的某个阶段得到控制权：
</p>

<pre class="example" id="orgfd2bf8e">
Remote debugging using tcp:localhost:4555
kgdb_register_io_module (new_kgdb_io_ops=&lt;value optimized out&gt;)
    at /data/home/hellwolf/mydoc/prog/linux/linux-2.6/kernel/kgdb.c:1674
(gdb)
</pre>

<p>
现在就可以开始使用 kgdb 调试内核了。
</p>
</div>
</div>
</div>

<div id="outline-container-orgcbb4e41" class="outline-2">
<h2 id="orgcbb4e41">基本功能</h2>
<div class="outline-text-2" id="text-orgcbb4e41">
</div>
<div id="outline-container-org5d87422" class="outline-3">
<h3 id="org5d87422">杀死 gdb</h3>
<div class="outline-text-3" id="text-org5d87422">
<p>
如果 gdb 遇到问题无法相应了，可以在测试系统上运行下列命令中断调试：
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #e090d7;">echo</span> -e <span style="color: #e9b96e;">"\003"</span> &gt; /dev/ttyS1
</pre>
</div>

<p>
如果你重启系统了，gdb 也需要重新连接系统。
</p>
</div>
</div>

<div id="outline-container-orgaaf7d35" class="outline-3">
<h3 id="orgaaf7d35">中断测试系统</h3>
<div class="outline-text-3" id="text-orgaaf7d35">
<p>
为了在测试系统运行的时候让 gdb 获得控制权，需要使用 Sys-Rq。关于 Sys-Rq 的详细设置方法，见 Documentation/sysrq.txt。 你
可以在系统运行时键盘上输入 Sys Rq+g，然后 gdb 就会出现：
</p>

<pre class="example" id="orgd295975">
Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread -1]
sysrq_handle_gdb (key=103, tty=0xc7869800)
    at /data/home/hellwolf/mydoc/prog/linux/linux-2.6/kernel/kgdb.c:1674
(gdb)
</pre>

<p>
如果你不知道如何在键盘上输入，或者你需要程序控制，则可以用下列等价命令模拟：
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #73d216;"># </span><span style="color: #73d216;">echo g &gt; /proc/sysrq-trigger</span>
</pre>
</div>
</div>
</div>

<div id="outline-container-org8663164" class="outline-3">
<h3 id="org8663164">继续执行测试系统</h3>
<div class="outline-text-3" id="text-org8663164">
<pre class="example" id="orgd600261">
(gdb) c
</pre>

<p>
即可
</p>
</div>
</div>

<div id="outline-container-org039cad1" class="outline-3">
<h3 id="org039cad1">设置断点，查询变量，单步调试，和调用堆栈</h3>
<div class="outline-text-3" id="text-org039cad1">
<p>
这些都和调试普通程序一样，比如：
</p>

<pre class="example" id="org130cfa6">
(gdb) b	sys_open
Breakpoint 1 at 0xc046d268: file /data/home/hellwolf/mydoc/prog/linux/linux-2.6/
fs/open.c, line 1107.
(gdb) c
Continuing.
[New Thread 612]
[Switching to Thread 612]

Breakpoint 1, sys_open (filename=0xb7f68a9c "/etc/ld.so.cache", flags=0,
    mode=0) at /data/home/hellwolf/mydoc/prog/linux/linux-2.6/fs/open.c:1107
(gdb) p filename
$1 = 0xb7f68a9c "/etc/ld.so.cache"
(gdb)n
(gdb)bt
#0  sys_open (filename=0xb7f68a9c "/etc/ld.so.cache", flags=0, mode=0)
    at /data/home/hellwolf/mydoc/prog/linux/linux-2.6/fs/open.c:1113
#1  0xc0403976 in system_call ()
    at /data/home/hellwolf/mydoc/prog/linux/linux-2.6/arch/x86/kernel/entry_32.S
:377
#2  0x00000000 in ?? ()
</pre>
</div>
</div>

<div id="outline-container-orgaa5a21b" class="outline-3">
<h3 id="orgaa5a21b">局限性</h3>
<div class="outline-text-3" id="text-orgaa5a21b">
<p>
kgdb 不支持 tracepoints 和 watchpoints，除非有硬件调试器支持。
</p>

<p>
kgdb 的 threads 也无法正常使用。
</p>
</div>
</div>


<div id="outline-container-org47cab1c" class="outline-3">
<h3 id="org47cab1c">GDB 脚本</h3>
<div class="outline-text-3" id="text-org47cab1c">
<p>
gdb 可以定义 sequences 脚本, 功能局限，但是可以用来简化一些工作。比如在 gdb 调试状态下 lsmod 的脚本：
</p>

<pre class="example" id="org97069f6">
set $_lsmod_modules = modules-&gt;next
#       1        10   15
printf "Module          Size\n"
while $_lsmod_modules != &amp;modules
	set $_lsmod_module = (struct module*)((unsigned char*)$_lsmod_modules-(unsigned int)&amp;(((struct module*)0)-&gt;list))
	printf "%-15s %d\n", $_lsmod_module-&gt;name, $_lsmod_module-&gt;init_size + $_lsmod_module-&gt;core_size
	set $_lsmod_modules = $_lsmod_modules-&gt;next
end
</pre>

<p>
用 source 命令可以读入外部的 gdb 命令序列文件。
</p>

<p>
gdb 脚本最大的局限性在于，没有内置的字符串比较功能，比如我要得到一个(struct module*)，我必须遍历模块列表然后做字符串匹配。
这里我用了一个比较特殊的解决办法，我定义了两个gdb sequences :
</p>

<pre class="example" id="org008f325">
define xsrun
	if $argc == 0
		printf "Usage : xsrun xsourcecmd args...\n"
	else
		shell rm -f /tmp/*.xsource
		shell echo 0 &gt; /tmp/seq.xsource
		if $argc == 1
			xsource '$arg0'
		end
		if $argc == 2
			xsource '$arg0' '$arg1'
		end
		if $argc == 3
			xsource '$arg0' '$arg1' '$arg2'
		end
		if $argc == 4
			xsource '$arg0' '$arg1' '$arg2' '$arg3'
		end
		if $argc == 5
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4'
		end
		if $argc == 6
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5'
		end
		if $argc == 7
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6'
		end
		if $argc == 8
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7'
		end
		if $argc == 9
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7' '$arg8'
		end
		if $argc == 10
			xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7' '$arg8' '$arg9'
		end
	end
end

define xsource
	if $argc == 1
		shell $TOOLSDIR/kgdb-xsource '$arg0'
	end
	if $argc == 2
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1'
	end
	if $argc == 3
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2'
	end
	if $argc == 4
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3'
	end
	if $argc == 5
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4'
	end
	if $argc == 6
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5'
	end
	if $argc == 7
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6'
	end
	if $argc == 8
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7'
	end
	if $argc == 9
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7' '$arg8'
	end
	if $argc == 10
		shell $TOOLSDIR/kgdb-xsource '$arg0' '$arg1' '$arg2' '$arg3' '$arg4' '$arg5' '$arg6' '$arg7' '$arg8' '$arg9'
	end

	if $argc &gt; 0
		source /tmp/current.xsource
	end
end
</pre>

<p>
其中 $TOOLSDIR/kgdb-xsource 是我自定义的一个寻找名字为 '$arg0' 的 xsource 脚本的工具，我的实现就是在某个目录下找名字为
$arg0 的文件：
</p>

<pre class="example" id="orge9db7ea">
$ cat tools/kgdb-xsource
#!/bin/bash
. $(dirname "$0")/common.sh

if [ "$#" == 0 ];then
	echo "kgdb-xsource xsourcecmd args...\\n\"" &gt; /tmp/current.xsource
else
	XSOURCECMD=$1
	shift
	XSOURCESEQ=$(cat /tmp/seq.xsource)
	XSOURCESEQ=$((${XSOURCESEQ}+1))
	echo ${XSOURCESEQ} &gt; /tmp/seq.xsource
	XSOURCEOFILE=/tmp/${XSOURCESEQ}-${XSOURCECMD}.xsource
	if [ -f "$XSOURCEDIR/$XSOURCECMD" ] &amp;&amp; [ -x "$XSOURCEDIR/$XSOURCECMD" ];then
		$XSOURCEDIR/$XSOURCECMD "$@" &gt; ${XSOURCEOFILE}
		rm -f /tmp/current.xsource
		ln -s ${XSOURCEOFILE} /tmp/current.xsource
	else
		echo "printf \"No such xsource command : $XSOURCECMD\\n\"" &gt; /tmp/current.xsource
	fi
fi
</pre>

<p>
这些脚本的目的就是，通过外部脚本生成 gdb 脚本，然后再让 gdb 执行。他首先寻找 xsource 脚本，然后运行它，得到的输出（gdb
sequences)保存到 /tmp 下的某个文件中，并链接为 /tmp/current.xsource, 然后让 gdb 执行改文件。
</p>

<p>
比如 strcmp<sub>vs</sub> 脚本，这个脚本就是为了比较内部变量和一个字符串的：
</p>

<pre class="example" id="org3837719">
$ cat tools/xsource.d/strcmp_vs
#!/usr/bin/perl
if (@ARGV != 3) {
    print "printf \"Usage : strcmp result var str\\n\"";
    exit 1
}

($result, $var, $str) = @ARGV;
print 'if ';
$i = 0;
for (0..length($str)-1) {
    $i = $_;
    $c = substr($str, $i, 1);
    print ' &amp;&amp; ' if $i;
    print "${var}[$i] == '$c'";
}
++$i;
print " &amp;&amp; ${var}[$i] == '\\0'
    set \$$result = 0
else
    set \$$result = -1
end
";
</pre>

<p>
利用这个基本命令，我们现在就可以实现 getmod 功能拉：
</p>

<pre class="example" id="orgc4e3f12">
$ cat tools/xsource.d/getmod
#!/bin/sh
[ $# != 2 ] &amp;&amp; echo "printf \"Usage : getmod modvar modname\n\"" &amp;&amp; exit 1

MODVAR=$1
MODNAME=$2
cat &lt;&lt;EOF
set \$_getmod_modules = modules-&gt;next
set \$_getmod_modfound = 0
while \$_getmod_modules != &amp;modules
	set \$_getmod_module = (struct module*)((unsigned char*)\$_getmod_modules-(unsigned int)&amp;(((struct module*)0)-&gt;list))
	xsource strcmp_vs _getmod_modfound \$_getmod_module-&gt;name $MODNAME
	if \$_getmod_modfound == 0
		set \$$MODVAR = \$_getmod_module
		set \$_getmod_modfound = 1
		loop_break
	end
	set \$_getmod_modules = \$_getmod_modules-&gt;next
end

if \$_getmod_modfound != 1
	printf "Module \\"$MODNAME\\" cannot be found\\n"
	set \$$MODVAR = 0
end
EOF
[/code]
运行范例：
[code]
(gdb) xsource getmod modvar hello
(gdb) print $modvar-&gt;sect_attrs-&gt;attrs[0]-&gt;name
$9 = 0xc7855b40 ".note.gnu.build-id"
</pre>
</div>
</div>
</div>

<div id="outline-container-org8f2a4bd" class="outline-2">
<h2 id="org8f2a4bd">调试内核模块</h2>
<div class="outline-text-2" id="text-org8f2a4bd">
<p>
调试内核模块需要额外的步骤，因为内核模块是动态载入的，gdb 一开始无法从内核 VMLINUX 文件中得到模块中的函数和变量地址信息。
这里必须用 gdb 的 add-symbol-file 命令：
</p>

<pre class="example" id="orgcda7363">
	add-symbol-file $MODFILE \\
		$TEXT_ADDR \\
		-s .data $DATA_ADDR \\
		-s .bss $BSS_ADDR
</pre>

<p>
其中 MODFILE 是 .ko 文件， 如何获得那三个地址是这里最关键的。这里有两种方法：
</p>

<ol class="org-ol">
<li>从 sysfs 中获得</li>
</ol>

<p>
这种方法比较简单：
</p>

<pre class="example" id="org080117e">
$ cat /sys/module/snd/sections/.text
0xf8f83000
$ cat /sys/module/snd/sections/.data
0xf8f8d040
$ cat /sys/module/snd/sections/.bss
0xf8f8e280
</pre>

<ol class="org-ol">
<li>用 gdb 脚本</li>
</ol>

<p>
这个脚本先通过上面的 getmod 脚本得到(struct module*)，然后从里面得到所需要的 sections 的地址，最后调用 add-symbol-file
命令。不过因为有大量的 gdb 交互，所以会比较慢 :)
</p>

<pre class="example" id="org9ecf49a">
$ cat tools/xsource.d/addmod2gdb
#!/bin/sh
# addmod2gdb($modname)
[ $# != 1 ] &amp;&amp; echo "printf \"Usage : addmod2gdb modname\n\"" &amp;&amp; exit 1

MODNAME=$1
MODFILE=$KMODSDIR/$MODNAME/${MODNAME}.ko
if [ -f $MODFILE ];then
	cat &lt;&lt;EOF
xsource getmod _addmod2gdb_mod $MODNAME
if \$_addmod2gdb_mod != 0
	set \$_addmod2gdb_i = 0
	set \$_addmod2gdb_c = 0
	while \$_addmod2gdb_i &lt; \$_addmod2gdb_mod-&gt;sect_attrs-&gt;nsections
		if \$_addmod2gdb_c == 3
			loop_break
		end
		xsource strcmp_vs _addmod2gdb_r \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].name .text
		if \$_addmod2gdb_r == 0
			set \$_addmod2gdb_text = \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].address
			set \$_addmod2gdb_c = \$_addmod2gdb_c + 1
			set \$_addmod2gdb_i = \$_addmod2gdb_i + 1
			loop_continue
		end

		xsource strcmp_vs _addmod2gdb_r \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].name .data
		if \$_addmod2gdb_r == 0
			set \$_addmod2gdb_data = \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].address
			set \$_addmod2gdb_c = \$_addmod2gdb_c + 1
			set \$_addmod2gdb_i = \$_addmod2gdb_i + 1
			loop_continue
		end

		xsource strcmp_vs _addmod2gdb_r \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].name .bss
		if \$_addmod2gdb_r == 0
			set \$_addmod2gdb_bss = \$_addmod2gdb_mod-&gt;sect_attrs-&gt;attrs[\$_addmod2gdb_i].address
			set \$_addmod2gdb_c = \$_addmod2gdb_c + 1
			set \$_addmod2gdb_i = \$_addmod2gdb_i + 1
			loop_continue
		end

		set \$_addmod2gdb_i = \$_addmod2gdb_i + 1
	end

	add-symbol-file $MODFILE \\
		\$_addmod2gdb_text \\
		-s .data \$_addmod2gdb_data \\
		-s .bss \$_addmod2gdb_bss
end
EOF
else
	echo "printf \"No such module file : $MODFILE\n\""
fi

</pre>
</div>
</div>

<div id="outline-container-org33cc293" class="outline-2">
<h2 id="org33cc293">参考资料</h2>
<div class="outline-text-2" id="text-org33cc293">
<ul class="org-ul">
<li>官方网站 <a href="http://kgdb.linsyssoft.com/">http://kgdb.linsyssoft.com/</a></li>
</ul>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-linux kernel.html">linux kernel</a> </div>
]]></description>
  <category><![CDATA[linux kernel]]></category>
  <link>http://miaozc.me/2008-07-22-kgdb-linux.html</link>
  <guid>http://miaozc.me/2008-07-22-kgdb-linux.html</guid>
  <pubDate>Sun, 20 Jul 2008 19:05:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[用ldscript实现编译期功能插入]]></title>
  <description><![CDATA[

<div id="outline-container-org723c0d3" class="outline-2">
<h2 id="org723c0d3">动机</h2>
<div class="outline-text-2" id="text-org723c0d3">
<p>
设想，如果你想在程序中支持多种后端(backends)，但在开发过程中并不能预计会有多少种。一般来说，会想着抽象出这种后端的描述，
然后用动态模块的方式，如 shared library 实现所谓的插件。使用插件，可以实现动态的功能插入，但如果你不想动态的功能插入，所
有功能在编译期间就已经确定呢。当然你可以使用一个数组硬编码维护，但这样增删功能就需要改代码，这里介绍一种使用 ld script
的方法。这种方法在 linux kernel 的代码中也使用到了。
</p>
</div>
</div>


<div id="outline-container-orge831527" class="outline-2">
<h2 id="orge831527">关于 ld script</h2>
<div class="outline-text-2" id="text-orge831527">
<p>
即使你不知道， ld script 在每次你链接程序的时候都被使用了，ld程序自带一个默认的脚本，如果你不指定其他的脚本就使用默认的。
ld script 的作用是描述如何组织从目标文件中得到的所有段，最终链接成最终的 elf 输出。关于 ld script 更多的信息，可以参考
ld 的 info page。
</p>
</div>
</div>


<div id="outline-container-orgfcaa99b" class="outline-2">
<h2 id="orgfcaa99b">定义 ldscript</h2>
<div class="outline-text-2" id="text-orgfcaa99b">
<p>
这里实现一个简单的示例程序，结构如下：主程序遍历一个外部静态数组，打印里面的所有字符串，直到结束；其他目标文件分别向该数
组插入一个或多个字符串，而无须修改主程序的代码或者执行额外的启动代码。
</p>

<p>
#+name main.c
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #e090d7;">#include</span> <span style="color: #e9b96e;">&lt;stdio.h&gt;</span>
<span style="color: #e090d7;">#include</span> <span style="color: #e9b96e;">&lt;string.h&gt;</span>

<span style="color: #b4fa70;">extern</span> <span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span> <span style="color: #fcaf3e;">array_begin</span>;
<span style="color: #b4fa70;">extern</span> <span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span> <span style="color: #fcaf3e;">array_end</span>;

<span style="color: #8cc4ff;">int</span> <span style="color: #fce94f;">main</span> ( <span style="color: #8cc4ff;">void</span> ){
  <span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span> *<span style="color: #fcaf3e;">array_iter</span>;
  printf( <span style="color: #e9b96e;">"array_begin : %p , array_end : %p\n"</span>, &amp;array_begin, &amp;array_end);
  <span style="color: #b4fa70;">for</span> ( array_iter = &amp;array_begin;
        array_iter &lt; &amp;array_end;
        array_iter += strlen(array_iter) + 1 ){
    printf ( <span style="color: #e9b96e;">"%3d:%s\n"</span>, strlen(array_iter), array_iter );
  }

  <span style="color: #b4fa70;">return</span> 0;
}
</pre>
</div>

<p>
其中 array<sub>begin</sub>, array<sub>end</sub> 为外部变量，他们会在 ld script 中定义。首先使用 ld &#x2013;verbose 得到一份 ld 的默认脚本（去掉开
头和结尾的多余内容输出），存为 array<sub>iter.ld</sub> 文件。 找到 .data 断的定义，修改为类似如下的内容 ：
</p>

<p>
#+name array<sub>iter.ld</sub> (partial)
</p>
<div class="org-src-container">
<pre class="src src-txt">  .data           :
  {
    array_begin = .;
    *(.extarray)
    array_end = .;

    *(.data .data.* .gnu.linkonce.d.*)
    KEEP (*(.gnu.linkonce.d.*personality*))
    SORT(CONSTRUCTORS)
  }
</pre>
</div>

<p>
其中 "*(.extarray)"的意思是，将所有输入目标文件的 .extarray 段输出到这里，并且在周围分别设上两个变量 array<sub>begin</sub>,
array<sub>end</sub>，他们就是在 main.c 中定义的外部变量。他们都被赋予了固定特殊变量"."，"."的意思是当前地址。
</p>

<p>
再来看 Makefile 如何写 ：
</p>

<p>
#+name Makefile
</p>
<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #fcaf3e;">OBJS</span>=

<span style="color: #fce94f;">array_iter</span> : extarray.h array_iter.ld main.o $(<span style="color: #fcaf3e;">OBJS</span>)
        gcc $(<span style="color: #fcaf3e;">CFLAGS</span>) -Wl,-T,array_iter.ld main.o $(<span style="color: #fcaf3e;">OBJS</span>) -o <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>

<span style="color: #fce94f;">clean</span> :
        rm -f *.o  array_iter
</pre>
</div>
</div>
</div>


<div id="outline-container-orgaed22d9" class="outline-2">
<h2 id="orgaed22d9">添加模块</h2>
<div class="outline-text-2" id="text-orgaed22d9">
<p>
在上面的 Makefile 中 OBJS 列表为空，我们现在就来添加几个模块 ：
</p>

<p>
#+name extarray.h
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #b4fa70;">typedef</span> <span style="color: #b4fa70;">const</span> <span style="color: #8cc4ff;">char</span> <span style="color: #8cc4ff;">extarray_t</span>[];

<span style="color: #e090d7;">#define</span> <span style="color: #fcaf3e;">extarray</span> extarray_t <span style="color: #b4fa70;">__attribute__</span>((section(<span style="color: #e9b96e;">".extarray"</span>)))
</pre>
</div>

<p>
#+name 1.c
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #e090d7;">#include</span> <span style="color: #e9b96e;">"extarray.h"</span>

<span style="color: #8cc4ff;">extarray</span> <span style="color: #fcaf3e;">a1</span> = <span style="color: #e9b96e;">"1"</span>;
<span style="color: #8cc4ff;">extarray</span> <span style="color: #fcaf3e;">a2</span> = <span style="color: #e9b96e;">"test 1"</span>;
<span style="color: #8cc4ff;">extarray</span> <span style="color: #fcaf3e;">a3</span> = <span style="color: #e9b96e;">""</span>;
</pre>
</div>

<p>
#+name 2.c
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #e090d7;">#include</span> <span style="color: #e9b96e;">"extarray.h"</span>

<span style="color: #8cc4ff;">extarray</span> <span style="color: #fcaf3e;">a4</span> = <span style="color: #e9b96e;">"HHIIOOIIYY"</span>;
</pre>
</div>

<p>
修改 Makefile, 添加上：
</p>

<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #fcaf3e;">OBJS</span>=1.o 2.o~
</pre>
</div>

<p>
然后执行命令 ：
</p>

<div class="org-src-container">
<pre class="src src-txt">$ make
cc -pipe -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g   -c -o main.o main.c
cc -pipe -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g   -c -o 1.o 1.c
cc -pipe -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g   -c -o 2.o 2.c
gcc -pipe -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g -Wl,-T,array_iter.ld main.o 1.o 2.o -o array_iter

$ ./array_iter
array_begin : 0x80496d8 , array_end : 0x80496ed
  1:1
  6:test 1
  0:
 10:HHIIOOIIYY
</pre>
</div>

<p>
无须修改其他文件，字符串已经被准确输出了。
</p>

<p>
再来看看内存模型 ：
</p>
<div class="org-src-container">
<pre class="src src-txt">$ objdump -t array_iter| fgrep '.data' | sort -n
080496d8 g       .data  00000000              array_begin
080496d8 g     O .data  00000002              a1
080496d8 l    d  .data  00000000              .data
080496da g     O .data  00000007              a2
080496e1 g     O .data  00000001              a3
080496e2 g     O .data  0000000b              a4
080496ed g       .data  00000000              array_end
080496f0 g       .data  00000000              __data_start
080496f0  w      .data  00000000              data_start
</pre>
</div>

<p>
注意到因为 array<sub>begin</sub>, array<sub>end</sub> 被赋予了一个常数，所以连接器没有为他们分配空间。
</p>
</div>
</div>

<div id="outline-container-org1257188" class="outline-2">
<h2 id="org1257188">现实例子</h2>
<div class="outline-text-2" id="text-org1257188">
<p>
在 PC x86 中，有多种通用的显示输出方式，常用的如 bios 提供的以字符为基础的输入输出例程，还有就是 vesa 2.0 显卡规范。在
linux x86 启动过程中，kernel 根据配置选择合适的视频输出设备。 实现中， kernel 就用到了 ldscript， 见 ：
linux-2.6/arch/x86/boot/setup.ld :
</p>

<div class="org-src-container">
<pre class="src src-txt">        .videocards     : {
                video_cards = .;
                *(.videocards)
                video_cards_end = .;
        }

linux-2.6/arch/x86/boot/video.h :
...
#define __videocard struct card_info __attribute__((section(".videocards")))
...
extern struct card_info video_cards[], video_cards_end[];
...
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-system programming.html">system programming</a> <a href="http://miaozc.me/tag-c programming.html">c programming</a> </div>
]]></description>
  <category><![CDATA[system programming]]></category>
  <category><![CDATA[c programming]]></category>
  <link>http://miaozc.me/2008-05-20-ldscript-based-plugin.html</link>
  <guid>http://miaozc.me/2008-05-20-ldscript-based-plugin.html</guid>
  <pubDate>Tue, 20 May 2008 15:02:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[冲刺ELF极限——最小ELF程序]]></title>
  <description><![CDATA[
<p>
tinyso1.S:
</p>

<div class="org-src-container">
<pre class="src src-asm"><span style="color: #73d216;">; </span><span style="color: #73d216;">&#26368;&#36817;&#30740;&#31350;ELF&#26684;&#24335;&#65292;hack&#20102;&#19968;&#25226;&#12290;</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">&#21442;&#32771;&#25991;&#26723;&#65306;</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">1&#12290; ELF_format.pdf http://www.skyfree.org/linux/references/ELF_Format.pdf</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">2&#12290;A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">&#21508;&#25991;&#20214;&#65306;</span>
<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">tinyso1.S</span>
<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>
<span style="color: #b4fa70;">.global</span> _start
<span style="color: #fce94f;">_start</span>:
    <span style="color: #b4fa70;">xor</span> <span style="color: #fcaf3e;">%eax</span>, <span style="color: #fcaf3e;">%eax</span>
    <span style="color: #b4fa70;">inc</span> <span style="color: #fcaf3e;">%eax</span>
    <span style="color: #b4fa70;">movw</span> $filesize,<span style="color: #fcaf3e;">%bx</span>
    <span style="color: #b4fa70;">int</span>  $0x80
<span style="color: #b4fa70;">.equ</span> filesize, . - _start

<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">tinyso2.S</span>
<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>
<span style="color: #73d216;">/* </span><span style="color: #73d216;">ELF Header</span><span style="color: #73d216;"> */</span>
<span style="color: #fce94f;">ehdr</span>:
    <span style="color: #73d216;">/* </span><span style="color: #73d216;">e_ident</span><span style="color: #73d216;"> */</span>
    <span style="color: #b4fa70;">.byte</span> 0x7F,'E,'L,'F
    <span style="color: #b4fa70;">.byte</span> 1 # EI_CLASS : ELFCLASS32
    <span style="color: #b4fa70;">.byte</span> 1 # EI_DATA  : ELFDATA2LSB
    <span style="color: #b4fa70;">.byte</span> 1 # EI_VERSION
    <span style="color: #b4fa70;">.rept</span> 9
        <span style="color: #b4fa70;">.byte</span> 0
    <span style="color: #b4fa70;">.endr</span>
    <span style="color: #b4fa70;">.word</span> 2        # e_type : ET_EXEC
    <span style="color: #b4fa70;">.word</span> 3        # e_machine : EM_386
    <span style="color: #b4fa70;">.int</span>  1        # e_version
    <span style="color: #b4fa70;">.int</span>  _start   # e_entry
    <span style="color: #b4fa70;">.int</span>  phdr_off # e_phoff
    <span style="color: #b4fa70;">.int</span>  0        # e_shoff
    <span style="color: #b4fa70;">.int</span>  0        # e_flags
    <span style="color: #b4fa70;">.word</span> ehdrsize # e_ehsize
  <span style="color: #b4fa70;">.word</span> phdrsize # e_phentsize
    <span style="color: #b4fa70;">.word</span> 1        # e_phnum
    <span style="color: #b4fa70;">.word</span> 0        # e_shentsize
    <span style="color: #b4fa70;">.word</span> 0        # e_shnum
    <span style="color: #b4fa70;">.word</span> 0        # e_shstrndx
<span style="color: #b4fa70;">.equ</span> ehdrsize, . - ehdr
<span style="color: #73d216;">/* </span><span style="color: #73d216;">Program Headher</span><span style="color: #73d216;"> */</span>
<span style="color: #b4fa70;">.equ</span> phdr_off, . - ehdr
<span style="color: #fce94f;">phdr</span>:
    <span style="color: #b4fa70;">.int</span>  1          # p_type : PT_LOAD
    <span style="color: #b4fa70;">.int</span>  0          # p_offset
    <span style="color: #b4fa70;">.int</span>  ehdr       # p_vaddr
    <span style="color: #b4fa70;">.int</span>  ehdr       # p_paddr (ignored)
    <span style="color: #b4fa70;">.int</span>  filesize   # p_filesz
    <span style="color: #b4fa70;">.int</span>  filesize   # p_memsz
    <span style="color: #b4fa70;">.int</span>  5          # p_flags : r-x
    <span style="color: #b4fa70;">.int</span>  0x1000     # p_align
<span style="color: #b4fa70;">.equ</span> phdrsize, . - phdr
<span style="color: #73d216;">/* </span><span style="color: #73d216;">Code</span><span style="color: #73d216;"> */</span>
<span style="color: #b4fa70;">.global</span> _start
<span style="color: #fce94f;">_start</span>:
    <span style="color: #b4fa70;">xor</span> <span style="color: #fcaf3e;">%eax</span>,<span style="color: #fcaf3e;">%eax</span>
    <span style="color: #b4fa70;">inc</span> <span style="color: #fcaf3e;">%eax</span>
    <span style="color: #b4fa70;">movw</span> $filesize,<span style="color: #fcaf3e;">%bx</span>
    <span style="color: #b4fa70;">int</span>  $0x80
<span style="color: #b4fa70;">.equ</span> filesize, . - ehdr
<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>
<span style="color: #73d216;">; </span><span style="color: #73d216;">tinyso3.S</span>
<span style="color: #73d216;">;;; </span><span style="color: #73d216;">**************************************************</span>

<span style="color: #73d216;">/* </span><span style="color: #73d216;">ELF Header 16 bytes, with embed CODE into preserved area</span><span style="color: #73d216;"> */</span>
<span style="color: #fce94f;">ehdr</span>:
    <span style="color: #73d216;">/* </span><span style="color: #73d216;">e_ident</span><span style="color: #73d216;"> */</span>
    <span style="color: #b4fa70;">.byte</span> 0x7F,'E,'L,'F
    <span style="color: #b4fa70;">.byte</span> 1 # EI_CLASS : ELFCLASS32
    <span style="color: #b4fa70;">.byte</span> 1 # EI_DATA  : ELFDATA2LSB
    <span style="color: #b4fa70;">.byte</span> 1 # EI_VERSION
    <span style="color: #b4fa70;">.global</span> _start
<span style="color: #73d216;">/*</span>
<span style="color: #73d216;"> * &lt;HACK&gt; 1: embed CODE into preserved area</span>
<span style="color: #73d216;"> * exactly, 9 bytes!</span>
<span style="color: #73d216;"> */</span>
<span style="color: #fce94f;">_start</span>:
    <span style="color: #b4fa70;">xor</span> <span style="color: #fcaf3e;">%eax</span>,<span style="color: #fcaf3e;">%eax</span>        # 2 bytes
    <span style="color: #b4fa70;">inc</span> <span style="color: #fcaf3e;">%eax</span>             # 1 bytes
    <span style="color: #b4fa70;">movw</span> $filesize,<span style="color: #fcaf3e;">%bx</span>   # 4 bytes
    <span style="color: #b4fa70;">int</span>  $0x80           # 2 bytes
    <span style="color: #b4fa70;">.word</span> 2        # e_type : ET_EXEC
    <span style="color: #b4fa70;">.word</span> 3        # e_machine : EM_386
    <span style="color: #b4fa70;">.int</span>  1        # e_version
    <span style="color: #b4fa70;">.int</span>  _start   # e_entry
    <span style="color: #b4fa70;">.int</span>  phdr_off # e_phoff
    <span style="color: #b4fa70;">.int</span>  0        # e_shoff
    <span style="color: #b4fa70;">.int</span>  0        # e_flags
    <span style="color: #b4fa70;">.word</span> ehdrsize # e_ehsize
  <span style="color: #b4fa70;">.word</span> phdrsize # e_phentsize
<span style="color: #73d216;">/* </span><span style="color: #73d216;">Program Headher</span><span style="color: #73d216;"> */</span>
<span style="color: #b4fa70;">.equ</span> phdr_off, . - ehdr
<span style="color: #fce94f;">phdr</span>:
<span style="color: #73d216;">/*</span>
<span style="color: #73d216;"> * &lt;HACK&gt; 2 : overlap two section</span>
<span style="color: #73d216;"> * .word 1        # e_phnum</span>
<span style="color: #73d216;"> * .word 0        # e_shentsize</span>
<span style="color: #73d216;"> * .word 0        # e_shnum</span>
<span style="color: #73d216;"> * .word 0        # e_shstrndx</span>
<span style="color: #73d216;"> */</span>
    <span style="color: #b4fa70;">.int</span>  1          # p_type : PT_LOAD
    <span style="color: #b4fa70;">.int</span>  0          # p_offset
<span style="color: #b4fa70;">.equ</span> ehdrsize, . - ehdr
    <span style="color: #b4fa70;">.int</span>  ehdr       # p_vaddr
    <span style="color: #b4fa70;">.int</span>  ehdr       # p_paddr (ignored)
    <span style="color: #b4fa70;">.int</span>  filesize   # p_filesz
    <span style="color: #b4fa70;">.int</span>  filesize   # p_memsz
    <span style="color: #b4fa70;">.int</span>  5          # p_flags : r-x
    <span style="color: #b4fa70;">.int</span>  0x1000     # p_align
<span style="color: #b4fa70;">.equ</span> phdrsize, . - phdr
<span style="color: #b4fa70;">.equ</span> filesize, . - ehdr
</pre>
</div>

<p>
Makefile:
</p>

<div class="org-src-container">
<pre class="src src-makefile"><span style="color: #fce94f;">all</span>:tinyso1 tinyso2 tinyso3
<span style="color: #fce94f;">tinyso1</span>: tinyso1.S
    @echo ----------   <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>  --------------
    gcc -nostdlib $<span style="color: #e9b2e3;">&lt;</span> -o <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>
    strip -s <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>
    wc -c <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>
    @echo ---------------------------------
<span style="color: #fce94f;">tinyso2</span>: tinyso2.S
    @echo -----------  <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>  ---------------
    gcc -c $<span style="color: #e9b2e3;">&lt;</span>
    ld tinyso2.o --oformat binary -o <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>
    @echo ---------------------------------
<span style="color: #fce94f;">tinyso3</span>: tinyso3.S
    @echo -----------  <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>  ----------------
    gcc -c $<span style="color: #e9b2e3;">&lt;</span>
    ld tinyso3.o --oformat binary -o <span style="color: #fce94f;">$</span><span style="color: #e9b2e3;">@</span>
    @echo ---------------------------------
<span style="color: #fce94f;">clean</span>:
    rm -f *.o tinyso1 tinyso2 tinyso3
</pre>
</div>


<p>
效果：
</p>

<pre class="example" id="org33ba143">
hellwolf@cocteau#pts/9%J0S2:tinyso$wc -c tinyso?
264 tinyso1
 93 tinyso2
 76 tinyso3
433 total
hellwolf@cocteau#pts/9%J0S2:tinyso$for i in $(seq 1 3);do ./tinyso$i;echo $?;done
9
93
76
hellwolf@cocteau#pts/9%J0S2:tinyso$
</pre>

<p>
文档2中还有更hack的手法，能压缩到42个字节, lol
</p>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-system programming.html">system programming</a> </div>
]]></description>
  <category><![CDATA[system programming]]></category>
  <link>http://miaozc.me/2007-06-30-minimum-elf-program.html</link>
  <guid>http://miaozc.me/2007-06-30-minimum-elf-program.html</guid>
  <pubDate>Sat, 30 Jun 2007 00:00:00 +0300</pubDate>
</item>
<item>
  <title><![CDATA[关于volatile]]></title>
  <description><![CDATA[
<pre class="example" id="org45ab31d">
$gcc --version
gcc (GCC) 4.0.0 20050519 (Red Hat 4.0.0-8)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</pre>

<p>
#+name cat 1.c
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #8cc4ff;">int</span> <span style="color: #fce94f;">main</span>()
{
  <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">j</span>=0;
  <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">i</span>=0;

  <span style="color: #b4fa70;">for</span> (i = 0; i &lt; 0xBACCA; i++)
     j += i * i;
}
</pre>
</div>

<pre class="example" id="orgdde1947">
$gcc -g -O0 1.c -o 1-O0
(gdb) disas main
Dump of assembler code for function main:
......
0x08048364 &lt;main+28&gt;:   movl   $0x0,0xfffffff8(%ebp)
0x0804836b &lt;main+35&gt;:   movl   $0x0,0xfffffffc(%ebp)
0x08048372 &lt;main+42&gt;:   movl   $0x0,0xfffffffc(%ebp)
0x08048379 &lt;main+49&gt;:   jmp    0x804838e &lt;main+70&gt;
0x0804837b &lt;main+51&gt;:   mov    0xfffffffc(%ebp),%eax
0x0804837e &lt;main+54&gt;:   mov    %eax,%edx
0x08048380 &lt;main+56&gt;:   imul   0xfffffffc(%ebp),%edx
0x08048384 &lt;main+60&gt;:   lea    0xfffffff8(%ebp),%eax
0x08048387 &lt;main+63&gt;:   add    %edx,(%eax)
0x08048389 &lt;main+65&gt;:   lea    0xfffffffc(%ebp),%eax
0x0804838c &lt;main+68&gt;:   incl   (%eax)
0x0804838e &lt;main+70&gt;:   cmpl   $0xbacc9,0xfffffffc(%ebp)
0x08048395 &lt;main+77&gt;:   jle    0x804837b &lt;main+51&gt;
0x08048397 &lt;main+79&gt;:   leave
0x08048398 &lt;main+80&gt;:   ret

$gcc -g -O1 1.c -o 1-O1
(gdb) disas main
Dump of assembler code for function main:
0x08048348 &lt;main+0&gt;:    push   %ebp
0x08048349 &lt;main+1&gt;:    mov    %esp,%ebp
0x0804834b &lt;main+3&gt;:    sub    $0x8,%esp
0x0804834e &lt;main+6&gt;:    and    $0xfffffff0,%esp
0x08048351 &lt;main+9&gt;:    sub    $0x10,%esp
0x08048354 &lt;main+12&gt;:   mov    $0xbacca,%eax
0x08048359 &lt;main+17&gt;:   dec    %eax
0x0804835a &lt;main+18&gt;:   jne    0x8048359 &lt;main+17&gt;
0x0804835c &lt;main+20&gt;:   leave
0x0804835d &lt;main+21&gt;:   ret
End of assembler dump.
</pre>

<p>
#+name 2.c
</p>
<div class="org-src-container">
<pre class="src src-c"><span style="color: #8cc4ff;">int</span> <span style="color: #fce94f;">main</span>()
{
  <span style="color: #b4fa70;">volatile</span> <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">j</span>=0;
  <span style="color: #8cc4ff;">int</span> <span style="color: #fcaf3e;">i</span>=0;

  <span style="color: #b4fa70;">for</span> (i = 0; i &lt; 0xBACCA; i++)
     j += i * i;
}
</pre>
</div>

<pre class="example" id="org0f8a0d6">
$gcc -g -O0 2.c -o 2-O0

(gdb) disas main
Dump of assembler code for function main:
......
0x08048364 &lt;main+28&gt;:   movl   $0x0,0xfffffff8(%ebp)
0x0804836b &lt;main+35&gt;:   movl   $0x0,0xfffffffc(%ebp)
0x08048372 &lt;main+42&gt;:   movl   $0x0,0xfffffffc(%ebp)
0x08048379 &lt;main+49&gt;:   jmp    0x8048392 &lt;main+74&gt;
0x0804837b &lt;main+51&gt;:   mov    0xfffffffc(%ebp),%eax
0x0804837e &lt;main+54&gt;:   mov    %eax,%edx
0x08048380 &lt;main+56&gt;:   imul   0xfffffffc(%ebp),%edx
0x08048384 &lt;main+60&gt;:   mov    0xfffffff8(%ebp),%eax
0x08048387 &lt;main+63&gt;:   lea    (%edx,%eax,1),%eax
0x0804838a &lt;main+66&gt;:   mov    %eax,0xfffffff8(%ebp)
0x0804838d &lt;main+69&gt;:   lea    0xfffffffc(%ebp),%eax
0x08048390 &lt;main+72&gt;:   incl   (%eax)
0x08048392 &lt;main+74&gt;:   cmpl   $0xbacc9,0xfffffffc(%ebp)
0x08048399 &lt;main+81&gt;:   jle    0x804837b &lt;main+51&gt;
0x0804839b &lt;main+83&gt;:   leave
0x0804839c &lt;main+84&gt;:   ret
End of assembler dump.

$gcc -g -O1 2.c -o 2-O1

(gdb) disas main
Dump of assembler code for function main:
0x08048348 &lt;main+0&gt;:    push   %ebp
0x08048349 &lt;main+1&gt;:    mov    %esp,%ebp
0x0804834b &lt;main+3&gt;:    sub    $0x18,%esp
0x0804834e &lt;main+6&gt;:    and    $0xfffffff0,%esp
0x08048351 &lt;main+9&gt;:    sub    $0x10,%esp
0x08048354 &lt;main+12&gt;:   movl   $0x0,0xfffffffc(%ebp)
0x0804835b &lt;main+19&gt;:   mov    $0x0,%ecx
0x08048360 &lt;main+24&gt;:   mov    0xfffffffc(%ebp),%edx
0x08048363 &lt;main+27&gt;:   mov    %ecx,%eax
0x08048365 &lt;main+29&gt;:   imul   %ecx,%eax
0x08048368 &lt;main+32&gt;:   add    %edx,%eax
0x0804836a &lt;main+34&gt;:   mov    %eax,0xfffffffc(%ebp)
0x0804836d &lt;main+37&gt;:   inc    %ecx
0x0804836e &lt;main+38&gt;:   cmp    $0xbacca,%ecx
0x08048374 &lt;main+44&gt;:   jne    0x8048360 &lt;main+24&gt;
0x08048376 &lt;main+46&gt;:   leave
0x08048377 &lt;main+47&gt;:   ret
</pre>

<p>
先分析-O0的情况：
</p>

<ul class="org-ul">
<li>这是没有volatile的版本：</li>
</ul>

<pre class="example" id="org216d343">
0x08048364 &lt;main+28&gt;: movl $0x0,0xfffffff8(%ebp)           j=0;
0x0804836b &lt;main+35&gt;: movl $0x0,0xfffffffc(%ebp)           i=0;
0x08048372 &lt;main+42&gt;: movl $0x0,0xfffffffc(%ebp)           for(i=0;
0x08048379 &lt;main+49&gt;: jmp 0x804838e &lt;main+70&gt;              -&gt;
0x0804837b &lt;main+51&gt;: mov 0xfffffffc(%ebp),%eax
0x0804837e &lt;main+54&gt;: mov %eax,%edx
0x08048380 &lt;main+56&gt;: imul 0xfffffffc(%ebp),%edx           i*i-&gt;EDX

0x08048384 &lt;main+60&gt;: lea 0xfffffff8(%ebp),%eax            EAX-&gt;j;
0x08048387 &lt;main+63&gt;: add %edx,(%eax)                      j+=EDX

0x08048389 &lt;main+65&gt;: lea 0xfffffffc(%ebp),%eax            eax-&gt;i;
0x0804838c &lt;main+68&gt;: incl (%eax)                          ++i;
0x0804838e &lt;main+70&gt;: cmpl $0xbacc9,0xfffffffc(%ebp)
0x08048395 &lt;main+77&gt;: jle 0x804837b &lt;main+51&gt;               ?i&lt;0xbacca
0x08048397 &lt;main+79&gt;: leave
0x08048398 &lt;main+80&gt;: ret
</pre>

<ul class="org-ul">
<li>再看有volatile的版本：</li>
</ul>

<pre class="example" id="org9591289">
0x08048364 &lt;main+28&gt;: movl $0x0,0xfffffff8(%ebp)            j=0;(volatile)
0x0804836b &lt;main+35&gt;: movl $0x0,0xfffffffc(%ebp)            i=0;
0x08048372 &lt;main+42&gt;: movl $0x0,0xfffffffc(%ebp)            for(i=0;
0x08048379 &lt;main+49&gt;: jmp 0x8048392 &lt;main+74&gt;               -&gt;
0x0804837b &lt;main+51&gt;: mov 0xfffffffc(%ebp),%eax
0x0804837e &lt;main+54&gt;: mov %eax,%edx                         i*i-&gt;EDX,
0x08048380 &lt;main+56&gt;: imul 0xfffffffc(%ebp),%edx            到这里和上面都是一样的

0x08048384 &lt;main+60&gt;: mov 0xfffffff8(%ebp),%eax             EAX=j;
0x08048387 &lt;main+63&gt;: lea (%edx,%eax,1),%eax
                      这里有点花哨，就是%edx+%eax*1,j+=i*i的意思
0x0804838a &lt;main+66&gt;: mov %eax,0xfffffff8(%ebp)

0x0804838d &lt;main+69&gt;: lea 0xfffffffc(%ebp),%eax
0x08048390 &lt;main+72&gt;: incl (%eax)
0x08048392 &lt;main+74&gt;: cmpl $0xbacc9,0xfffffffc(%ebp)
0x08048399 &lt;main+81&gt;: jle 0x804837b &lt;main+51&gt;
0x0804839b &lt;main+83&gt;: leave
0x0804839c &lt;main+84&gt;: ret
</pre>

<p>
再看这里 <a href="http://www.linuxdevices.com/articles/AT5980346182.html">http://www.linuxdevices.com/articles/AT5980346182.html</a> 关于volatile的介绍：
</p>

<blockquote>
<p>
The reason to use volatile is to ensure that the compiler generates code to re-load a data item each time it is
referenced in your program.
</p>
</blockquote>

<p>
就不难理解上面的差异了，volatile的j每次都是存入到寄存器中而不是由寄存器指向其地址，即所谓的 "re-load a data item each time
 it's refenced."
</p>
<div class="taglist"><a href="http://miaozc.me/tags.html">Tags</a>: <a href="http://miaozc.me/tag-system programming.html">system programming</a> <a href="http://miaozc.me/tag-c programming.html">c programming</a> </div>
]]></description>
  <category><![CDATA[system programming]]></category>
  <category><![CDATA[c programming]]></category>
  <link>http://miaozc.me/2005-07-22-about-volatile.html</link>
  <guid>http://miaozc.me/2005-07-22-about-volatile.html</guid>
  <pubDate>Fri, 22 Jul 2005 16:12:00 +0300</pubDate>
</item>
</channel>
</rss>
