<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2022-11-17T20:34:39+00:00</updated><id>/feed.xml</id><title type="html">Source Code Artisan</title><subtitle>A personal blog on computing topics</subtitle><entry><title type="html">Understanding Git (Part III): Workflows</title><link href="/2022/11/17/understanding-git-p3.html" rel="alternate" type="text/html" title="Understanding Git (Part III): Workflows" /><published>2022-11-17T10:21:09+00:00</published><updated>2022-11-17T10:21:09+00:00</updated><id>/2022/11/17/understanding-git-p3</id><content type="html" xml:base="/2022/11/17/understanding-git-p3.html">&lt;p&gt;Git is an extremely flexible and versatile tool to effectively and reliably
version control files. However, there are a million ways to organize
projects with Git, so it is important to agree on general usage guidelines. For
example, good guidelines tell us where is the latest stable version of the
code, how to propose changes or new features, etc. People sometimes call those
guidelines a &lt;em&gt;workflow&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A Git workflow is much like the “coding style” rules from a software
project. Git does not enforce the guidelines, just as programming languages
like C or Java do not enforce coding styles, although everyone contributing
to the project is &lt;em&gt;strongly&lt;/em&gt; encouraged to follow them to ensure that Git is
used in a coherent, consistent and productive fashion.&lt;/p&gt;

&lt;p&gt;In the remainder of this post, I will briefly describe two Git workflows. I had
to use either of these workflows in virtually all the private and open-source
projects that I contributed to. I assume that you read parts &lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;I&lt;/a&gt; and &lt;a href=&quot;/2022/11/11/understanding-git-p2.html&quot;&gt;II&lt;/a&gt; of this series, so you know your branches,
merges, remotes, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; These are the post in the &lt;em&gt;Understanding Git&lt;/em&gt; series:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;Part I: The VERY Basics!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/11/understanding-git-p2.html&quot;&gt;Part II: Working with Remotes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/17/understanding-git-p3.html&quot;&gt;Part III: Workflows&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;feature-branch-workflow&quot;&gt;Feature Branch Workflow&lt;/h1&gt;

&lt;p&gt;The idea is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; is a long-lived branch that is always kept in working
order. As a user, you can always be sure that the latest &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; will compile
and is broadly expected to work. It is also common to run regressions, such as
nightly tests, in a Continuous Integration (CI) system to sanity check and
ensure quality.&lt;/p&gt;

&lt;p&gt;Contributors are required to propose changes via branches. A contributor’s
workflow is typically like this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Update your local copy of the repository with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch origin&lt;/code&gt;. Assume
that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; is the remote’s name.&lt;/li&gt;
  &lt;li&gt;Create a branch off the latest commit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; and switch to that branch
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout origin/main -b my-feature-branch&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Make your changes.&lt;/li&gt;
  &lt;li&gt;Create commits in the branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-feature-branch&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Push your feature branch to the remote when you are happy with the changes:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push origin my-feature-branch&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Other contributors are able to see your feature branch with the proposed
changes at this point. Ideally, the changes will be reviewed giving rise to
discussions. Websites, like &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;,
&lt;a href=&quot;https://bitbucket.com&quot;&gt;BitBucket&lt;/a&gt; and &lt;a href=&quot;https://gitlab.com&quot;&gt;GitLab&lt;/a&gt;, have a
great feature to assist with the review process: &lt;em&gt;Pull Requests (PR)&lt;/em&gt; (GitLab
calls them &lt;em&gt;Merge Requests (MR)&lt;/em&gt;!). In this context, a PR is simply a “formal”
request to merge your feature branch into another branch (typically &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;).
Contributors will be able to review your changes, add comments and request
amendments. You can upload those changes by creating more commits in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-feature-branch&lt;/code&gt; and then pushing with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push origin my-feature-branch&lt;/code&gt;
as usual.&lt;/p&gt;

&lt;p&gt;PRs are merged after the changes are reviewed and discussed – and hopefully
agreed! – by clicking a button on the web UI. When that happens, the feature
branch is merged by automatically creating a merge commit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; (think
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; from &lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;here&lt;/a&gt;!).&lt;/p&gt;

&lt;p&gt;As discussed before, a branch is simply a pointer to a commit and we can create
(and throw-away!) as many branches as we like. There is no need to keep
maintaining and updating feature branches – hence why I never use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt;!
–, so it is desirable to delete feature branches, like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-feature-branch&lt;/code&gt;, after the PR is merged to avoid having lots of unused
branches cluttering the repository. In fact, this is so common that web UIs
normally have an option to automatically delete the feature branch after a PR
is merged. Alternatively, you can manually delete a branch like this:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Delete branch locally&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git branch &lt;span class=&quot;nt&quot;&gt;-D&lt;/span&gt; my-feature-branch
&lt;span class=&quot;c&quot;&gt;# Delete remote branch&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push origin &lt;span class=&quot;nt&quot;&gt;--delete&lt;/span&gt; my-feature-branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Using Pull Requests (PR) and Merge Requests (MR)&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;First of all, PRs and MRs are basically the same thing: GitHub and BitBucket
call them PRs and GitLab calls them MRs. You will be glad to know that these
are created and used through the graphical web UI which is fairly intuitive.
However, each website works in a slightly different way, so you need to look at
their specific documentation to see how to create and merge PRs, make comments,
approve, etc.&lt;/p&gt;

    &lt;p&gt;The key benefit of PRs is to create good spaces for reviewing and discussing
the proposed changes before these are integrated into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;. However, reviews
can be lenghty and it is likely that your feature branch diverges from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;
by the time everything is agreed and ready to merge. If that is the case, you
may need to incorporate the latest changes from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/main&lt;/code&gt; into your
feature branch by either rebasing or merging.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h1 id=&quot;forking-workflow&quot;&gt;Forking Workflow&lt;/h1&gt;

&lt;p&gt;The feature branch workflow is great with a single remote repository and a few
contributors. However, a couple of problems pop up as the number of
contributors grows or when projects are open-source. First, each contributor
will work on at least one feature branch, and usually many more, so the number
of &lt;em&gt;active&lt;/em&gt; branches tends to grow very quickly cluttering the repository.
And second, and perhaps most importantly in open-source projects, you do not
want every contributor to have permissions to directly modify the project’s
official remote repository – what if someone deletes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;?!&lt;/p&gt;

&lt;p&gt;The forking workflow neatly addresses both problems. The idea is that only a
small, select, trusted (!) group of core contributors has permissions to manage
and modify the project’s remote repository – including merging PRs! Everyone
else has either no permission (if it is a private project) or read-only
permissions. Contributors with read-only permissions are able to clone the
repository (with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone&lt;/code&gt;) and &lt;em&gt;fork&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;A fork is simply a copy in another remote of the project’s original remote
repository. For example, lets say that I would like to contribute to the Mbed
TLS project which is hosted in GitHub
&lt;a href=&quot;https://github.com/Mbed-TLS/mbedtls&quot;&gt;here&lt;/a&gt;, so I clone their
repository in my local computer and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; is the only remote:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone https://github.com/Mbed-TLS/mbedtls.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
origin  https://github.com/Mbed-TLS/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fetch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
origin  https://github.com/Mbed-TLS/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;push&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I wanted to propose changes to Mbed TLS. I had read-only access to their
repository, so I forked Mbed TLS using the “fork” button in GitHub’s web UI.
This creates my own copy of Mbed TLS in another remote
&lt;a href=&quot;https://github.com/andresag01/mbedtls&quot;&gt;here&lt;/a&gt;. I then configure a second remote
in my local copy of Mbed TLS like this (notice the different URL!):&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote add andresag https://github.com/andresag01/mbedtls.git
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git fetch andresag
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So my local repository is now aware of two remotes:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
andresag        https://github.com/andresag01/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fetch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
andresag        https://github.com/andresag01/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;push&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
origin  https://github.com/Mbed-TLS/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fetch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
origin  https://github.com/Mbed-TLS/mbedtls.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;push&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The remote &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; is Mbed TLS’s official repository that I can only read
while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;andresag&lt;/code&gt; is my fork which I have permission to both read and write. But
both remotes are entirely different, so commits pushed into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; will not
affect &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;andresag&lt;/code&gt; and viceversa!&lt;/p&gt;

&lt;p&gt;Back to the original task: how do we propose a change using the fork? We first
create the change commits and push them to the fork. Then we use PRs! I like
using the feature branch workflow in my forks, so the steps would be like this
in the Mbed TLS example:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Update local repository: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch origin&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create feature branch: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout origin/main -b my-feature-branch&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make your changes.&lt;/li&gt;
  &lt;li&gt;Create commits in the branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-feature-branch&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Push feature branch to my for: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push andresag my-feature-branch&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create PR using the GitHub web UI as described
&lt;a href=&quot;https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request&quot;&gt;here&lt;/a&gt;.
&lt;a href=&quot;https://github.com/Mbed-TLS/mbedtls/pull/2496&quot;&gt;Here&lt;/a&gt; is an example of a PR I
created a long time ago for Mbed TLS from my fork.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The PR is then merged as usual after the review and discussion process.&lt;/p&gt;

&lt;h1 id=&quot;closing-thoughts-on-workflows&quot;&gt;Closing Thoughts on Workflows&lt;/h1&gt;

&lt;p&gt;The general workflows described above recommend, very broadly, how to use
Git. However, using Git in a project has many more practical considerations.
Here are a few things to look out for when contributing to, creating
your own or simply using a project versioned with Git:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Projects regularly produce official releases. The release is taken from a
commit that is usually tracked by either a Git branch or a
&lt;a href=&quot;https://git-scm.com/book/en/v2/Git-Basics-Tagging&quot;&gt;tag&lt;/a&gt;. Ideally, you want to
take an officially released, presumably stable, version of the project if you
are a user.&lt;/li&gt;
  &lt;li&gt;The main branch is usually called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;primary&lt;/code&gt;. The latest
commit in this branch is normally a stable version of the project as discussed
above. Projects sometimes have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;development&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dev&lt;/code&gt; branch too where PRs
and new features are merged using the feature branch workflow. In this case,
the development branch may be unstable and it is only merged into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; when
an official release is produced.&lt;/li&gt;
  &lt;li&gt;CIs normally executes long-running tests in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dev&lt;/code&gt; branch (or
both). Sometimes the CI also runs shorter sanity checks in feature branches
after a PR is created. Ideally, the PR is only merged if the CI tests pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I described two workflows to help us use Git in a consistent and productive
way. As mentioned along the way, I had to use either of these two approaches
virtually everywhere I worked with Git. Also, I tend to use the feature branch
workflow for my own forks to keep things organized. However, I only scratched
the surface! There are many other approaches to using Git with their own
advantages and disadvantages, so have a look at the way others use Git and
learn from it!&lt;/p&gt;

&lt;p&gt;This is the last post in this Git series (after parts &lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;I&lt;/a&gt; and &lt;a href=&quot;/2022/11/11/understanding-git-p2.html&quot;&gt;II&lt;/a&gt;). Hopefully, these articles are helpful if
you are getting started with Git or even if you have been using it for some
time but perhaps it had not fully clicked. Happy times using Git!&lt;/p&gt;</content><author><name></name></author><summary type="html"></summary></entry><entry><title type="html">Understanding Git (Part II): Working with Remotes</title><link href="/2022/11/11/understanding-git-p2.html" rel="alternate" type="text/html" title="Understanding Git (Part II): Working with Remotes" /><published>2022-11-11T10:21:09+00:00</published><updated>2022-11-11T10:21:09+00:00</updated><id>/2022/11/11/understanding-git-p2</id><content type="html" xml:base="/2022/11/11/understanding-git-p2.html">&lt;p&gt;In &lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;this&lt;/a&gt; post, I
explained the very basics of Git. There was only one repository in
your local machine and only one person making changes. That is well and
good, but in practice many programmers contribute to a project: each needs a
copy of the repository and many changes are made simultaneously. Version
controlling these &lt;em&gt;distributed&lt;/em&gt; projects is a big problem that Git solves
brilliantly!&lt;/p&gt;

&lt;p&gt;In this post, I will explain how this works and how you can use Git remote
repositories without shooting-yourself-in-the-foot. I only assume that you
are already familiar with the very basics of Git like commits and branches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; These are the post in the &lt;em&gt;Understanding Git&lt;/em&gt; series:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;Part I: The VERY Basics!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/11/understanding-git-p2.html&quot;&gt;Part II: Working with Remotes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/17/understanding-git-p3.html&quot;&gt;Part III: Workflows&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;remotes&quot;&gt;Remotes&lt;/h1&gt;

&lt;p&gt;Git relies on servers to version control a distributed project. The server
manages the order in which changes are versioned and provides a consistent
view of the files in the repository. The Git server also allows programmers to
download local copies of the repository using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone &amp;lt;address&amp;gt;&lt;/code&gt;
command.&lt;/p&gt;

&lt;p&gt;Nowadays, it is popular to host Git repositories on the internet using websites
like &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;, &lt;a href=&quot;https://gitlab.com&quot;&gt;GitLab&lt;/a&gt; or
&lt;a href=&quot;https://bitbucket.com&quot;&gt;BitBucket&lt;/a&gt;. The website acts as the Git server for a
project. For example, I can make a local copy of RISC-V’s Spike’s simulator,
which is hosted in GitHub, like this:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/riscv-software-src/riscv-isa-sim.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On success, Git will download, a.k.a &lt;em&gt;clone&lt;/em&gt;, the repository and store it in my
computer at a directory called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;riscv-isa-sim&lt;/code&gt;. As discussed before, Git
repositories have a main branch which is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; in Spike’s case, so
Git will checkout that branch right after cloning. You can check that with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git
branch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From Git’s point of view, your clone is just a local copy of the repository
which tracks Spike’s &lt;em&gt;remote&lt;/em&gt; repository in GitHub. You can check this with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote&lt;/code&gt; that outputs the following for my Spike clone:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
origin  https://github.com/riscv-software-src/riscv-isa-sim.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;fetch&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
origin  https://github.com/riscv-software-src/riscv-isa-sim.git &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;push&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After cloning, you will contact the repository for either of two reasons. You
can upload, a.k.a &lt;em&gt;push&lt;/em&gt;, new commits, i.e. changes, that you made or you can
download, a.k.a &lt;em&gt;fetch&lt;/em&gt;, commits that others have pushed to the remote since
the last time you fetched. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote&lt;/code&gt; is telling us that Git will contact
the server at that HTTPS URL for either pushing or fetching. Git helpfully calls
the remote &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; so we do not have to keep typing that long URL!&lt;/p&gt;

&lt;h1 id=&quot;branches-and-remotes&quot;&gt;Branches and Remotes&lt;/h1&gt;

&lt;p&gt;Recall that a branch is simply a pointer to a commit and that you can create
an arbitrary number of branches with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch&lt;/code&gt;. Newly created branches are
only local to your repository until you push them to the Git server. In fact,
there are two sets of branches in my Spike clone repository: your &lt;em&gt;local&lt;/em&gt;
branches and the &lt;em&gt;remote&lt;/em&gt;’s branches! You can see all branches with:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git branch &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; master
  remotes/origin/HEAD -&amp;gt; origin/master
  remotes/origin/confprec
  remotes/origin/cs250
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first line of output says that there is a local branch called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; that
is currently checked out, hence the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;. If I were to create a new commit at
this point, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; would point to the new commit. The following lines start
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remotes/origin/&lt;/code&gt; meaning that these branches belong to the remote called
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; i.e. the GitHub remote repository. Line 2 is special for two reasons:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; is the server’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; branch.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remotes/origin/HEAD&lt;/code&gt; indicates the remote branch checked out when cloning.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we said that Git “checked out” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; after cloning, what happened is
that Git saw that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remotes/origin/HEAD&lt;/code&gt; pointed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt;, so it
created a local branch, i.e. a pointer, called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; which points to the
same commit that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; references.&lt;/p&gt;

&lt;p&gt;You can create local copies of other remote branches with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout&lt;/code&gt;. For
example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout confprec&lt;/code&gt; will create a local branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;confprec&lt;/code&gt; pointing
to the same commit that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/confprec&lt;/code&gt; does. You can also checkout the
commit that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/confprec&lt;/code&gt; points to with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout origin/confprec&lt;/code&gt;.
However, you cannot directly make a remote branch point to another commit
(e.g. by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit&lt;/code&gt;) because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout origin/confprec&lt;/code&gt; will
actually set the repository into &lt;em&gt;detached state&lt;/em&gt; like this:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout origin/confprec
Note: switching to &lt;span class=&quot;s1&quot;&gt;'origin/confprec'&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

You are &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'detached HEAD'&lt;/span&gt; state. You can look around, make experimental
changes and commit them, and you can discard any commits you make &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;this
state without impacting any branches by switching back to a branch.
...
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git branch
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;HEAD detached at origin/confprec&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Multiple Remotes&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;You can configure an arbitrary number of remotes in your local repository. Each
remote will have its own set of remote branches. For example, there would be
three sets of branches if I had two remotes: one set of local branches and two
sets of remote branches. Again, recall that remote branch names are prefixed
with the remote’s name so that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;remote_name&amp;gt;/master&lt;/code&gt; is a remote branch while
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; is a local branch.&lt;/p&gt;

    &lt;p&gt;I will discuss why having multiple remotes helps and how to use them in a
future post.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h1 id=&quot;pushing-to-remotes&quot;&gt;Pushing to Remotes&lt;/h1&gt;

&lt;p&gt;As we discussed, we cannot directly modify the remote’s branches in our local
repository, so how do we create new commits and &lt;em&gt;push&lt;/em&gt; them to the server? The
process is actually very simple:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Checkout a local branch, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout master&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Make your changes&lt;/li&gt;
  &lt;li&gt;Create a new commit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; with the changes using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git
commit&lt;/code&gt;, and perhaps &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; too!&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push &amp;lt;remote_name&amp;gt; &amp;lt;branch_name&amp;gt;&lt;/code&gt;, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push origin master&lt;/code&gt; in this case.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt;, Git automatically understands that your local
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; branch is tracking the remote’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; branch, so Git will
upload any new commits to the server &lt;em&gt;and&lt;/em&gt; set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; to point to the
same commit as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; as shown below. In the case that you are pushing
commits in a new branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-new-branch&lt;/code&gt; that the server does not know about,
Git will upload the new commits &lt;em&gt;and&lt;/em&gt; create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/my-new-branch&lt;/code&gt; branch.
Once you pushed, anyone will be able to see your new commits, and potentially a
new branch, in the Git server.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p2-push-no-conflicts.png&quot; alt=&quot;Before and after pushing new commits in the local `master` branch to the Git server at `origin`.&quot; height=&quot;100%&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Before and after pushing new commits in the local &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; branch to the Git server at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt; will throw an error if you try to push commits to a remote branch
that cannot be fast-forwarded. For example, this occurs when another programmer
pushes a commit to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; before you push your own changes in the
local &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; branch; in other words, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; &lt;em&gt;diverged&lt;/em&gt;
as shown below. If this happens, simply fetch from the remote (see below!),
update your local branch with the latest changes (using, e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase&lt;/code&gt;) from the remote branch that it is tracking and try to push again.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p2-push-divergence.png&quot; alt=&quot;`git push` fails because `origin/master` and `master` branches diverged.&quot; height=&quot;65%&quot; width=&quot;65%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt; fails because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; branches diverged.&lt;/em&gt;
&lt;/p&gt;

&lt;h1 id=&quot;fetching-from-remotes&quot;&gt;Fetching From Remotes&lt;/h1&gt;

&lt;p&gt;We obviously want to regularly download the latest changes that others have
pushed to the server. We can do that with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch&lt;/code&gt;, for example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch
origin&lt;/code&gt; in the case of my local Spike repository. Git will download the latest
commits from the server and update the remote branches i.e. the branches
prefixed with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch&lt;/code&gt;, the remote branches in my local copy of the repository are
synchronized with the server, but my local branches will be left untouched as
shown below.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p2-fetch.png&quot; alt=&quot;Git history before and after `git fetch origin`. New commits and branches are downloaded from `origin` while local branches are unchanged.&quot; height=&quot;85%&quot; width=&quot;85%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Git history before and after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fetch origin&lt;/code&gt;. New commits and branches are downloaded from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin&lt;/code&gt; while local branches are unchanged.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;You can update your local branches to point to the latest commit if you wish to
with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase&lt;/code&gt; just as discussed in &lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;this&lt;/a&gt; previous post. For example, the figure
below shows the history of a repository before and after fetching and merging
with:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git fetch origin
git checkout main
&lt;span class=&quot;c&quot;&gt;# Fast-forward main to reference the same commit as origin/main&lt;/span&gt;
git merge origin/main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p2-fetch-fast-forward.png&quot; alt=&quot;Git history after fetching from origin and fast-forwarding `master` to reference new commits in `origin/master`.&quot; height=&quot;100%&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Git history after fetching from origin and fast-forwarding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt; to reference new commits in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/master&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Pulling: Fetching + Merging&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt; is a convenience command that combines the fetching and
merging/rebasing functions into one (see documentation
&lt;a href=&quot;https://git-scm.com/docs/git-pull&quot;&gt;here&lt;/a&gt;). I seldom use it because I rarely
ever update my local branches! I will explain why in a future post. I also
think that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt; does a lot behind the scenes and this tends to trip new
users, so I would recommend that you avoid it if you are new to Git.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h1 id=&quot;visualizing-git-history&quot;&gt;Visualizing Git History&lt;/h1&gt;

&lt;p&gt;It can sometimes be helpful to visualize your Git history as the project grows
with many commits, branches and remotes. Of course, you can use the venerable
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git log&lt;/code&gt; (see documentation &lt;a href=&quot;https://git-scm.com/docs/git-log&quot;&gt;here&lt;/a&gt;), but
there are also many tools to assist you with this, such as
&lt;a href=&quot;https://git-scm.com/docs/gitk&quot;&gt;gitk&lt;/a&gt;, &lt;a href=&quot;https://www.gitkraken.com/&quot;&gt;GitKraken&lt;/a&gt;
or &lt;a href=&quot;https://www.sourcetreeapp.com/&quot;&gt;Sourcetree&lt;/a&gt;. My favorite visualizer is
&lt;a href=&quot;https://jonas.github.io/tig/&quot;&gt;tig&lt;/a&gt;, which stands for Text-mode Interface for
Git, because it is light-weight, easy-to-use and works directly in the
terminal. &lt;a href=&quot;https://www.atlassian.com/blog/git/git-tig&quot;&gt;Here&lt;/a&gt; is a great blog
post about tig if you are interested!&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;You should now be familiar with how Git tracks remote repositories using
branches if you made it this far. We also covered how you can clone
repositories from a server as well as fetch the latest changes and push your
new commits to the server. In the next post, I will describe the workflow that
many Git open-source projects use.&lt;/p&gt;</content><author><name></name></author><summary type="html"></summary></entry><entry><title type="html">Understanding Git (Part I): The VERY Basics!</title><link href="/2022/11/09/understanding-git-p1.html" rel="alternate" type="text/html" title="Understanding Git (Part I): The VERY Basics!" /><published>2022-11-09T07:43:09+00:00</published><updated>2022-11-09T07:43:09+00:00</updated><id>/2022/11/09/understanding-git-p1</id><content type="html" xml:base="/2022/11/09/understanding-git-p1.html">&lt;p&gt;Git is an awesome tool to version control your coding project. It tracks
changes in your project files and helps coordinate how changes from many
developers are put together. However, Git comes across as an over-complicated
and difficult-to-use tool for newcomers. It appears to have a million ways of
doing things and a two million ways to shoot-yourself-in-the-foot. The good
news is that we can skip all the Git-pain! But we need to have a basic
understanding of how Git works…&lt;/p&gt;

&lt;p&gt;In this post, I will explain those basic ideas that I wished someone had
explained to me 10 years ago when I started using Git. In a later posts, I will
introduce other Git features and describe the Git workflow that many
open-source projects hosted in (e.g.) GitHub or GitLab normally use.&lt;/p&gt;

&lt;p&gt;Note that this is not a step-by-step tutorial on how to use individual Git
commands – you can find that from plenty of sources! The goal of my posts
is to describe, at a high-level, how Git works and take a tour of some of its
key features. My hope is that after reading these posts you will understand
enough of Git to know which feature works best for which situation in everyday
usage without wrecking your repository!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; These are the post in the &lt;em&gt;Understanding Git&lt;/em&gt; series:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/09/understanding-git-p1.html&quot;&gt;Part I: The VERY Basics!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/11/understanding-git-p2.html&quot;&gt;Part II: Working with Remotes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2022/11/17/understanding-git-p3.html&quot;&gt;Part III: Workflows&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;versions-commits-and-graphs&quot;&gt;Versions, Commits and Graphs&lt;/h1&gt;

&lt;p&gt;Coding takes a lot of effort! So hardware and software projects are developed
incrementally over many (many!) years. &lt;em&gt;Versions&lt;/em&gt; of the project will
be released from time to time for users to, well…, use. A new version of the
project may include new features, bug fixes, etc when compared to the previous
version. Since coding projects are basically file repositories, a new
version of the project makes changes to the files from the older version. Git
tracks these changes in something called &lt;em&gt;commits&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Lets consider an example. Imagine that I have a Git repository called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt;
that has a single file: the venerable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.c&lt;/code&gt;. Lets say that so far I only
released version 1.0. I then develop a new feature and end up making some
changes to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.c&lt;/code&gt; and create a new file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo.c&lt;/code&gt;. I am happy with my changes
and would like Git to know about them, so I create commits tracking them. The
new commits are part of version 2.0 of my project.&lt;/p&gt;

&lt;p&gt;I create more commits as I continue to change and release &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt;. The project
starts to have a Git &lt;em&gt;history&lt;/em&gt; that we can visualise in a graph as shown below.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-commits.png&quot; alt=&quot;Git history of a project with four commits.&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Git history of a project with four commits.&lt;/em&gt;
&lt;/p&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Creating Commits&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;Creating a commit is dead-easy! Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add&lt;/code&gt; from the command line to let Git
know which changes you would like to add to your commit; this is called
&lt;em&gt;staging&lt;/em&gt;. You can check which files are changed or staged with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt;.
Then create the commit using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit&lt;/code&gt;. Git will open your favorite text
editor where you can type a message describing what changes you are
introducing. For example, you can commit changes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo.c&lt;/code&gt; and all files in a
directory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar/&lt;/code&gt; like this:&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add foo.c ./bar
git commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;The commit message should be helpful, so do not just type ‘changes’ or
‘version 1’!  &lt;a href=&quot;https://cbea.ms/git-commit/&quot;&gt;Here&lt;/a&gt; are some guidelines on how to
write good commit messages.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h1 id=&quot;anatomy-of-a-git-commit&quot;&gt;Anatomy of a Git Commit&lt;/h1&gt;

&lt;p&gt;The code below shows the contents of an old commit that I created while working
on an open-source project (see &lt;a href=&quot;https://github.com/Mbed-TLS/mbedtls&quot;&gt;here&lt;/a&gt;).
The commit has four components:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The first line is an ID unique to each commit. Git generates this
number by taking a &lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-1&quot;&gt;SHA-1&lt;/a&gt; hash of the
repository contents.&lt;/li&gt;
  &lt;li&gt;The second and third lines state the author and when the commit was created.&lt;/li&gt;
  &lt;li&gt;The commit message is the text after the date line and before the line with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff&lt;/code&gt;. The message is usually shown indented and may be multiple lines long.&lt;/li&gt;
  &lt;li&gt;The remaining of the file shows the changes that this commit makes. Each
file is shown in a separate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff&lt;/code&gt; block. Among other things, the diff states
the lines that change between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@@&lt;/code&gt;, added lines preceded by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt; and removed
lines preceded by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can view commit information using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git show &amp;lt;commit_id&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;commit a685d4f28dce5ad6aeba3308514b8a5b6008ca0b
Author: Andres Amaya Garcia &amp;lt;andres.amayagarcia@arm.com&amp;gt;
Date:   Sun Dec 9 19:13:01 2018 +0000
&lt;/span&gt;
    Add MBEDTLS_ERR_SHA1_BAD_INPUT_DATA to error.{h,c}

diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
&lt;span class=&quot;gh&quot;&gt;index 0c3888987..57bbfeb6e 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/include/mbedtls/error.h
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/include/mbedtls/error.h
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -74,7 +74,7 @@&lt;/span&gt;
  * MD4       1                  0x002D-0x002D
  * MD5       1                  0x002F-0x002F
  * RIPEMD160 1                  0x0031-0x0031
&lt;span class=&quot;gd&quot;&gt;- * SHA1      1                  0x0035-0x0035
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ * SHA1      1                  0x0035-0x0035 0x0073-0x0073
&lt;/span&gt;  * SHA256    1                  0x0037-0x0037
  * SHA512    1                  0x0039-0x0039
  * CHACHA20  3                  0x0051-0x0055
&lt;span class=&quot;gh&quot;&gt;diff --git a/library/error.c b/library/error.c
index eabee9e21..564490e58 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/library/error.c
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/library/error.c
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -855,6 +855,8 @@&lt;/span&gt; void mbedtls_strerror( int ret, char *buf, size_t buflen )
 #if defined(MBEDTLS_SHA1_C)
     if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
         mbedtls_snprintf( buf, buflen, &quot;SHA1 - SHA-1 hardware accelerator failed&quot; );
&lt;span class=&quot;gi&quot;&gt;+    if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, &quot;SHA1 - Invalid input data&quot; );
&lt;/span&gt; #endif /* MBEDTLS_SHA1_C */

 #if defined(MBEDTLS_SHA256_C)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;branching-and-merging&quot;&gt;Branching and Merging&lt;/h1&gt;

&lt;p&gt;Imagine that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt; user finds a bug in version 3.0 after I started working
in version 4.0 as shown below. Its a security issue and I need to work fast to
release version 3.1 – i.e. version 3.0 plus the fix minus all version 4.0
changes.  How do I keep track of my partial version 4.0 changes while I develop
version 3.1?&lt;/p&gt;

&lt;p&gt;Git has a great feature to get around this conundrum: &lt;em&gt;branches&lt;/em&gt;. In a
nutshell, a branch is a pointer to a commit in the Git history. Developers can
create any number of branches, but by default, all repositories have an aptly
called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; branch (a.k.a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;primary&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;master&lt;/code&gt;) where most of the
development changes occur. So I can create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; branch from the
commit with all version 3.0 changes. After developing my fix and releasing
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt; 3.1 my Git
history looks like this:&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-branches.png&quot; alt=&quot;Branch `version-3.1-fix` created off `Commit #4`.&quot; height=&quot;50%&quot; width=&quot;50%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; created off &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Commit #4&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;Yay! I fixed the security bug via branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt;. However, a future
version 4.0 would not include the security fix because the changes from branch
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; are not in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;! We can sort this out by &lt;em&gt;merging&lt;/em&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;: this creates a new commit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; that tracks
all the changes from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; as shown below.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-merge.png&quot; alt=&quot;Before and after merging branch `version-3.1-fix` into `main`.&quot; height=&quot;100%&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Before and after merging branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Checking Out, Creating and Merging Branches&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch&lt;/code&gt; will show a list of branches and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; next to the branch
you are currently at. You can create a new branch at the current commit with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch &amp;lt;branch_name&amp;gt;&lt;/code&gt; and you can &lt;em&gt;checkout&lt;/em&gt;, i.e. change to another
branch, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout &amp;lt;branch_name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;To merge a branch, ensure that you checkout the branch that will contain the
merge commit, then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt;. For example, I can merge branch
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version-3.1-fix&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; like this:&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout main
git merge version-3.1-fix
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Sometimes merging gives raise to conflicts if the branches being
merged both include commits changing the same files.
&lt;a href=&quot;https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line&quot;&gt;Here&lt;/a&gt;
is a good tutorial on how to resolve merge conflicts.&lt;/p&gt;

&lt;h1 id=&quot;rebasing&quot;&gt;Rebasing&lt;/h1&gt;

&lt;p&gt;Later on, while developing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt; 4.0, I had a shift in priorities. I started
developing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; feature that I later had to abandon due to time
constraints in my release cycle. I did not want to throw this work away, so
I put the partial &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; changes on its own branch and continued creating
commits in master. My history now looks like this:&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-before-rebase.png&quot; alt=&quot;Branch `super-crash` diverted from `main`, i.e. there are commits in `main` that are not in `super-crash`.&quot; height=&quot;55%&quot; width=&quot;55%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; diverted from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;, i.e. there are commits (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Commit #7&lt;/code&gt;) in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; that are not in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;However, it turns out that version 4.0 must include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; because
my troublesome users really want that feature (perhaps they threatened to stop
using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crash&lt;/code&gt; if I refused!). Merging branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; is not
a great option because it would create yet another merge commit which I really
want to avoid – it makes it harder to navigate my Git history. Thankfully, Git
has another great feature to deal with this problem: &lt;em&gt;rebasing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We can say that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Merge commit&lt;/code&gt; is the &lt;em&gt;base&lt;/em&gt; commit of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; if I created
that branch off commit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Merge commit&lt;/code&gt;. Rebasing simply changes the base of the
branch making it look like I started working on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; off another
commit in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; – in this case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Commit #7&lt;/code&gt; as shown below.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-rebase.png&quot; alt=&quot;Before and after rebasing branch `super-crash` on top of `main`.&quot; height=&quot;100%&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Before and after rebasing branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; on top of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;I can then &lt;em&gt;fast-forward&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; such that both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;
branches point to exactly the same commit like this:&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/git-p1-fast-forward.png&quot; alt=&quot;Before and after fast-forwarding `main`.&quot; height=&quot;100%&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Before and after fast-forwarding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt;.&lt;/em&gt;
&lt;/p&gt;

&lt;div class=&quot;panel-info&quot;&gt;
  &lt;div class=&quot;panel-info-title&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Rebasing and Fast-Forwarding&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;panel-info-body&quot;&gt;
    &lt;p&gt;Make sure you are currently on the branch whose base is going to change. Then
run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase &amp;lt;new_base&amp;gt;&lt;/code&gt;. For example, we can rebase &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; on top
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; like this:&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout super-crash
git rebase main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;We can then fast-forward &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; to match &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; like this:&lt;/p&gt;

    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout main
git merge super-crash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;Git will fast-forward, instead of creating a merge commit, because
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt; contains all commits in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; plus a few new ones.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Sometimes rebasing gives raise to conflicts because the new base
commit includes changes to the same files that the branch being rebased also
changes.
&lt;a href=&quot;https://docs.github.com/en/get-started/using-git/resolving-merge-conflicts-after-a-git-rebase&quot;&gt;Here&lt;/a&gt;
is a good tutorial on how to resolve rebase conflicts – the idea is generally
the same as resolving merge conflicts.&lt;/p&gt;

&lt;h1 id=&quot;navigating-git-history&quot;&gt;Navigating Git History&lt;/h1&gt;

&lt;p&gt;As we discussed, Git allows you to view, a.k.a &lt;em&gt;checkout&lt;/em&gt;, the files in the
repository at one commit only. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout main&lt;/code&gt; will checkout
the files at the latest commit that the branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; references. But it is
often necessary to navigate the Git history and checkout arbitrary commits, for
example, while debugging. You can view a summary of the Git history of the
current commit with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git log&lt;/code&gt;. Here is some example output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;commit a685d4f28dce5ad6aeba3308514b8a5b6008ca0b (HEAD)
Author: Andres Amaya Garcia &amp;lt;andres.amayagarcia@arm.com&amp;gt;
Date:   Sun Dec 9 19:13:01 2018 +0000

    Add MBEDTLS_ERR_SHA1_BAD_INPUT_DATA to error.{h,c}

commit f7c43b3145b2952a0bc0e5fe4584df4bf47fe67e
Author: Andres Amaya Garcia &amp;lt;andres.amayagarcia@arm.com&amp;gt;
Date:   Sun Dec 9 19:12:19 2018 +0000

    Add parameter validation to SHA-1

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is showing that I currently checked out commit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a685d4f28...&lt;/code&gt;, hence why
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(HEAD)&lt;/code&gt; is next to the ID, and an earlier commit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f7c43b31...&lt;/code&gt;. You can
checkout an arbitrary commit using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout &amp;lt;commit_id&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Again, we can only view the repository files at one commit. So it is sometimes
helpful to view the differences between two arbitrary commits in the Git
history using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt;. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff main..super-crash&lt;/code&gt; will show
you the differences in the repository, in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff&lt;/code&gt; format, between the latest
commit in branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; references and the latest commit in branch
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super-crash&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;We discussed the VERY basics of Git in this post. You should now have a rough
idea about commits, branches, merging and rebasing. In the following posts,
we will build on this knowledge to understand how Git helps versioning when
a project is developed concurrently by many programmers. We will also discuss
the workflow that many Git open-source projects use.&lt;/p&gt;</content><author><name></name></author><summary type="html"></summary></entry><entry><title type="html">What’s So Good About RISC V?</title><link href="/2022/08/14/riscv-like.html" rel="alternate" type="text/html" title="What’s So Good About RISC V?" /><published>2022-08-14T10:21:09+00:00</published><updated>2022-08-14T10:21:09+00:00</updated><id>/2022/08/14/riscv-like</id><content type="html" xml:base="/2022/08/14/riscv-like.html">&lt;p&gt;I was fresh out of university when I first heard about RISC V. The &lt;a href=&quot;https://riscv.org/about/history/&quot;&gt;RISC V
Foundation&lt;/a&gt; just set up shop and the big
guys, like Google and IBM,&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; were throwing their weight behind it. There was
suddenly renewed interest on open-source processors, like
&lt;a href=&quot;https://github.com/riscv-boom/riscv-boom&quot;&gt;BOOM&lt;/a&gt;, and many IP businesses
started emerging alongside RISC V. But “open” hardware or Instruction Set
Architectures (ISA) are clearly not novel ideas,&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; and most
certainly, neither are Reduced Instruction Set Computers (RISC). So what is so
good about RISC V?&lt;/p&gt;

&lt;p&gt;I pondered this question for some time and I will humbly provide my
perspective. I first worked with computer architectures while
pursuing a PhD. I then joined ARM as a CPU Architect for about a year before
joining Codasip where I currently work. ARM is an established IP business that
owns its well-known ISA while Codasip, among other
things, provides RISC V IP and is a founding member of the RISC V Foundation.
In short, I worked with both ARM, the incumbent, and RISC V, the challenger, as
an &lt;em&gt;engineer&lt;/em&gt;, so hopefully my perspective provides a slightly different
insight.&lt;/p&gt;

&lt;p&gt;I would like to stress that the opinions expressed in this post are solely my
own and do not express the views or opinions of my employer. My opinion is of
course that RISC V is a great project and here are three reasons why…&lt;/p&gt;

&lt;h1 id=&quot;1-its-free&quot;&gt;1. It’s Free!&lt;/h1&gt;

&lt;p&gt;And again, &lt;strong&gt;it’s FREE!&lt;/strong&gt; Well, actually RISC V is &lt;em&gt;sort of&lt;/em&gt; free. The ISA is
free and “open” in the sense that anyone can download the manuals and use them
however they like. For example, an enterprising group of engineers can
develop and commercialize RISC V processors without paying a penny in licenses
or royalties for the ISA. Anyone can configure or customize RISC V however they
see fit and use it for research, business or any other purpose. Even better,
anyone can choose to ignore RISC V compliance and &lt;em&gt;modify&lt;/em&gt; it however they see
fit to make a new ISA based on RISC V – we could call it RISC VI or RISC V++!&lt;/p&gt;

&lt;p&gt;But there is a (tiny) catch! You need to be a member of the RISC V
International Association to really be part of RISC V.  RISC V International
oversees and fosters the RISC V community including its strategy, technical
committees and workgroups, technical deliveries, etc. You must be a member if
you want to participate in discussions, simply ask a technical question or have
any kind of influence or voice in RISC V.&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; Of course, becoming a member of
RISC V International costs $$$!&lt;/p&gt;

&lt;p&gt;Therefore, RISC V is more of an &lt;em&gt;open standard&lt;/em&gt;, like Bluetooth&lt;sup id=&quot;fnref:6&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; or DDR&lt;sup id=&quot;fnref:7&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:7&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;,
as opposed to a regular open-source project. The ISA specifications are
available online and you can submit patches via GitHub,&lt;sup id=&quot;fnref:8&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:8&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; but anything
significant, like a new instruction, will probably be dismissed if you are not
a member and the ideas were not previously discussed in members-only forums.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The RISC V International Association is a non-profit organization
incorporated in Switzerland back in 2020 to “manage strategic risk for [the]
community investing in RISC V for the next 50+ years”.&lt;sup id=&quot;fnref:9&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:9&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt; Feel free to read
that in whatever geopolitical context you like!&lt;/p&gt;

&lt;p&gt;The good news is that RISC V International memberships are relatively cheap,
that is, when compared to buying an architecture license. Also,
you do not have to ask anyone’s permission to use RISC V. You just need to get
on with the work! In contrast, you cannot touch proprietary IP with a ten-foot
pole for ages while your organization negotiates the purchase of an
architecture license with, say, ARM. And most importantly, RISC V gives you the
freedom to configure, customize or modify the ISA &lt;em&gt;however you want&lt;/em&gt; without
having to ask anyone for permission, and this brings us to the second point…&lt;/p&gt;

&lt;h1 id=&quot;2-innovation&quot;&gt;2. Innovation&lt;/h1&gt;

&lt;p&gt;Imagine that you are designing a new processor optimized for machine learning
applications, so you decide that it needs a matrix coprocessor. Your new
processor will implement a proprietary ISA, but there is a problem! Your legal
department is saying, after the requisite few weeks of delays, that you are
forbidden from extending the proprietary ISA with custom instructions to easily
interface with your matrix coprocessor even though you purchased an
architecture license. Perhaps the restriction is in the license agreement!
What do you do?&lt;/p&gt;

&lt;p&gt;Situations like this happened before. Apple wanted a matrix coprocessor, known
as Apple Matrix coprocessor (AMX), in their M1 chip which implements the
(proprietary) ARMv8-A ISA.&lt;sup id=&quot;fnref:11&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:11&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; However, ARM “has long resisted adding custom
instructions to their ISA” as Erik Engheim pointed out.&lt;sup id=&quot;fnref:10&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:10&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; Apple did not end
up extending the ISA in the usual way; AMX instructions are posted to the
coprocessor via the processor’s store unit instead.&lt;sup id=&quot;fnref:11:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:11&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; Also, Apple did not
document AMX and we are only aware of it thanks to Dougall Johnson’s reverse
engineering efforts!&lt;sup id=&quot;fnref:11:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:11&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; The idea of matrix coprocessors caught on and ARM
eventually introduced a proper Scalable Matrix Extension (SME) for their
ARMv9-A ISA although this took years and the M1 was in production by then.&lt;sup id=&quot;fnref:12&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:12&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The point of this story is that closed, proprietary ISAs restrict innovation.
You cannot do whatever you want with those ISAs without asking permission, and
permission may not always be granted!&lt;sup id=&quot;fnref:13&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:13&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; This is not a problem with
an open ISA like RISC V. You do not have to ask permission to extend
the ISA if the current specification does not suit your needs. Extending RISC V
is even encouraged and the designers helpfully point out free opcodes for
custom instructions in the ISA specification!&lt;sup id=&quot;fnref:14&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:14&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;14&lt;/a&gt;&lt;/sup&gt; There is also a huge amount
of freedom to tune the core components of the ISA in an implementation, like
the memory model.&lt;/p&gt;

&lt;p&gt;The freedom to extend the ISA allows engineers to create innovative and unique
RISC V processors. For example, you can be sure that two processors
implementing, say, the proprietary ARMv8-M ISA only differ in their
microarchitecture (e.g. slightly different pipeline, perhaps a coprocessor,
etc). In contrast, two RISC V processors could have a different
microarchitecture &lt;em&gt;and&lt;/em&gt; implement different (custom) ISA extensions such that
one processor is great for machine learning while the other is great for
real-time applications. The freedom to innovate creating these
&lt;em&gt;domain-specific&lt;/em&gt; ISA extensions, not just the microarchitecture, is specially
important as we reach the end of Moore’s law and Denard scaling.&lt;/p&gt;

&lt;p&gt;Extending the ISA is so appealing that a few years ago ARM opened up the
possibility for licensees to build custom instructions.&lt;sup id=&quot;fnref:15&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:15&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Additionally, the freedom to innovate with RISC V enables businesses to come up
with products that have clear differentiator features, like custom instructions
and coprocessors, and even entirely novel products or services. RISC V also
opens up great opportunities for research. And this brings us to my final
point…&lt;/p&gt;

&lt;h1 id=&quot;3-community&quot;&gt;3. Community&lt;/h1&gt;

&lt;p&gt;An ISA would not be complete if it does not have a great community around it.
RISC V absolutely nailed this point! A great open-source, research and business
community sprung up to create a rich software (compilers, operating systems,
tools, etc) and hardware (processors, coprocessors, etc) ecosystem and
offer IP or services around the ISA.&lt;/p&gt;

&lt;p&gt;My employer, &lt;a href=&quot;https://codasip.com/&quot;&gt;Codasip&lt;/a&gt;, is a great example of a business
in the RISC V community.&lt;sup id=&quot;fnref:16&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:16&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt; Codasip’s flagship product, Codasip Studio, is an
innovative EDA toolset that allows engineers to quickly design and customize
processors &lt;em&gt;and&lt;/em&gt; ISAs. Of course, you can use Studio to customize any ISA,
but it would be a hard sell if an open ISA, like RISC V, was not available and
customers could only rely on proprietary ISAs that restrict innovation. Similar
to Codasip, there are many other businesses and projects who depend on an open
ISA, like RISC V, to exist.&lt;sup id=&quot;fnref:16:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:16&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;So what’s so good about RISC V? It is free, enables innovation and has a great
community around it! Those are, in my opinion, the three key points that
make RISC V a compelling ISA today. Personally, this is also why I decided to
join the RISC V community!&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://riscv.org/members/&quot;&gt;Here&lt;/a&gt; is a list of members in the RISC V Foundation. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://openrisc.io/&quot;&gt;OpenRISC&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://openpowerfoundation.org/&quot;&gt;OpenPOWER&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.oracle.com/servers/technologies/opensparc-overview.html&quot;&gt;OpenSPARC&lt;/a&gt; &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://riscv.org/technical/technical-forums/&quot;&gt;RISC V Technical Forums&lt;/a&gt; &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:6&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.bluetooth.com/about-us/&quot;&gt;Bluetooth SIG develops and maintains the Bluetooth standards&lt;/a&gt; &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:7&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.jedec.org/about-jedec&quot;&gt;JEDEC develops and maintains the DDR (and many other) standards&lt;/a&gt; &lt;a href=&quot;#fnref:7&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:8&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://github.com/riscv&quot;&gt;RISC V’s GitHub&lt;/a&gt; &lt;a href=&quot;#fnref:8&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:9&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://riscv.org/about/history/&quot;&gt;RISC V history&lt;/a&gt; &lt;a href=&quot;#fnref:9&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:11&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The Apple Matrix coprocessor (AMX) is largely undocumented. Developer Dougall Johnson has reversed engineered a lot of it. See &lt;a href=&quot;https://gist.github.com/dougallj/7a75a3be1ec69ca550e7c36dc75e0d6f&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;#fnref:11&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:11:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;#fnref:11:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:10&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Erik Engheim, The Secret Apple M1 Coprocessor, see &lt;a href=&quot;https://medium.com/swlh/apples-m1-secret-coprocessor-6599492fc1e1&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;#fnref:10&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:12&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;ARM, Introducing the Scalable Matrix Extension for the Armv9-A Architecture, see &lt;a href=&quot;https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;#fnref:12&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:13&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;There certainly are advantages for tightly controlled ISAs. For example, the ISA does not “fragment” in the sense that processors implement the same core set of instructions, so it is easier to have software that is written once and runs everywhere. I personally still favor innovation! Solutions to mitigate problems like fragmentation exist anyway. &lt;a href=&quot;#fnref:13&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:14&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;See Chapter 26 (Extending RISC V) from &lt;a href=&quot;https://riscv.org/technical/specifications/&quot;&gt;The RISC V Instruction Set Manual Volume I: Unprivileged ISA.&lt;/a&gt; &lt;a href=&quot;#fnref:14&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:15&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Kevin Krewell, Arm Responds to RISC V, and More, see &lt;a href=&quot;https://www.eetimes.com/arm-responds-to-risc-v-and-more/#&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;#fnref:15&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:16&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Many of these businesses are also RISC V members. See &lt;a href=&quot;https://riscv.org/members/&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;#fnref:16&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:16:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name></name></author><summary type="html">I was fresh out of university when I first heard about RISC V. The RISC V Foundation just set up shop and the big guys, like Google and IBM,1 were throwing their weight behind it. There was suddenly renewed interest on open-source processors, like BOOM, and many IP businesses started emerging alongside RISC V. But “open” hardware or Instruction Set Architectures (ISA) are clearly not novel ideas,2 3 4 and most certainly, neither are Reduced Instruction Set Computers (RISC). So what is so good about RISC V? Here is a list of members in the RISC V Foundation. &amp;#8617; OpenRISC &amp;#8617; OpenPOWER &amp;#8617; OpenSPARC &amp;#8617;</summary></entry><entry><title type="html">Analyzing Real-Time Systems</title><link href="/2022/01/26/real-time-2.html" rel="alternate" type="text/html" title="Analyzing Real-Time Systems" /><published>2022-01-26T10:21:09+00:00</published><updated>2022-01-26T10:21:09+00:00</updated><id>/2022/01/26/real-time-2</id><content type="html" xml:base="/2022/01/26/real-time-2.html">&lt;p&gt;In a previous post (&lt;a href=&quot;/2022/01/25/real-time-1.html&quot;&gt;here&lt;/a&gt;) we discussed
what are and the types of real-time systems. We also gave some examples to
highlight their importance and clarify some of the confusion regarding the
real-time and run-time performance tradeoff. In this post, we will focus
exclusively on “hard” real-time systems and how they are statically analyzed
(i.e. before the program is run) to guarantee that deadlines are never missed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; You can find a great survey of hard real-time analysis methods and
tools (both commercial and open-source)
&lt;a href=&quot;https://dl.acm.org/doi/10.1145/1347375.1347389&quot;&gt;here&lt;/a&gt;. I will only discuss one
method in this post, but there are alternatives.&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Our goal is to ensure that the hard real-time system &lt;em&gt;never&lt;/em&gt; misses a deadline.
To achieve that, we are going to count how many clock cycles the processor will
take to run our given hard real-time program through any possible execution
path. Then we will select the code path that takes the longest to run and
declare that our &lt;em&gt;Worst-Case Execution Time (WCET)&lt;/em&gt;. The hard real-time system
will meet all its deadlines if the WCET is smaller than the deadline, otherwise
the system needs to be re-designed so that it does meet its deadlines. For
example, the WCET to draw a frame must be less than 16 ms if we would like the
Chrome browser to operate at 60 fps although that is not a hard real-time
application!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I do mean counting how many clock cycles it takes to execute each
add, sub, ld, st, etc instruction. For this reason, I have sometimes heard
people call this method &lt;em&gt;cycle-counting&lt;/em&gt; analysis.&lt;/p&gt;

&lt;p&gt;The worst-case idea is actually very important and perhaps the most troublesome
in this analysis. For example, the WCET of an if-statement is given by the
branch with the longest run-time. And this is regardless of how often that
particularly long-running branch of the if-statement is executed because in
practice it is hard to know how many times this branch is run. So our
&lt;em&gt;estimated&lt;/em&gt; program run-time can add up in unrealistic ways when the code has
widely different best-case and worst-case execution times!&lt;/p&gt;

&lt;p&gt;Lets consider the simple pseudo-code example below to nail down this idea. The
for-loop executes the if-statement N times and the run-times of statements
A and B are 2 ms and 10 ms respectively. So the WCET for this code is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10 * 10
ms = 100 ms&lt;/code&gt; because we assume that the program is invariably going to execute
the worst-case branch B from the if-statement. However, it might be the case
that B is only executed 50% of the time on average, so a more &lt;em&gt;realistic&lt;/em&gt;
run-time for this code would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5 * 2 ms + 5 * 10 ms = 60 ms&lt;/code&gt;. Even in this
simple example we are over-estimating the WCET by about 40%! But we cannot
improve our WCET with the information provided because we have no idea how
frequently &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x(i)&lt;/code&gt; evaluates to true or false. If we heavy-handedly assumed that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x(i)&lt;/code&gt; is true say 50% of the time, but its actually 60% or 70% in practice, we
are at risk of missing deadlines.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is for these reasons that we can often hear engineers saying that
&lt;a href=&quot;https://en.wikipedia.org/wiki/Cache_(computing)&quot;&gt;caching&lt;/a&gt; and other hardware
optimization features are incompatible with hard real-time analysis. The idea
of caching is to use smaller and faster memories close to the processor to
reduce the time it takes to load or store data. However, caching makes the
run-time of load and store instructions difficult to estimate because we cannot
tell whether a memory access will result in a cache hit, so it has short
run-time, or a miss so we need to check slower memories which takes longer.
Therefore, the real-time analysis must often assume that the caches will miss,
since this is the worst-case, and the overall WCET estimate will be far
detached from the real run-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; As far as I know, hard real-time systems often rely on small
processors, like the ARM Cortex-M0, or processors with relatively simple
pipelines and caches because these are easier to analyze. For example, you can
see &lt;a href=&quot;https://www.absint.com/ait/targets.htm&quot;&gt;this&lt;/a&gt; list of targets supported by
a commercial real-time analysis tool. There is also extensive research to try
to account for more complex processors, but I have not looked much into it.&lt;/p&gt;

&lt;p&gt;In summary, we would like to make WCET analysis easier for ourselves to check
whether the system will meet its deadlines. We can do so by ensuring that the
program’s worst-case and best-case run-times are not outrageously different.
We can also use simpler processors that do not have complicated features, like
caching, that introduce unpredictability in the run-time of instructions. And
without further ado, lets analyze a simple program to see how WCET works. We
will perform the analysis in two steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Control Flow Graph (CFG) construction&lt;/li&gt;
  &lt;li&gt;Implicit Path Enumeration (IPET)&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;control-flow-graph&quot;&gt;Control Flow Graph&lt;/h1&gt;

&lt;p&gt;We will analyze the following C program that implements
&lt;a href=&quot;https://en.wikipedia.org/wiki/Bubble_sort&quot;&gt;bubblesort&lt;/a&gt; to sort 10 integers. I
took this code from the &lt;a href=&quot;https://github.com/mageec/beebs&quot;&gt;BEEBS&lt;/a&gt; benchmarks
mostly because it is relatively straight-forward to analyze.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define FALSE 0
#define TRUE 1
#define NUMELEMS 10
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BubbleSort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sorted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUMELEMS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Sorted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUMELEMS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUMELEMS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Sorted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FALSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The C code above is there mostly for illustration purposes because we are
actually interested in the disassembly of that program’s binary. Analysing the
disassembly, as opposed to the C code, takes into account any optimizations and
transformations introduced by the compiler, so we eliminate potential errors in
our estimation. In this case, it looks like the compiler inlined the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BubbleSort&lt;/code&gt; function into another function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;benchmark&lt;/code&gt; to produce the
code shown below. The program was compiled with LLVM 10 for the ARMv6-M
architecture.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;00000074 &amp;lt;benchmark&amp;gt;:
  74:	b5f0      	push	{r4, r5, r6, r7, lr}
  76:	2000      	movs	r0, #0
  78:	2164      	movs	r1, #100	; 0x64
  7a:	4a0d      	ldr	r2, [pc, #52]	; (b0 &amp;lt;benchmark+0x3c&amp;gt;)
  7c:	6813      	ldr	r3, [r2, #0]
  7e:	2601      	movs	r6, #1
  80:	460c      	mov	r4, r1
  82:	4615      	mov	r5, r2
  84:	e006      	b.n	94 &amp;lt;benchmark+0x20&amp;gt;
  86:	602f      	str	r7, [r5, #0]
  88:	606b      	str	r3, [r5, #4]
  8a:	2600      	movs	r6, #0
  8c:	1e64      	subs	r4, r4, #1
  8e:	1d2d      	adds	r5, r5, #4
  90:	2c00      	cmp	r4, #0
  92:	d004      	beq.n	9e &amp;lt;benchmark+0x2a&amp;gt;
  94:	686f      	ldr	r7, [r5, #4]
  96:	42bb      	cmp	r3, r7
  98:	dcf5      	bgt.n	86 &amp;lt;benchmark+0x12&amp;gt;
  9a:	463b      	mov	r3, r7
  9c:	e7f6      	b.n	8c &amp;lt;benchmark+0x18&amp;gt;
  9e:	2e00      	cmp	r6, #0
  a0:	d103      	bne.n	aa &amp;lt;benchmark+0x36&amp;gt;
  a2:	1e49      	subs	r1, r1, #1
  a4:	1c40      	adds	r0, r0, #1
  a6:	2864      	cmp	r0, #100	; 0x64
  a8:	d1e8      	bne.n	7c &amp;lt;benchmark+0x8&amp;gt;
  aa:	2000      	movs	r0, #0
  ac:	bdf0      	pop	{r4, r5, r6, r7, pc}
  ae:	46c0      	nop			; (mov r8, r8)
  b0:	00000164 	.word	0x00000164
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first step in the analysis is to construct a &lt;a href=&quot;https://en.wikipedia.org/wiki/Control-flow_graph&quot;&gt;&lt;em&gt;Control Flow Graph
(CFG)&lt;/em&gt;&lt;/a&gt; out of this
disassembly. The CFG is a directed graph representation that captures the
control-flow information, i.e. branches, conditionals, loops, etc, from the
program. The nodes of a CFG represent blocks of code without branches or branch
destinations, while the edges are branches as shown in the figure below. Each
node and edge is given an identifier (e.g. block0 or b0 for short, e0, b1,
etc) for convenience and a &lt;em&gt;cost coefficient&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The cost coefficient represents the worst-case cost, in clock cycles, of
executing the sequence of instructions in a node’s block of code. And this is
where the choice of processor is very important! A &lt;em&gt;cost model&lt;/em&gt; of the chosen
processor is used to estimate the time that the microarchitecture takes to
execute each instructions. From this, we calculate each node and edge’s cost
coefficient. If the processor has unpredictable features like complex caching
then its hard to approximate the worst-case run-time of instructions, and as a
result, the cost cofficients could be way off-board.&lt;/p&gt;

&lt;p&gt;In our case, the cost model is very simple because hard real-time analysis
targets a processor similar to an ARM Cortex-M0 which has a very simple
microarchitecture with the very predictable execution times listed
&lt;a href=&quot;https://developer.arm.com/documentation/ddi0432/c/programmers-model/instruction-set-summary&quot;&gt;here&lt;/a&gt;.
For example, node b6 has a compare (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmp&lt;/code&gt;) instruction followed by a
conditional branch (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bne&lt;/code&gt;) with 1 and 3 clock cycles of run-time respectively,
so the cost coefficient for b6 is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1 + 3 = 4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I generated this CFG using a tool I jointly developed with a
colleague during my PhD. It takes an ARMv6-M program binary as an input along
with a configuration file to produce the WCET estimate (among other things like
the CFG!). The tool is open-source and is available &lt;a href=&quot;https://github.com/andresag01/bwca&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; CFG’s are not unique to real-time analysis. They are used in many
other applications like compilers.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/cfg-bubblesort.png&quot; alt=&quot;Control Flow Graph (CFG) for bubblesort.&quot; height=&quot;90%&quot; width=&quot;90%&quot; /&gt;&lt;/p&gt;

&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Control Flow Graph for the bubblesort program. block0 is the start of the
function. block10 is a placeholder exit node to ensure that the CFG has a single
exit point. The exit node has no &quot;cost&quot; because it does not include any real
instructions.&lt;/em&gt;
&lt;/p&gt;

&lt;h1 id=&quot;integer-linear-programming&quot;&gt;Integer Linear Programming&lt;/h1&gt;

&lt;p&gt;The second part of the analysis uses &lt;em&gt;Implict Path Enumeration (IPET)&lt;/em&gt; to
calculate the WCET. IPET derives an &lt;a href=&quot;https://en.wikipedia.org/wiki/Integer_programming&quot;&gt;&lt;em&gt;Integer Linear Programming
(ILP)&lt;/em&gt;&lt;/a&gt; problem by combining
the flow information and coefficients encoded in the CFG. It consists of an
objective function, that encodes the run-time of the code when solved, and a
set of constraints over the variables in that function.&lt;/p&gt;

&lt;p&gt;The ILP problem for our bubblesort CFG is shown below. It tells us that the
run-time of the code will be 11 clock cycles (i.e. b0’s cost coefficient)
multiplied by the number of times that node b0 in the CFG is executed plus 9
clock cycles multiplied by the number of times that node b1 is executed and so
on. But the ILP also gives us a few restrictions or contraints when calculating
a solution for the variables b0, b1, e4, e6, etc. For example, there is an
input constraint &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b0 = 1&lt;/code&gt; meaning that the code at node b0 can only be executed
once on entry to the function which makes sense because that code is not within
a loop. There is also an output constraint &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b0 = e0&lt;/code&gt; restricting edge e0 to be
“executed” as many times as the code at b0 is executed.&lt;/p&gt;

&lt;p&gt;The ILP formulation is constructed from a simple graph traversal of the CFG.
Each node and edge has a cost coefficient (or 0) and a unique identifier; the
objective function is a summation of these terms. The majority of the
constraints relate the number of times that the edges are followed with how
often the node is executed. Loop bounds are the only constraints that are
difficult to construct as the information is not readily available in the CFG,
so these bounds are either input manually or estimated automatically using a
tool like &lt;a href=&quot;https://drops.dagstuhl.de/opus/volltexte/2007/1194/&quot;&gt;SWEET&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* Objective function */
max: 11 b0 + 9 b1 + 5 b2 + 6 b3 + 7 b4 + 4 b5 + 4 b6 + 6 b7 + 11 b8 + 0 b10
     - 2 e4 - 2 e6 - 2 e9 - 2 e11;

/* Output constraints */
b0 = e0;
b1 = e1;
b2 = e2;
b3 = e3 + e4;
b4 = e5 + e6;
b5 = e7;
b6 = e8 + e9;
b7 = e10 + e11;
b8 = e12;
b10 = 1;

/* Input constraints */
b0 = 1;
b1 = e0 + e10;
b2 = e5;
b3 = e2 + e7;
b4 = e1 + e4;
b5 = e6;
b6 = e3;
b7 = e9;
b8 = e8 + e11;
b10 = e12;

/* Loop constraints */
10 b0 &amp;lt;= b1;
b1 &amp;lt;= 10 b0;
10 b1 &amp;lt;= b4;
b4 &amp;lt;= 10 b1;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we need to solve the ILP problem by maximizing the objective function
as we would like to calculate the &lt;em&gt;worst-case&lt;/em&gt; execution time. We can do just
that with a nice tool called &lt;a href=&quot;http://web.mit.edu/lpsolve/doc/&quot;&gt;lp_solve&lt;/a&gt; that
you probably have installed in your Linux computer without realizing. The
lp_solve output for our bubblesort ILP is shown below, so the WCET estimate for
this code is 1810 clock cycles!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Value of objective function: 1810.00000000

Actual values of the variables:
b0                              1
b1                             10
b2                            100
b3                            100
b4                            100
b5                              0
b6                             10
b7                             10
b8                              1
b10                             1
e4                             90
e6                              0
e9                             10
e11                             1
e0                              1
e1                             10
e2                            100
e3                             10
e5                            100
e7                              0
e8                              0
e10                             9
e12                             1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;And that is it! We statically analyzed a hard real-time implementation of
bubblesort and estimated a WCET. It is worth pointing out that this is
frustratingly difficult in practice as the complexity of the problem increases
very quickly when programs are larger or the processor has more features. Also,
there is a lot of manual labour involved in getting the right parameters, like
look bounds, and constantly re-designing bits of your system to try to fulfil
the real-time constraints. But hopefully this was a helpful introduction to
hard real-time systems!&lt;/p&gt;</content><author><name></name></author><summary type="html">In a previous post (here) we discussed what are and the types of real-time systems. We also gave some examples to highlight their importance and clarify some of the confusion regarding the real-time and run-time performance tradeoff. In this post, we will focus exclusively on “hard” real-time systems and how they are statically analyzed (i.e. before the program is run) to guarantee that deadlines are never missed.</summary></entry><entry><title type="html">What are Real-Time Systems?</title><link href="/2022/01/25/real-time-1.html" rel="alternate" type="text/html" title="What are Real-Time Systems?" /><published>2022-01-25T08:21:09+00:00</published><updated>2022-01-25T08:21:09+00:00</updated><id>/2022/01/25/real-time-1</id><content type="html" xml:base="/2022/01/25/real-time-1.html">&lt;p&gt;Explaining research ideas clearly was perhaps my most difficult undertaking
while pursuing a &lt;a href=&quot;/2021/09/30/phd-thesis.html&quot;&gt;PhD&lt;/a&gt;. More often than
not, my explanations were frankly incomprehenible and that is entirely my own
fault. But sometimes my audience had inaccurate ideas and misplaced
expectations about the subject matter. I found real-time systems to be one of
those misunderstood topics. In the remaining of this post, I will attempt to
clear up some of the confusion and explain what real-time systems are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This is the first post of a two-part series about real-time systems.
The following post will mostly talk about hard real-time analysis.&lt;/p&gt;

&lt;h2 id=&quot;what-are-real-time-systems&quot;&gt;What are Real-Time Systems?&lt;/h2&gt;

&lt;p&gt;Every applications imposes a set of constrains that computer engineers are
constantly battling to meet. Of course, a constraint is (almost!) always that
the program should produce the correct result. But it is also common to want a
system to perform a task as fast as possible, these are run-time constraints,
or to ensure that a device’s battery life lasts longer, as in a constraint on
power consumption. A real-time system is simply a system that has &lt;em&gt;timing&lt;/em&gt;
constraints in addition to correctness and (potentially) run-time or power
requirements. In a real-time system, the time when a result is produced (i.e.
before a deadline) is as important as ensuring that the result is correct.&lt;/p&gt;

&lt;p&gt;Lets consider a couple of use-cases. Classic examples of real-time applications
are &lt;a href=&quot;https://en.wikipedia.org/wiki/Safety-critical_system&quot;&gt;safety-critical
systems&lt;/a&gt; such as &lt;a href=&quot;https://en.wikipedia.org/wiki/Artificial_cardiac_pacemaker&quot;&gt;cardiac
pacemakers&lt;/a&gt;, engine
control systems and avionics. Clearly, these systems must always operate
correctly &lt;em&gt;and&lt;/em&gt; deliver results on time (i.e. before a deadline) otherwise
patients may die, your car engine might explote or a plane could crash.
Interactive systems are also good examples of real-time systems, although not
quite as critical, such as mobile phones or desktop PCs. For example, we like
responsive PCs that keep the mouse pointer moving smoothly, windows
switching quickly and videos or music playing clearly. These are all real-time
tasks and the deadline usually is “before the user gets annoyed”.  Unresponsive
PCs make unhappy and frustrated users, and I have been known to angrily strike
the keyboard once or twice when this happens!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; A coincidentally pedantic note on the use of the words &lt;em&gt;run-time&lt;/em&gt; and
&lt;em&gt;runtime&lt;/em&gt;. Lots of people (myself included!) often use these words
interchangeable, but I was very fortunate to have been corrected by someone
peer reviewing my journal submission. So nowadays I use the word
&lt;em&gt;run-time&lt;/em&gt; to mean the length of time that something takes to run. I also refer
to a program’s status of being running as &lt;em&gt;run-time&lt;/em&gt;, e.g. as in variables are
resolved at run-time. In contrast, I use &lt;em&gt;runtime&lt;/em&gt; to mean the environment in
which a program is running, e.g. as in a runtime library. These definitions are
by no means perfect, but I strive to be consistent!&lt;/p&gt;

&lt;h2 id=&quot;real-time-systems-are-not&quot;&gt;Real-Time Systems are NOT…&lt;/h2&gt;

&lt;p&gt;Fast, power-efficient, secure, small, etc. Or rather, real-time systems are not
&lt;em&gt;necessarily&lt;/em&gt; fast, power-efficient, secure, small, etc. These are individual
constraints that a system could be required to meet, but neither of them implies
the other. Many people are particularly puzzled to hear that a fast system,
i.e. the run-time of a task is very short, does not mean that it is real-time.
In fact, real-time are systems often slower than their non-real-time
counterparts due to the overheads inherent to concurrent operation, such as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Context_switch&quot;&gt;context switching&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Synchronization_(computer_science)&quot;&gt;synchronization&lt;/a&gt;,
etc.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)&quot;&gt;Garbage
collection&lt;/a&gt;
is an example that neatly illustrates this real-time and run-time performance
tradeoff. The collector is a component of the runtime environment responsible
for automatically reclaiming unused memory and repurposing it to fulfil future
dynamic memory allocation requests. Its work is critical to both the
real-time and run-time performance of many programming languages like Python,
JavaScript, Java, etc.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/real-time-gc-stw.png&quot; alt=&quot;Stop-the-world garbage collectors.&quot; height=&quot;70%&quot; width=&quot;70%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Stop-the-world garbage collectors. Each bar represents the execution in a single core.
White regions are the execution of the user's program threads and shaded regions
correspond to the collector's execution.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;The simplest and fastest collectors are &lt;em&gt;stop-the-world&lt;/em&gt;: the user’s program is
stopped while the collector does its job and then the program is restarted as
shown above. The run-time performance of these collectors is great because
there is little interaction with the user’s program. In fact, it is
straight-forward to run these collectors in a single-core or in parallel across
multiple cores to reclaim memory faster. But the real-time performance of the
system is atrocious either way because the user’s program is stopped (i.e.
paused, does not run) while the collector runs, so any task that the program is
supposed to do is delayed. &lt;em&gt;Concurrent&lt;/em&gt; collectors mitigate this real-time
problem by either running collection operations interleaved or in parallel with
the program as shown below.&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;/images/real-time-gc-concurrent.png&quot; alt=&quot;Concurrent garbage collectors.&quot; height=&quot;70%&quot; width=&quot;70%&quot; /&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;
&lt;em&gt;Concurrent garbage collectors.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;However, concurrent collectors require a lot of synchronization to make sure
the system works properly. Sadly, the extra synchronization often incurs high
run-time overheads although this is unavoidable for the system to operate in
real-time.&lt;/p&gt;

&lt;p&gt;You can clearly see this tradeoff for yourself in &lt;a href=&quot;https://youtu.be/Scxz6jVS4Ls&quot;&gt;this
presentation&lt;/a&gt; about the JavaScript V8 Engine
which is used in Chrome. Ideally, the web browser runs at 60 fps to avoid jank,
so each frame must be generated in about 16 ms. But using a stop-the-world
garbage collector caused earlier Chrome versions to often miss these deadlines.
More recent Chrome versions use a mostly concurrent collector. The video below
compares the very visible effects of both collectors.&lt;/p&gt;

&lt;div style=&quot;text-align:center;&quot;&gt;
    &lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Scxz6jVS4Ls?start=183&amp;amp;end=220&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;
    &lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&quot;types-of-real-time-systems&quot;&gt;Types of Real-Time Systems&lt;/h2&gt;

&lt;p&gt;You might have noticed that not all real-time systems are the same. It is
important to consider the kind and strictness of timing requirements when
engineering such systems. So it is common to clasify real-time systems as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Soft Real-Time:&lt;/strong&gt; There are many systems, like phones, tablets, etc, where
it is desirable to meet deadlines, but there is no harm if deadlines are missed
occasionally. For example, we said that ideally Chrome runs at 60 fps although
nobody will die if sometimes it does 55, 58, 56 fps! In other words,
it is desirable for the real-time system to meet all its deadlines, but in
practice, its acceptable if some deadlines are missed because the worst
consequece is perhaps an annoyed user.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hard Real-Time:&lt;/strong&gt; The system must &lt;em&gt;always&lt;/em&gt; meet deadlines if hard real-time
operation is required. Failure to meet a deadline is equivalent to an incorrect
calculation and can result in catastrophic consequences such as the death of
a patient or an airplane crashing. Cardiac pacemakers and avionics are good
examples of hard real-time systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Naturally, the approach for engineering and testing soft real-time systems is a
lot more informal. The system is developed and empirical experiments are run in
various settings to ensure that most deadlines are met i.e. that the frequency
of missed deadlines is below a threshold. I have even heard of engineers
testing soft real-time systems with slow processors and then switching to
faster ones (or cranking up the clock!) just to make extra sure that the final
product does meet &lt;em&gt;most&lt;/em&gt; deadlines. In contrast, there are formal static
analysis methods to evaluate hard real-time systems and guarantee that no
deadlines are missed under &lt;em&gt;any&lt;/em&gt; circumstance. I will describe one such method
in the next blog post.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In conclusion, real-time systems are simply systems that have timing
contraints. That is, the device must perform a task before a deadline. Broadly
speaking, real-time devices are either soft or hard real-time depending on how
strict we need to be about meeting deadlines. In the following post, we will
focus almost exclusively on how to statically analyze hard real-time programs
to guarantee that timing requirements are always met.&lt;/p&gt;</content><author><name></name></author><summary type="html">Explaining research ideas clearly was perhaps my most difficult undertaking while pursuing a PhD. More often than not, my explanations were frankly incomprehenible and that is entirely my own fault. But sometimes my audience had inaccurate ideas and misplaced expectations about the subject matter. I found real-time systems to be one of those misunderstood topics. In the remaining of this post, I will attempt to clear up some of the confusion and explain what real-time systems are.</summary></entry><entry><title type="html">Integrated Hardware Garbage Collection for Real-Time Embedded Systems</title><link href="/2021/09/30/phd-thesis.html" rel="alternate" type="text/html" title="Integrated Hardware Garbage Collection for Real-Time Embedded Systems" /><published>2021-09-30T10:21:09+00:00</published><updated>2021-09-30T10:21:09+00:00</updated><id>/2021/09/30/phd-thesis</id><content type="html" xml:base="/2021/09/30/phd-thesis.html">&lt;p&gt;I recently completed my thesis while pursuing a PhD in Computer Science at the
University of Bristol. The thesis, titled &lt;em&gt;Integrated Hardware Garbage
Collection for Real-Time Embedded Systems&lt;/em&gt;, is shared below under the
&lt;a href=&quot;http://creativecommons.org/licenses/by-nc/4.0/&quot;&gt;Creative Commons Attribution-NonCommercial 4.0
International&lt;/a&gt; license.&lt;/p&gt;

&lt;p&gt;The thesis is related to garbage collection, computer architecture, memory
management, among other topics. I continue to be interested in the subject, so
please feel free to reach out with questions, comments, ideas, thoughts, etc.
My contact details are &lt;a href=&quot;/about/&quot;&gt;here&lt;/a&gt; and at the bottom of this
page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; A lot of the articles in this blog are about findings or ideas that I
came across while working on my PhD thesis!&lt;/p&gt;

&lt;h1 id=&quot;abstract&quot;&gt;Abstract&lt;/h1&gt;

&lt;p&gt;Modern programming languages, like Python and C#, provide
productivity and trust benefits that are key in managing the growing complexity
of computer systems. However, modern language implementations rely on software
garbage collection which imposes high overheads and unpredictable pauses. This
is tolerable in large computer systems, like desktops and servers, but
impractical for real-time embedded systems. Hence modern languages are rarely
used to program embedded devices.&lt;/p&gt;

&lt;p&gt;This thesis investigates a shift in architecture towards hardware garbage
collection to better support modern languages in embedded devices while meeting
their unique performance and real-time requirements. We present an
Integrated Hardware Garbage Collector (IHGC) that demonstrates this
approach: a collector that is tightly coupled with the processor and runs
continuously in the background. Our design allocates a memory cycle to the
collector when the processor is not using the memory. The IHGC achieves this by
careful subdivision of collection work into single-memory-access steps that are
interleaved with the processor’s memory accesses. We also introduce a static
analysis technique to guarantee that real-time programs are never paused by the
IHGC. As a result, our collector eliminates run-time overheads and is suitable
for real-time embedded systems.&lt;/p&gt;

&lt;p&gt;The IHGC is evaluated through simulation based on a hardware implementation
model using modern fabrication technologies. Our experiments indicate that
the IHGC offers 1.5-7 times better performance compared to a conventional
processor running a software garbage collector. In addition, our static,
real-time analysis technique was evaluated through practical use cases showing
that an IHGC system meets specific timing constraints. This thesis concludes
that the IHGC delivers in real-time the benefits of garbage collected languages
without the complexity and overheads inherent in software collectors.&lt;/p&gt;

&lt;h1 id=&quot;download&quot;&gt;Download&lt;/h1&gt;

&lt;p&gt;You can download the thesis from &lt;a href=&quot;/download/phd_thesis.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;related-publications&quot;&gt;Related Publications&lt;/h1&gt;

&lt;p&gt;The following publications are related to the contents of the thesis:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A. Amaya García, D. May and E. Nutting, Garbage Collection for Edge
Computing, in 2020 IEEE/ACM Symposium on Edge Computing (SEC), 2020, pp.
319-319. Accessible &lt;a href=&quot;https://ieeexplore.ieee.org/document/9355637&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;A. Amaya García, D. May and E. Nutting, Integrated Hardware Garbage
Collection, ACM Transactions on Embedded Computer Systems (TECS), 2021. Accessible
&lt;a href=&quot;https://dl.acm.org/doi/10.1145/3450147&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">I recently completed my thesis while pursuing a PhD in Computer Science at the University of Bristol. The thesis, titled Integrated Hardware Garbage Collection for Real-Time Embedded Systems, is shared below under the Creative Commons Attribution-NonCommercial 4.0 International license.</summary></entry><entry><title type="html">Dynamic Linking to a Different libc</title><link href="/2021/05/08/libc-linking.html" rel="alternate" type="text/html" title="Dynamic Linking to a Different libc" /><published>2021-05-08T10:21:09+00:00</published><updated>2021-05-08T10:21:09+00:00</updated><id>/2021/05/08/libc-linking</id><content type="html" xml:base="/2021/05/08/libc-linking.html">&lt;p&gt;Sometimes it is necessary to run a dynamically linked program using an
alternative libc from the system’s. In the remaining of this post, we will take
a look at a few ways of doing that in Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The contents of this post were put together from several
StackOverflow answers that were helpful to me when dealing with this problem
(see &lt;a href=&quot;https://stackoverflow.com/questions/847179/multiple-glibc-libraries-on-a-single-host&quot;&gt;here&lt;/a&gt;
and &lt;a href=&quot;https://unix.stackexchange.com/questions/120015/how-to-find-out-the-dynamic-libraries-executables-loads-when-run&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;h1 id=&quot;finding-dynamic-library-dependencies&quot;&gt;Finding Dynamic Library dependencies&lt;/h1&gt;

&lt;p&gt;Lets start from the beginning: How do you find the dynamic library dependencies
of an existing executable? There are two easy ways to do this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd&lt;/code&gt;: This command is perhaps the most straight-forward method. Here is an
example.
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ldd &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;which &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
     linux-vdso.so.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007ffe867fa000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     libcap.so.2 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib/libcap.so.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f6faa5bd000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     libc.so.6 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib/libc.so.6 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f6faa3f0000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     /lib64/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib64/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f6faa607000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;The output is mostly self-explanatory: The first line is Linux’s &lt;a href=&quot;https://man7.org/linux/man-pages/man7/vdso.7.html&quot;&gt;vDSO (Virtual
Dynamic Shared Object)&lt;/a&gt;
which is a small shared object that we do not have to care about. libcap and
libc in the second and third lines of output are library dependencies while the
last line is the &lt;a href=&quot;https://linux.die.net/man/8/ld-linux&quot;&gt;dynamic linker/loader&lt;/a&gt;
(this runs implicitly whenever you execute a dynamically linked program).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readelf&lt;/code&gt;: This is the classic utility to display information about ELF
files (see &lt;a href=&quot;https://linux.die.net/man/1/readelf&quot;&gt;here&lt;/a&gt;). Run it like this to
display the contents of the ELF’s dynamic section:
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;readelf &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;which &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
Dynamic section at offset 0x21a58 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;NEEDED&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;             Shared library: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;libcap.so.2]
 0x0000000000000001 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;NEEDED&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;             Shared library: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;libc.so.6]
 0x000000000000000c &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;INIT&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;               0x4000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;Again, the content is mostly self-explanatory.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; These commands can be useful to track down which libraries you are
missing!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readelf&lt;/code&gt; do not show information about libraries loaded at
run-time using &lt;a href=&quot;https://man7.org/linux/man-pages/man3/dlopen.3.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dlopen&lt;/code&gt;&lt;/a&gt;.
Use other utilities for that!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The advantage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readelf&lt;/code&gt; over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd&lt;/code&gt; is that the it shows you the
ELF’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Rpath&quot;&gt;rpath&lt;/a&gt; (if any). Read on for more
information about the rpath.&lt;/p&gt;

&lt;h1 id=&quot;linking-against-a-specific-libc&quot;&gt;Linking Against a Specific libc&lt;/h1&gt;

&lt;p&gt;By default, ELF files are linked against the system’s libc (usually found at
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/lib/&lt;/code&gt;). We will explore three ways to link against another libc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The libc consists of many shared objects. The versions of these files
must match since they contain some hard-coded information (e.g. file paths), so
do not attempt to link against shared objects from different libcs.&lt;/p&gt;

&lt;h2 id=&quot;method-1-ld_library_path&quot;&gt;Method 1: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;This is perhaps the easiest way if you have an already built ELF executable.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt; is an environment variable with a colon-separated list of
paths telling the linker &lt;em&gt;where&lt;/em&gt; to look for libraries. Here is a usage
example:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/andres/Repos/glibc-2.33/install/lib
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ldd &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;which &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
        linux-vdso.so.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007fff889ec000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        libcap.so.2 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib/libcap.so.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f61144fa000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        libc.so.6 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /home/andres/Repos/glibc-2.33/install/lib/libc.so.6 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f6114337000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        /lib64/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib64/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f6114544000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd&lt;/code&gt; resolved the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc.so.6&lt;/code&gt; to the alternative libc indicated in
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt;. However, my alternative libc does not contain
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libcap.so.2&lt;/code&gt;, so this shared object was resolved using the system’s libraries
at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/lib&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Changing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LD_LIBRARY_PATH&lt;/code&gt; works well in most cases, but it cannot
overwrite the &lt;a href=&quot;https://en.wikipedia.org/wiki/Rpath&quot;&gt;run-time search path
(rpath)&lt;/a&gt; hard-coded into an ELF
executable. We will look at one way to change the rpath later in this post.&lt;/p&gt;

&lt;h2 id=&quot;method-2-using-the-dynamic-linkerloader&quot;&gt;Method 2: Using the Dynamic Linker/Loader&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://linux.die.net/man/8/ld-linux&quot;&gt;dynamic linker/loader&lt;/a&gt; is run
implicitly when you run a dynamically linked executable. It looks like a shared
object file, but can be run explicitly to configure dynamic linking options.
Perhaps its most useful command line option is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--library-path&lt;/code&gt; which allows
you to indicate a colon-separated list of locations to resolve the dynamic
libraries. Here is an example of running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; with an alternative libc that I
downloaded and compiled from source:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/home/andres/Repos/glibc-2.33/install/lib/ld-linux-x86-64.so.2        \
    --library-path /home/andres/Repos/glibc-2.33/install/lib:/usr/lib \
    $(which ls)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Take a look at the dynamic linker/loader command line options by
running it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--help&lt;/code&gt;. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/lib64/ld-linux-x86-64.so.2 --help&lt;/code&gt; in
my system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The dynamic linker/loader is a little bit temperamental, so only pass
absolute paths to it. Avoid using relative paths like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;..&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;method-3-set-the-rpath-at-link-time&quot;&gt;Method 3: Set the rpath at Link-Time&lt;/h2&gt;

&lt;p&gt;The idea is to set the ELF’s rpath at link-time by passing compiler flags. This
is obviously inconvenient if you already have an executable and do not want (or
cannot) link it once again, but is still an effective mechanism.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--rpath&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--dynamic-linker&lt;/code&gt; are the linker options to configure the rpath
and the dynamic linker/loader. Here is a usage example:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cc &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-lm&lt;/span&gt;                                                                          &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-Wl&lt;/span&gt;,--rpath&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/andres/Repos/glibc-2.33/install/lib                               &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-Wl&lt;/span&gt;,--dynamic-linker&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/home/andres/Repos/glibc-2.33/install/lib/ld-linux-x86-64.so.2 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    test.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readelf&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ldd&lt;/code&gt; outputs confirm that the rpath for my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt; executable
is set to the desired location, so the dynamic linker/loader will use the
alternative shared objects for libc and libm.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;readelf &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;test

&lt;/span&gt;Dynamic section at offset 0x2dd8 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;NEEDED&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;             Shared library: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;libm.so.6]
 0x0000000000000001 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;NEEDED&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;             Shared library: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;libc.so.6]
 0x000000000000000f &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;RPATH&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;              Library rpath: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;/home/andres/Repos/glibc-2.33/install/lib]
...

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ldd &lt;span class=&quot;nb&quot;&gt;test
        &lt;/span&gt;linux-vdso.so.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007ffcfea8f000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        libm.so.6 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /home/andres/Repos/glibc-2.33/install/lib/libm.so.6 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f7564e67000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        libc.so.6 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /home/andres/Repos/glibc-2.33/install/lib/libc.so.6 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f7564ca4000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        /home/andres/Repos/glibc-2.33/install/lib/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; /usr/lib64/ld-linux-x86-64.so.2 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x00007f7564faf000&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; According to &lt;a href=&quot;https://stackoverflow.com/a/44710599/2111578&quot;&gt;this&lt;/a&gt;
post, it is also possible to change the rpath of an existing ELF with
&lt;a href=&quot;https://github.com/NixOS/patchelf&quot;&gt;patchelf&lt;/a&gt;, but I have never tried this. The
advange over Method 3 is that patchelf does not require you to link the program
again.&lt;/p&gt;</content><author><name></name></author><summary type="html">Sometimes it is necessary to run a dynamically linked program using an alternative libc from the system’s. In the remaining of this post, we will take a look at a few ways of doing that in Linux.</summary></entry><entry><title type="html">C++11: Invalid Suffix on Literal Warning/Error</title><link href="/2021/03/06/invalid-suffix-on-literal.html" rel="alternate" type="text/html" title="C++11: Invalid Suffix on Literal Warning/Error" /><published>2021-03-06T10:21:09+00:00</published><updated>2021-03-06T10:21:09+00:00</updated><id>/2021/03/06/invalid-suffix-on-literal</id><content type="html" xml:base="/2021/03/06/invalid-suffix-on-literal.html">&lt;p&gt;I recently came across this unexpected error when compiling C++ code using
Clang:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;error: invalid suffix on literal; C++11 requires a space between literal and identifier
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I got a similar message, although as a warning, when compiling the same code
with GCC:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;warning: invalid suffix on literal; C++11 requires a space between literal and string macro
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The problem occurs when compiling code like this:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Test %&quot;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRIu32&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that there is no space between the string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Test %&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PRIu32&lt;/code&gt; which is
apparently a requirement in C++11 (or newer). Fortunately, the fix is quite
simple – just add spaces between the string and identifier. So the equivalent
code below fixes the problem:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Test %&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRIu32&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But what if you have a lot of legacy code that you cannot modify? There are a
couple of flags that can disable the warnings/errors, but these are different
for Clang and GCC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; An obvious way to get rid of the problem in both Clang and GCC is to
indicate a C++ standard version earlier than C++11. For example, invoking the
compiler with the flag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-std=c++03&lt;/code&gt; fixes the problem, but of course, this is
not an ideal solution.&lt;/p&gt;

&lt;h1 id=&quot;clang&quot;&gt;Clang&lt;/h1&gt;

&lt;p&gt;In Clang, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;invalid suffix literal&lt;/code&gt; message shows as an error by default.
You can turn it into a warning message with the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Wno-error=reserved-user-defined-literal&lt;/code&gt; flag. Alternatively, you can
completely eliminate the warning/error message with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Wno-reserved-user-defined-literal&lt;/code&gt;.
For example,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;clang++ -std=c++11 -Wno-error=reserved-user-defined-literal -c -o test.o test.cpp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;a href=&quot;https://clang.llvm.org/docs/UsersManual.html#options-to-control-error-and-warning-messages&quot;&gt;This page&lt;/a&gt;
from the Clang documentation explains how the warning and error flags
work.&lt;/p&gt;

&lt;h1 id=&quot;gcc&quot;&gt;GCC&lt;/h1&gt;

&lt;p&gt;In GCC, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;invalid suffix literal&lt;/code&gt; message shows as a warning by default. You
can eliminate the message with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Wno-literal-suffix&lt;/code&gt; flag. For example,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;g++ -std=c++11 -Wno-literal-suffix -c -o test.o test.cpp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html&quot;&gt;This page&lt;/a&gt;
from the GCC documentation explains how the warning and error flags work.&lt;/p&gt;</content><author><name></name></author><summary type="html">I recently came across this unexpected error when compiling C++ code using Clang:</summary></entry><entry><title type="html">Managing Audio in i3 with PulseAudio</title><link href="/2020/12/03/i3-and-pulse-audio.html" rel="alternate" type="text/html" title="Managing Audio in i3 with PulseAudio" /><published>2020-12-03T10:21:09+00:00</published><updated>2020-12-03T10:21:09+00:00</updated><id>/2020/12/03/i3-and-pulse-audio</id><content type="html" xml:base="/2020/12/03/i3-and-pulse-audio.html">&lt;p&gt;I recently switched to i3 after using GNOME for a few years. Unlike many window
managers, i3 is very bare-bones and its default installation does not include
functionality to manage audio through a graphical interface like you would in
GNOME. I fixed the problem by modifying my i3 configuration instead of
installing a graphical application such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gnome-control-center&lt;/code&gt;. Here is how
I did it using
&lt;a href=&quot;https://www.freedesktop.org/wiki/Software/PulseAudio/#:~:text=PulseAudio%20is%20a%20sound%20system,your%20application%20and%20your%20hardware.&quot;&gt;PulseAudio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lets look at the easy part first: mute audio and increase/decrease volume. With
a bit of Googling, you can actually find a lot of suggestions for how to do
this. I chose to do it through i3 by mapping the F10, F11 and F12 keys to
PulseAudio commands that mute, decrease volume and increase volume
respectively. I added the following lines to my i3 config file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bindsym $mod+F10 exec pactl set-sink-mute @DEFAULT_SINK@ toggle # Mute
bindsym $mod+F11 exec pactl set-sink-volume @DEFAULT_SINK@ -5%  # Up
bindsym $mod+F12 exec pactl set-sink-volume @DEFAULT_SINK@ +5%  # Down
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The volume is increased/decrease by 5% for each time that the commands are
issued. A small matter with PulseAudio is that you can actuall set the volume
above 100%!&lt;/p&gt;

&lt;p&gt;A slightly harder problem I had was to changing the output device. For example,
my computer has two output devices for audio: a speaker and the headphones. I
wanted an easy and quick way to change the output audio device (or sink in
PulseAudio terminology) with a keystroke (or two). So I mapped the F9 key to
execute a bash script which does just that. Here is the relevant line in my i3
configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bindsym $mod+F9  exec ~/.config/i3/toggle_sink.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The script relies on PulseAudio commands and is relatively simple. It does
three things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Query a list of possible output sinks.&lt;/li&gt;
  &lt;li&gt;Update the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEFAULT_SINK&lt;/code&gt; to the next available output sink in the
previously queried list.&lt;/li&gt;
  &lt;li&gt;Redirect all currently playing audio streams to the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEFAULT_SINK&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEFAULT_SINK&lt;/code&gt; is the sink that the mute and increase/decrease
audio commands will affect. Also, simply changing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEFAULT_SINK&lt;/code&gt; does not
cause the currently playing audio to be automatically redirected to that sink.&lt;/p&gt;

&lt;p&gt;Whenever the script is executed, all sound is redirected to the next sink in
the list. So repeatedly pressing $Mod+F9 effectively lets me cycle through the
audio output devices with a couple of keystrokes!&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#! /usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-eu&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Get the ID for the current DEFAULT_SINK&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;defaultSink&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;pactl info | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Default Sink: &quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{ print $3 }'&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Query the list of all available sinks&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;sinks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=()&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;line&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$line&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{ print $1 }'&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    sinks[&lt;span class=&quot;k&quot;&gt;${#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sinks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Find the current DEFAULT_SINK&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$defaultSink&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$line&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;defaultIndex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;defaultPos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;pactl list sinks short&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Compute the ID of the new DEFAULT_SINK&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;newDefaultPos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$defaultPos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sinks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;newDefaultSink&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;sinks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$newDefaultPos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Update the DEFAULT_SINK&lt;/span&gt;
pacmd set-default-sink &lt;span class=&quot;nv&quot;&gt;$newDefaultSink&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Move all current playing streams to the new DEFAULT_SINK&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;stream&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Check whether there is a stream playing in the first place&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$stream&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;break
    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;streamId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stream&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{ print $1 }'&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    pactl move-sink-input &lt;span class=&quot;nv&quot;&gt;$streamId&lt;/span&gt; @DEFAULT_SINK@
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;pactl list short sink-inputs&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name></name></author><summary type="html">I recently switched to i3 after using GNOME for a few years. Unlike many window managers, i3 is very bare-bones and its default installation does not include functionality to manage audio through a graphical interface like you would in GNOME. I fixed the problem by modifying my i3 configuration instead of installing a graphical application such as gnome-control-center. Here is how I did it using PulseAudio.</summary></entry></feed>