<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Technology on Arash Sal Moslehian</title>
    <link>https://moslehian.com/categories/technology/</link>
    <description>Recent content in Technology on Arash Sal Moslehian</description>
    <image>
      <title>Arash Sal Moslehian</title>
      <url>https://moslehian.com/images/card.jpg</url>
      <link>https://moslehian.com/images/card.jpg</link>
    </image>
    <generator>Hugo -- 0.123.4</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 12 Aug 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://moslehian.com/categories/technology/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Reliable Desktop Linux Installation with Btrfs Snapshots, Snapper, and Rollbacks on Ubuntu (openSUSE style)</title>
      <link>https://moslehian.com/posts/2023/2-reliable-btrfs-snapshots-snapper-debian-ubuntu/</link>
      <pubDate>Sat, 12 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://moslehian.com/posts/2023/2-reliable-btrfs-snapshots-snapper-debian-ubuntu/</guid>
      <description>Creating a rock solid desktop Ubuntu (or Debian) system with btrfs, snapshots, snapper and rollbacks</description>
      <content:encoded><![CDATA[<p>We&rsquo;re gonna first install the system using the default btrfs setup for Ubuntu with only a few option changes.
After installing the system, we&rsquo;re going to create our custom subvolumes in a nested structure (unlike most other guides that use a flat layout). We are also going to let <code>/boot</code> be part of the snapshots and only put <code>/boot/efi</code> in its own partition. I am using Kubuntu as an example here, but you can easily change that to your own Ubuntu spin or even use Debian with minor tweaks.</p>
<p>Boot into the live environment of your installation medium.
Open a terminal and change the password of the root user to something easy using:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ sudo passwd root
</span></span></code></pre></td></tr></table>
</div>
</div><p>and then change the user to root using</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>$ su -p
</span></span></code></pre></td></tr></table>
</div>
</div><p>This helps us avoid using <code>sudo</code> at the beginning of each command. The rest of the guide assumes you&rsquo;re the root user.</p>
<h2 id="change-the-default-btrfs-partition-configuration">Change the default btrfs partition configuration</h2>
<p>First, we need to modify the configuration file for partman that the installer uses for partitioning the disks.</p>
<p>Open <code>/usr/lib/partman/mount.d/70btrfs</code> with a text editor and add the options <code>noatime,compress=zstd,space_cache=v2</code> alongside <code>subvol</code> as specified below:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#66d9ef">case</span> $type in
</span></span><span style="display:flex;"><span>    btrfs<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    options<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>options%,subvol=*<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    options<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>options%subvol=*<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    mount -t btrfs <span style="color:#e6db74">${</span>options:+-o <span style="color:#e6db74">&#34;</span>$options<span style="color:#e6db74">&#34;</span><span style="color:#e6db74">}</span> $fs /target$mp <span style="color:#f92672">||</span> exit <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> $mp in
</span></span><span style="display:flex;"><span>        /<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        btrfs subvolume create /target$mp/@
</span></span><span style="display:flex;"><span>        chmod <span style="color:#ae81ff">755</span> /target$mp/@
</span></span><span style="display:flex;"><span>        umount /target$mp
</span></span><span style="display:flex;"><span>        options<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>options:+$options,<span style="color:#e6db74">}</span><span style="color:#e6db74">subvol=@,noatime,compress=zstd,space_cache=v2&#34;</span> <span style="color:#75715e"># &lt;-- Change here</span>
</span></span><span style="display:flex;"><span>        mount -t btrfs -o $options $fs /target$mp
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>        /home<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        btrfs subvolume create /target$mp/@home
</span></span><span style="display:flex;"><span>        chmod <span style="color:#ae81ff">755</span> /target$mp/@home
</span></span><span style="display:flex;"><span>        umount /target$mp
</span></span><span style="display:flex;"><span>        options<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>options:+$options,<span style="color:#e6db74">}</span><span style="color:#e6db74">subvol=@home,noatime,compress=zstd,space_cache=v2&#34;</span> <span style="color:#75715e"># &lt;-- Change here</span>
</span></span><span style="display:flex;"><span>        mount -t btrfs -o $options $fs /target$mp
</span></span><span style="display:flex;"><span>        ;;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">esac</span>
</span></span><span style="display:flex;"><span>    echo <span style="color:#e6db74">&#34;umount /target</span>$mp<span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>    exit <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>    ;;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">esac</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Start the installer and proceed with the installation as you normally would.</p>
<h2 id="disk-partition">Disk partition</h2>
<ul>
<li>Create an EFI system partition with around 512 MB of space</li>
<li>Create another partition that spans the rest of the disk, format it with btrfs and set the mount point at <code>/</code>
<img loading="lazy" src="./assets/partition-scheme.jpg" alt="Partition Scheme"  />
</li>
</ul>
<p>Choose the partition that you created for EFI (EFI System Partition) to install the bootloader to and proceed with the installation to the end. DO NOT boot into the installed system just yet and stay in the live environment (do not restart).</p>
<h2 id="creating-the-necessary-subvolumes">Creating the necessary subvolumes</h2>
<p>We will be using the <a href="https://btrfs.readthedocs.io/en/latest/Subvolumes.html#nested-subvolumes"   target="_blank">nested subvolume</a> layout as described in the btrfs documentation.</p>
<p>Mount the btrfs partition that you installed your system on using the same options you used in the previous section to <code>/mnt</code>. For example:</p>
<pre tabindex="0"><code>root@kubuntu:~# mount /dev/vda2 -o noatime,compress=zstd,space_cache=v2 /mnt
</code></pre><p>You should see the following two directories under <code>/mnt</code>:</p>
<pre tabindex="0"><code>root@kubuntu:~# ls /mnt
@  @home
</code></pre><p>Go to <code>/mnt/@</code> and remove the following empty directories:</p>
<pre tabindex="0"><code>root@kubuntu:/mnt/@# rm -rf opt/ tmp/ srv/ home/
</code></pre><p>Rename the following directories and add <code>.bak</code> to the end of their names:</p>
<pre tabindex="0"><code>root@kubuntu:/mnt/@# mv root/ root.bak
root@kubuntu:/mnt/@# mv var/ var.bak
root@kubuntu:/mnt/@# mv boot/grub/x86_64-efi boot/grub/x86_64-efi.bak
</code></pre><p>Create an empty directory called <code>var</code></p>
<pre tabindex="0"><code>root@kubuntu:/mnt/@# mkdir -p var/lib
root@kubuntu:/mnt/@# mkdir -p root
</code></pre><p>Create the following subvolumes under <code>@</code>:</p>
<pre tabindex="0"><code>btrfs subvolume create /mnt/@/boot/grub/x86_64-efi
btrfs subvolume create /mnt/@/home
btrfs subvolume create /mnt/@/root
btrfs subvolume create /mnt/@/opt
btrfs subvolume create /mnt/@/srv
btrfs subvolume create /mnt/@/tmp
btrfs subvolume create /mnt/@/var/log
btrfs subvolume create /mnt/@/var/crash
btrfs subvolume create /mnt/@/var/cache
btrfs subvolume create /mnt/@/var/tmp
btrfs subvolume create /mnt/@/var/opt
btrfs subvolume create /mnt/@/var/spool
btrfs subvolume create /mnt/@/var/lib/flatpak
</code></pre><p>Go to <code>var</code> and change disable Copy-on-Write for the created directories:</p>
<pre tabindex="0"><code>root@kubuntu:/mnt/@/var# chattr +C cache/ crash/ tmp/ opt/ log/ spool/ lib/flatpak/
</code></pre><p>You can use <code>lsattr</code> to check and see if CoW has correctly been disabled.</p>
<p>Now move the contents of <code>@home</code>, <code>root.bak</code>, and <code>var.bak</code> to the new locations: (ignore any errors for root.bak, since it might be empty of non-hidden files)</p>
<pre tabindex="0"><code>mv /mnt/@home/{.,}* /mnt/@/home
mv /mnt/@/root.bak/{.,}* /mnt/@/root
mv /mnt/@/boot/grub/x86_64-efi.bak/* /mnt/@/boot/grub/x86_64-efi

cp -a --reflink=never /mnt/@/var.bak/crash/. /mnt/@/var/crash/
cp -a --reflink=never /mnt/@/var.bak/cache/. /mnt/@/var/cache/
cp -a --reflink=never /mnt/@/var.bak/log/.   /mnt/@/var/log/
cp -a --reflink=never /mnt/@/var.bak/spool/. /mnt/@/var/spool/
cp -a --reflink=never /mnt/@/var.bak/tmp/.   /mnt/@/var/tmp/
cp -a --reflink=never /mnt/@/var.bak/opt/.   /mnt/@/var/opt/
</code></pre><p>Go to <code>var.bak</code> and remove the copied directories:</p>
<pre tabindex="0"><code>root@kubuntu:/mnt/@/var.bak# rm -rf crash/ cache/ tmp/ opt/ log/ spool/
</code></pre><p>Copy the rest of <code>var.bak</code> to <code>var</code></p>
<pre tabindex="0"><code>cp -a /mnt/@/var.bak/. /mnt/@/var
</code></pre><p>remove the following directories:</p>
<pre tabindex="0"><code>rm -rf /mnt/@/root.bak /mnt/@/var.bak /mnt/@/boot/grub/x86_64-efi.bak/
</code></pre><p>and remove the <code>@home</code> subvolume:</p>
<pre tabindex="0"><code>btrfs subvolume delete /mnt/@home/
</code></pre><p>The final subvolume layout should look like this:</p>
<pre tabindex="0"><code>root@kubuntu:~# sudo btrfs subvolume list -apt /mnt
ID	gen	parent	top level	path	
--	---	------	---------	----	
256	81	5	5		@
258	65	256	256		&lt;FS_TREE&gt;/@/home
259	69	256	256		&lt;FS_TREE&gt;/@/root
260	54	256	256		&lt;FS_TREE&gt;/@/opt
261	55	256	256		&lt;FS_TREE&gt;/@/srv
262	56	256	256		&lt;FS_TREE&gt;/@/tmp
269	64	256	256		&lt;FS_TREE&gt;/@/var/lib/flatpak
270	78	256	256		&lt;FS_TREE&gt;/@/var/log
271	77	256	256		&lt;FS_TREE&gt;/@/var/crash
272	78	256	256		&lt;FS_TREE&gt;/@/var/cache
273	77	256	256		&lt;FS_TREE&gt;/@/var/tmp
274	77	256	256		&lt;FS_TREE&gt;/@/var/opt
275	77	256	256		&lt;FS_TREE&gt;/@/var/spool
276	84	256	256		&lt;FS_TREE&gt;/@/boot/grub/x86_64-efi
</code></pre><p>Edit the fstab file at <code>/mnt/@/etc/fstab</code> and add the following entries (change the UUID accordingly)</p>
<pre tabindex="0"><code>UUID=1A5D-5465                             /boot/efi              vfat     umask=0077                                                                   0       1
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /                      btrfs    defaults,noatime,compress=zstd,space_cache=v2                                0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /home                  btrfs    defaults,subvol=@/home,noatime,compress=zstd,space_cache=v2                  0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /root                  btrfs    defaults,subvol=@/root,noatime,compress=zstd,space_cache=v2                  0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /opt                   btrfs    defaults,subvol=@/opt,noatime,compress=zstd,space_cache=v2                   0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /srv                   btrfs    defaults,subvol=@/srv,noatime,compress=zstd,space_cache=v2                   0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /tmp                   btrfs    defaults,subvol=@/tmp,noatime,compress=zstd,space_cache=v2                   0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/lib/flatpak       btrfs    defaults,subvol=@/var/lib/flatpak,noatime,compress=zstd,space_cache=v2       0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/log               btrfs    defaults,subvol=@/var/log,noatime,compress=zstd,space_cache=v2               0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/crash             btrfs    defaults,subvol=@/var/crash,noatime,compress=zstd,space_cache=v2             0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/cache             btrfs    defaults,subvol=@/var/cache,noatime,compress=zstd,space_cache=v2             0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/tmp               btrfs    defaults,subvol=@/var/tmp,noatime,compress=zstd,space_cache=v2               0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/opt               btrfs    defaults,subvol=@/var/opt,noatime,compress=zstd,space_cache=v2               0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /var/spool             btrfs    defaults,subvol=@/var/spool,noatime,compress=zstd,space_cache=v2             0       0
UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /boot/grub/x86_64-efi  btrfs    defaults,subvol=@/boot/grub/x86_64-efi,noatime,compress=zstd,space_cache=v2  0       0
</code></pre><p>Set the default subvolume for your btrfs file system to <code>@</code></p>
<pre tabindex="0"><code>btrfs subvolume set-default /mnt/@
</code></pre><h2 id="disable-updatedb-indexing-for-snapshots">Disable updatedb indexing for snapshots</h2>
<p>To disable the indexing of snapshots, simply edit the file <code>/mnt/@/etc/updatedb.conf</code> and add <code>.snapshots</code> to the list of <code>PRUNENAMES</code> (you may need to uncomment it first)</p>
<pre tabindex="0"><code>PRUNENAMES=&#34;.snapshots&#34;
</code></pre><p>Restart the system and boot into your new installation.</p>
<h2 id="install-the-necessary-packages">Install the necessary packages</h2>
<p>First install <code>snapper</code> and <code>snapper-gui</code> using apt.</p>
<pre tabindex="0"><code>sudo apt install snapper snapper-gui
</code></pre><p>Then install <a href="https://github.com/Antynea/grub-btrfs"   target="_blank"><code>grub-btrfs</code></a> from source; the instructions are available in the README of its repository. Make sure you install the required dependencies such as inotify-tools beforehand. (at the time of writing it is not yet available in the repos)</p>
<h2 id="create-snapper-config">Create snapper config</h2>
<p>Run the following command to create a configuration named <code>root</code> for the all the files under our root directory (only stopping at subvolume boundaries)</p>
<pre tabindex="0"><code>sudo snapper -c root create-config /
</code></pre><p>This should create a new subvolume named <code>.snapshots</code> nested under subvolume <code>@</code> along with its corresponding directory at <code>/.snapshots</code>. Run the following command to see it:</p>
<pre tabindex="0"><code>root@kubuntu:~$ btrfs subvolume list -apt /
ID      gen     parent  top level       path
--      ---     ------  ---------       ----
256     231     5       5               &lt;FS_TREE&gt;/@
258     231     256     256             @/home
259     128     256     256             @/root
260     54      256     256             @/opt
261     55      256     256             @/srv
262     230     256     256             @/tmp
269     64      256     256             @/var/lib/flatpak
270     231     256     256             @/var/log
271     213     256     256             @/var/crash
272     231     256     256             @/var/cache
273     214     256     256             @/var/tmp
274     77      256     256             @/var/opt
275     224     256     256             @/var/spool
276     84      256     256             @/boot/grub/x86_64-efi
277     231     256     256             @/.snapshots
</code></pre><p>A new configuration file at <code>/etc/snapper/configs/root</code> is also created. Please refer to the <a href="http://snapper.io/manpages/snapper-configs.html"   target="_blank">snapper documentation</a> and change the options to your liking. Make sure you add your username to <code>ALLOW_USERS</code>. I personally reduce the number of timeline snapshots to once a week or turn them off entirely. I also reduce the <code>NUMBER_LIMIT</code> to 10.</p>
<p>Edit <code>/etc/fstab</code> and add a mount point for <code>.snapshots</code> just like the other subvolumes.</p>
<pre tabindex="0"><code>UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f  /.snapshots  btrfs  defaults,subvol=@/.snapshots,noatime,compress=zstd,space_cache=v2  0  0
</code></pre><h2 id="enable-systemd-timers-and-services">Enable systemd timers and services</h2>
<p>Enable this timer to allow snapper to take time-based snapshots based on the configuration you provided.</p>
<pre tabindex="0"><code>sudo systemctl enable --now snapper-timeline.timer
</code></pre><p>Enable this timer to allow snapper to take clean up its snapshots.</p>
<pre tabindex="0"><code>sudo systemctl enable --now snapper-cleanup.timer
</code></pre><p>Enable the grub-btrfs service.</p>
<pre tabindex="0"><code>sudo systemctl enable --now grub-btrfsd.service
</code></pre><p>By default, snapper creates a new snapshot on every boot. You can disable this behaviour using the following command.</p>
<pre tabindex="0"><code> sudo systemctl disable --now snapper-boot.timer
</code></pre><p>Reboot the system.</p>
<h2 id="10_linux-grub-configuration-file"><code>10_linux</code> grub configuration file</h2>
<p>Open <code>/etc/grub.d/10_linux</code> with a text editor and navigate to the following segment:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#66d9ef">case</span> x<span style="color:#e6db74">&#34;</span>$GRUB_FS<span style="color:#e6db74">&#34;</span> in
</span></span><span style="display:flex;"><span>    xbtrfs<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>        rootsubvol<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;`make_system_path_relative_to_its_root /`&#34;</span>
</span></span><span style="display:flex;"><span>        rootsubvol<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>rootsubvol#/<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;x</span><span style="color:#e6db74">${</span>rootsubvol<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> !<span style="color:#f92672">=</span> x <span style="color:#f92672">]</span>; <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>            GRUB_CMDLINE_LINUX<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;rootflags=subvol=</span><span style="color:#e6db74">${</span>rootsubvol<span style="color:#e6db74">}</span><span style="color:#e6db74"> </span><span style="color:#e6db74">${</span>GRUB_CMDLINE_LINUX<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">fi</span>;;
</span></span></code></pre></td></tr></table>
</div>
</div><p>remove <code>rootflags=subvol=${rootsubvol}</code> from the <code>GRUB_CMDLINE_LINUX</code> string:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>GRUB_CMDLINE_LINUX<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>GRUB_CMDLINE_LINUX<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Do the same thing for <code>/etc/grub.d/20_linux_xen</code> and update grub using:</p>
<pre tabindex="0"><code>sudo update-grub
</code></pre><p>This allows grub to look for kernel and root directory in the correct location after each rollback.</p>
<h2 id="test-out-booting-from-a-snapshot">Test out booting from a snapshot</h2>
<p>Let&rsquo;s install a simple package like <code>hello</code>.</p>
<pre tabindex="0"><code>sudo apt install hello
</code></pre><p>Now let&rsquo;s see the snapshots that snapper has created for this action:</p>
<pre tabindex="0"><code>kubuntu@kubuntu:~$ snapper list
 # | Type   | Pre # | Date                              | User | Cleanup | Description | Userdata
---+--------+-------+-----------------------------------+------+---------+-------------+---------
0  | single |       |                                   | root |         | current     |
1  | pre    |       |                                   | root | number  | apt         |
2  | post   |     1 |                                   | root | number  | apt         |
</code></pre><p>There are two snapshots. One is taken before the action is performed (pre) and one is taken after it (post).</p>
<p>Now reboot. In the boot menu you should see <code>Ubuntu Snapshots</code> as an option. Choose it and select the <code>pre</code> apt snapshot and select a kernel after that. After booting into this read-only system you can see that you don&rsquo;t have the <code>hello</code> binary anymore and that <code>apt</code> has no record of installing it.</p>
<p><img loading="lazy" src="./assets/grub-main.jpg" alt="grub main"  />

<img loading="lazy" src="./assets/grub-choose.jpg" alt="grub snapshot"  />
</p>
<pre tabindex="0"><code>arash@kubuntu:~$ hello
Command &#39;hello&#39; not found, but can be installed with:
sudo apt install hello              # version 2.10-3, or
sudo apt install hello-traditional  # version 2.10-6
</code></pre><p>and</p>
<pre tabindex="0"><code>arash@kubuntu:~$ sudo apt list --installed | grep hello
</code></pre><p>returns no result. Issuing <code>snapper list</code> tells you which snapshot you are currently booted into using a <code>-</code> next to the snapshot number.</p>
<p>Please note that this is a read-only snapshot, and you cannot change the contents of the snapshot (for example trying to install anything with apt would fail). You can however change the contents of other subvolumes such as home. This is why we chose to put the contents of some subdirectories of <code>/var</code> such as <code>/var/log</code> under separate subvolumes so that the system would be able to boot.</p>
<p>Reboot into the default entry of grub (your original system).</p>
<h2 id="rollbacks">Rollbacks</h2>
<p>In case the system gets broken, we want to be able to boot into a working read-only snapshot, issue a rollback command, and reboot into a normal writable snapshot by default.
OpenSUSE achieves this by <a href="https://build.opensuse.org/package/show/openSUSE%3AFactory/grub2"   target="_blank">patching the grub2</a> source code and adding extra functionalities that allow grub to boot into rollback snapshots directly and by default. (search for btrfs in source files and you will see the patches)</p>
<h3 id="btrfs-default-subvolume">BTRFS default subvolume</h3>
<p>From the <a href="https://btrfs.readthedocs.io/en/latest/btrfs-subvolume.html"   target="_blank">btrfs docs</a>:</p>
<p><em>A freshly created filesystem is also a subvolume, called top-level, internally has an id 5. This subvolume cannot be removed or replaced by another subvolume. This is also the subvolume that will be mounted by default, unless the default subvolume has been changed (see btrfs subvolume set-default).</em></p>
<p>This means that when we changed the default subvolume to <code>@</code> in the previous sections and did not specify <code>subvol=</code> in the mount options of <code>/</code> in our fstab file, the default subvolume of the btrfs system would be mounted at <code>/</code> (in our case <code>@</code>). Snapper uses this functionality to roll back to a snapshot. It changes the default subvolume of the btrfs filesystem to the snapshot we want to roll back into and the OS using the fstab file that we provided mounts that default subvolume unto <code>/</code>.</p>
<h3 id="early-grub-configuration-file">Early grub configuration file</h3>
<p>Normally, when your system is turned on, the EFI firmware calls the grub bootloader, grub reads the initial <code>grub.cfg</code> configuration file that is stored at <code>/boot/efi/EFI/ubuntu/grub.cfg</code> and that configuration file calls into the main <code>grub.cfg</code> stored in <code>/boot/grub/grub.cfg</code> that is generated by <code>update-grub</code> and in turn by <code>grub-mkconfig</code>.</p>
<p>Let&rsquo;s compare the file early grub configuration file that Ubuntu uses to that of OpenSUSE with their patched grub2 package.
Ubuntu&rsquo;s configuration <code>arash@kubuntu:~# cat /boot/efi/EFI/ubuntu/grub.cfg</code>:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#a6e22e">search.fs_uuid 84cc93cb-d382-45f8-a0f0-79a0316ba88f root</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">set prefix</span><span style="color:#f92672">=</span><span style="color:#e6db74">($root)&#39;/@/boot/grub&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">configfile $prefix/grub.cfg</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>OpenSUSE&rsquo;s configuration <code>arash@opensuse ~# cat /boot/efi/EFI/opensuse/grub.cfg</code>:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#a6e22e">set btrfs_relative_path</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;yes&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">search --fs-uuid --set</span><span style="color:#f92672">=</span><span style="color:#e6db74">root 512bb31b-c5a9-468b-a549-22ad3b4e99fb</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">set prefix</span><span style="color:#f92672">=</span><span style="color:#e6db74">(${root})/boot/grub2</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">source &#34;${prefix}/grub.cfg&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>as you can see the grub2 package of OpenSUSE supports the <code>btrfs_relative_path</code> option. This allows grub to choose the <code>/boot/grub/grub.cfg</code> file that resides in the <strong>default</strong> subvolume of the btrfs filesystem (in our case the snapshot that we have rolled back into). Ubuntu on the other hand, has a static path for <code>/boot/grub/grub.cfg</code> under the <code>@</code> subvolume.</p>
<p>To fix this issue, we install a plugin for snapper that changes line 2 in <code>/boot/efi/EFI/ubuntu/grub.cfg</code> to the snapshot that we want to roll back into, for example:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#a6e22e">set prefix</span><span style="color:#f92672">=</span><span style="color:#e6db74">($root)&#39;/@/.snapshots/5/snapshot/boot/grub&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="snapper-efi-plugin">Snapper EFI plugin</h3>
<p>To achieve the behaviour described in the previous section, create a file named <code>99_efi</code> in <code>/usr/lib/snapper/plugins</code> and add the following script into it and make it executable using <code>chmod +x 99_efi</code>.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#75715e">#!/bin/sh
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>set -e
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>distro<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>awk -F <span style="color:#e6db74">&#34;=&#34;</span> <span style="color:#e6db74">&#39;/^NAME=/ {gsub(/&#34;/, &#34;&#34;, $2); print tolower($2)}&#39;</span> /etc/os-release<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">case</span> $1 in
</span></span><span style="display:flex;"><span>        rollback*<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>                sed -i <span style="color:#e6db74">&#34;s/^set prefix=(\$root).*/set prefix=(\$root)\&#39;\/@\/\.snapshots\/</span>$5<span style="color:#e6db74">\/snapshot\/boot\/grub\&#39;/&#34;</span> /boot/efi/EFI/$distro/grub.cfg
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">esac</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Every time snapper performs an action it calls all the plugins it has with the name of the action as its argument. This script changes the entry in <code>/boot/efi/EFI/ubuntu/grub.cfg</code> so that it points to the location of the new default snapshot that snapper rollback has set.</p>
<h3 id="perform-the-first-rollback">Perform the first rollback</h3>
<p>Using <code>snapper list</code> and <code>snapper remove &lt;list of snapshot numbers&gt;</code> delete all the previous snapshots.
Install <code>cowsay</code> using apt, reboot the system and boot into the <code>pre</code> snapshot (where <code>cowsay</code> is not installed).</p>
<p>Perform the very first rollback using:</p>
<pre tabindex="0"><code>arash@kubuntu:~$ sudo snapper --ambit classic rollback
Ambit is classic.
Creating read-only snapshot of default subvolume. (Snapshot 3).
Creating read-write snapshot of current subvolume. (Snapshot 4).
Setting default subvolume to snapshot 4.
</code></pre><p>The contents of <code>/boot/efi/EFI/ubuntu/grub.cfg</code> should also indicate that grub will use the configuration file in snapshot 4.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cfg" data-lang="cfg"><span style="display:flex;"><span><span style="color:#a6e22e">...</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">set prefix</span><span style="color:#f92672">=</span><span style="color:#e6db74">($root)&#39;/@/.snapshots/4/snapshot/boot/grub&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">...</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Now reboot the system. The default grub entry should boot you into snapshot 4. You can confirm this using the following commands:</p>
<ul>
<li>First make sure that <code>cowsay</code> is indeed not available anymore in this system.</li>
<li>Run <code>sudo btrfs snapshot show /</code> and confirm that the subvolume mounted at <code>/</code> is the snapshot we rolled back into.</li>
</ul>
<p>Please note that <code>--ambit classic</code> is only needed on the first ever rollback. After that you can roll back using:</p>
<pre tabindex="0"><code>sudo snapper rollback
</code></pre><h3 id="update-grub-after-each-rollback"><code>update-grub</code> after each rollback</h3>
<p>In your new rolled back system, check the contents of <code>/boot/grub/grub.cfg</code>. You can see that grub still invokes the kernel from the previous default subvolume of the btrfs filesystem</p>
<pre tabindex="0"><code>...
linux   /@/boot/vmlinuz-6.2.0-27-generic root=UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f ro  quiet splash $vt_handoff
initrd  /@/boot/initrd.img-6.2.0-27-generic
...
</code></pre><p>To fix this, <em>after you boot into your rolled back system for the first time, you must update grub</em> using</p>
<pre tabindex="0"><code>sudo update-grub
</code></pre><p>This makes sure that the default entry in grub points to the kernel inside the rolled back snapshot instead of the kernel in previous system. Now <code>/boot/grub/grub.cfg</code> points to the correct kernel:</p>
<pre tabindex="0"><code>linux   /@/.snapshots/4/snapshot/boot/vmlinuz-6.2.0-27-generic root=UUID=84cc93cb-d382-45f8-a0f0-79a0316ba88f ro  quiet splash $vt_handoff
initrd  /@/.snapshots/4/snapshot/boot/initrd.img-6.2.0-27-generic
</code></pre><h2 id="delete-the-contents-of-the-original-root-subvolume-">Delete the contents of the original root subvolume <code>@</code></h2>
<p>Since from now on you will always boot into a snapshot subvolume, you won&rsquo;t be needing the contents of <code>@</code>.
First mount it at <code>/mnt</code>:</p>
<pre tabindex="0"><code>sudo mount /dev/vda2 /mnt -o subvol=@
</code></pre><p>and then delete all the files (make sure you only delete the files inside <code>@</code> and not the files of other subvolumes nested inside <code>@</code>).</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>rm -rf /mnt/<span style="color:#f92672">{</span>usr,etc,lib,lib32,lib64,libx32,bin,sbin,cdrom,media,mnt<span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>ls -d /mnt/var/lib/* | grep -v <span style="color:#e6db74">&#34;flatpak&#34;</span> | xargs rm -r
</span></span><span style="display:flex;"><span>ls -d /mnt/boot/* | grep -v <span style="color:#e6db74">&#39;boot/\(efi\|grub\)&#39;</span> | xargs rm -r
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="conclusion">Conclusion</h2>
<p>You can now enjoy your rock solid system. If you happen to mess up system configuration or an update bricks your system, you can easily boot into a working snapshot and issue a rollback command from there. I find this method a suitable alternative for immutable distros for people who may not want to fully commit to them.</p>
<p>Snapper also includes a lot of other features such as undoing changes and seeing the difference between snapshots. You can check out the <a href="http://snapper.io/manpages/snapper.html"   target="_blank">documentation of snapper</a> for more info.</p>
<h2 id="resources">Resources</h2>
<p>The following resource helped with the creation of this guide:</p>
<ul>
<li><a href="https://www.ordinatechnic.com/distribution-specific-guides/Arch/an-arch-linux-installation-on-a-btrfs-filesystem-with-snapper-for-system-snapshots-and-rollbacks"   target="_blank">An Arch Linux Installation on a Btrfs Filesystem with Snapper for System Snapshots and Rollbacks</a></li>
<li><a href="https://sysguides.com/install-fedora-38-with-snapshot-and-rollback-support/"   target="_blank">How to Install Fedora 38 with Snapshot and Rollback Support</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Artificial General Intelligence:  What machine learning left behind from neuroscience - in Persian</title>
      <link>https://moslehian.com/presentations/2023/agi-neuroscience-ml/</link>
      <pubDate>Mon, 19 Jun 2023 00:00:00 +0000</pubDate>
      <guid>https://moslehian.com/presentations/2023/agi-neuroscience-ml/</guid>
      <description>I recently gave a presentation about AGI at the 2nd Symposium on Artificial Intelligence for Good, AI Applications, Ferdowsi University of Mashhad, Spring 2023.
I start with a quick history of AI and how after decades from its inception, the initial goal of building a system with human capabilities has slowly transitioned towards applied AI platforms that the market demands. An overview of the differences between biological neurons and those used in today&amp;rsquo;s machine learning algorithms is then presented.</description>
      <content:encoded><![CDATA[<p>I recently gave a presentation about AGI at the <a href="www.eesc-fum.ir/event-2nd-symposium"  >2nd Symposium on Artificial Intelligence for Good, AI Applications, Ferdowsi University of Mashhad, Spring 2023</a>.</p>
<p>I start with a quick history of AI and how after decades from its inception, the initial goal of building a system with human capabilities has slowly transitioned towards applied AI platforms that the market demands.
An overview of the differences between biological neurons and those used in today&rsquo;s machine learning algorithms is then presented. After that, I go over what consciousness is and how it is related to feelings, homeostasis, self-organizing systems, the Markov blanket, and the free energy principle. I then go over the possibility of building a conscious AI using these physical models.
In the last part, I talk about how organismic agents differ from AI agents. I explain what affordances are and how organisms can achieve their goals through jury-rigging.  I end the talk with a discussion of whether true AGI is even possible in the current algorithmic frame of development and explain what this may entail regarding simulating evolution and various deep learning models.</p>
<p>Link to the Video In Persian: <a href="https://youtu.be/YkxiCrku3ck"   target="_blank">YouTube</a></p>
<p>Slides available <a href="./assets/agi-neuroscience-ml.pdf"  >here</a></p>
<p>Thumbnail background from: Patheon (TV series)</p>
]]></content:encoded>
    </item>
    <item>
      <title>An Introduction to Asynchronous Programming in Rust and a High-level Overview of Tokio&#39;s Architecture</title>
      <link>https://moslehian.com/posts/2023/1-intro-async-rust-tokio/</link>
      <pubDate>Wed, 25 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://moslehian.com/posts/2023/1-intro-async-rust-tokio/</guid>
      <description>Asynchronous programming allows the development of services that can handle millions of requests without saturating memory and CPU utilization. Support for asynchrony is usually baked into the programming language; we take a look at async support in Rust, a type-safe and memory-safe systems programming language that guarantees safety at compile time using rules that eliminate many issues prevalent in traditional languages. We take a peek at the inner workings of Tokio, an asynchronous runtime for Rust that provides scheduling, networking, and many other primitive operations for managing asynchronous tasks.</description>
      <content:encoded><![CDATA[<blockquote>
<p>Asynchronous programming allows the development of services that can handle millions of requests without saturating memory and CPU utilization. Support for asynchrony is usually baked into the programming language; we take a look at async support in Rust, a type-safe and memory-safe systems programming language that guarantees safety at compile time using rules that eliminate many issues prevalent in traditional languages. We take a peek at the inner workings of Tokio, an asynchronous runtime for Rust that provides scheduling, networking, and many other primitive operations for managing asynchronous tasks. Runtime libraries rely on the operating system for registering and dispatching asynchronous events. We compare the different asynchronous APIs that Linux provides and conclude why the new io_uring interface is the best approach. This article was originally written in 2022-09.</p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>The need for asynchronous programming grew when traditional multithreaded programs failed to meet the demands of handling a huge number of requests without upgrading the hardware. Traditional threads provide their own call stack and are periodically placed on a core as part of a context switch by the operating system, to advance their execution. Because of these memory requirements, spawning a thread for handling every request becomes infeasible in terms of memory usage when the number of requests grows. Supporting asynchronous programming on a language level needs constructs built into the language as well as a runtime library for managing asynchronous green threads (tasks) and scheduling them on CPU cores. This runtime is also responsible for interfacing with the operating system and dispatching resources associated with each event that the OS emits.</p>
<p>Rust is a programming language that first had its 1.0 release back in 2014. This systems programming language promises safety and efficiency for programs that serve all kinds of functionality e.g. web servers, operating systems, GUI and CLI programs, machine learning models, game engines and etc. Rust enforces some rules at compile time that allow the programmer to write memory and type-safe code without the need for excessive testing. Even with testing, traditional programming languages like C/C++ still fail to create memory-safe programs, even if these programs were written by the best programmers in the world. Some examples of memory issues that lead to dangerous vulnerabilities in software include buffer and stack overflows, use-after-free,  out-of-bounds indexing, double freeing and etc. Rust tries to solve all these problems at compile time while providing a modern and standard syntax for programmers.</p>
<p>Asynchronous support is built into the Rust language. Rust uses the concept of Futures (a value that might be available in the future) and state machines to create resumable green threads that use a cooperative strategy to run themselves to completion. There can be other futures inside a future leading to the creation of a tree-like structure where the futures at the root, called a task, are directly managed by the runtime, and as the runtime polls the task for advancement, the task then polls its inner futures to completion. There leaf futures of this tree are futures that communicate with the I/O driver and the operating system. They register resources with the OS and wait for the OS to emit events, stating the status of those resources.</p>
<p>Tokio is an asynchronous runtime for the Rust programming language. It provides a scheduler, an I/O and time driver, and other functionalities like networking, inter-task communications, and synchronization primitives. Tokio provides a multithreaded scheduler that creates multiple workers on different threads. These workers each have a run queue that tasks reside in; they then pop tasks from their run queue and try to advance them to completion. The I/O driver uses an abstraction over different operating systems for registering events. It then waits for events to come from the OS and iterates through all of them, dispatching tasks that were blocked on the resource associated with each event.</p>
<p>Linux provides different system calls for working with asynchronous operations, these system calls tell the called about the readiness of file descriptors it was given. The problem with these system calls is that they don&rsquo;t work as expected for file operations and always return a read status for file descriptors backed by regular files. For this reason, io_uring was introduced back in 2019 in the Linux kernel. It provides a uniform asynchronous interface at programs can use to manage all their asynchronous operations.</p>
<h2 id="the-rust-programming-language">The Rust Programming Language</h2>
<p>Rust is a new programming language made to create safe and efficient systems by modern standards. The thing that makes rust safe is a set of rules that rust enforces on the programmer during the compilation time. These rules are designed to catch memory bugs and race conditions in multi-threaded programs. Rust does all these while still being as efficient as the C programming language. A huge portion of software vulnerabilities is because of memory safety violations, things such as buffer overflow, use after free, and index out-of-bounds. There have been many attempts at trying to reduce these memory violations by statically checking C/C++ code but were mostly in vain. Today more than 70% of software vulnerabilities are because of memory safety issues <a href="#most_vulnerabilities"  >[2]</a>. For this reason, companies like Google and Mozilla started to come up with languages such as Go and Rust respectively. These new languages aim to be as efficient as C/C++ but without all their memory issues. Rust is different from Go in terms of how they manage their memory; Go is garbage collected whereas Rust lacks one and most values are simply dropped at the end of the scope.</p>
<p>Rust has become the most loved language every year since 2016 in Stackoverflow surveys <a href="#stackoverflow_survey_2021"  >[16]</a> and has seen a significant adaptation among companies and individual developers. For example, in the embedded area companies like STMicrocontrollers and Espressif Systems introduced their community projects for enabling the use of the Rust programming language on their SoCs and modules.</p>
<p>The Rust programming language was first conceived back in 2009 in Mozilla and had its 1.0 release in 2014. Rust achieves its safety using two new concepts: ownership and lifetimes which we will be talking about shortly. The main drawback of using Rust is its steep learning curve. Like languages such as Haskell or Prolog, Rust introduces new concepts and new semantics that have a striking difference from what most system programmers are accustomed to. When starting to learn Rust, most of the time will be spent clashing with the compiler and trying to get the code to run.</p>
<h3 id="overview">Overview</h3>
<p>Rust inherits from both object-oriented and functional paradigms. It supports generics, enums, pattern matching, and modules and has support for polymorphism using traits; traits are like interfaces in Java and allow types that implement them to be used as an instance of that trait or perform constraints on other types. Variables are by default immutable and can only be mutated if explicitly marked with the <code>mut</code> keyword.</p>
<p>One of the most loved features of Rust is its easy-to-use build system and package manager called Cargo. Cargo can download packages, resolve dependencies, build projects for different targets and so much more. Rust has a packages registry with more than 50,000 packages (or crates as we call them in Rust).</p>
<h3 id="ownership">Ownership</h3>
<p>For Rust to not use a garbage collector it needs to know when it is ok to free values; it does this using the concept of ownership. Ownership has three rules which are enforced by the compiler:</p>
<ul>
<li>Values in Rust only have one owner.</li>
<li>There can only be one owner at a time for a value.</li>
<li>When the owner goes out of scope the value is dropped.
In <a href="#lst1-ownership"  >listing 1</a> we can see an example. At line \( 11 \) a new scope is started using a curly bracket; this scope ends at line \( 15 \) with a closing bracket. At line \( 12 \) a new variable called \(x\) is created and assigned a value of \( 22 \). After its scope is ended at line \( 15 \) the \( x \) is dropped. If we try to use the value of \( x \) at line \( 17 \) we hit a compile error.</li>
</ul>
<div class="highlight" id="lst1-ownership"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">total</span>(numbers Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">i32</span><span style="color:#f92672">&gt;</span>) -&gt; <span style="color:#66d9ef">i32</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> sum <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#75715e">// create a mutable variable
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> num <span style="color:#66d9ef">in</span> numbers {
</span></span><span style="display:flex;"><span>        sum <span style="color:#f92672">=</span> sum <span style="color:#f92672">+</span> num
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    sum
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> x <span style="color:#f92672">=</span> <span style="color:#ae81ff">22</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        println!(<span style="color:#e6db74">&#34;x: </span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#34;</span>, x);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// println!(&#34;x: {}&#34;, x); //! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> a <span style="color:#f92672">=</span> vec![<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">3</span>]; <span style="color:#75715e">// a heap allocated array
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">let</span> b <span style="color:#f92672">=</span> a;             <span style="color:#75715e">// move ownership of array from &#39;a&#39; to &#39;b&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    println!(<span style="color:#e6db74">&#34;b: </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, b); <span style="color:#75715e">// This is correct
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#75715e">// println!(&#34;a: {:?}&#34;, a); //! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> t <span style="color:#f92672">=</span> total(b); <span style="color:#75715e">// b is moved
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// println!(&#34;numbers {}&#34;, b); //! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 1: Ownership</em></p>
<p>At line \( 19 \) a heap-allocated array (a vector) is created and is assigned to an immutable variable called \( a \). The ownership of the vector is then passed from \( a \) to another variable called \( b \). After this assignment, we cannot use \( a \) anymore and the print statement at line \( 23 \) would fail at compile time.</p>
<p>\( b \) is then passed to a function that takes a vector as its single argument. In this case, the ownership of our vector is passed into the function and is given to the variable \( numbers \). At the end of the function, the vector is freed because its owner which is \( number \) goes out of scope. Thus, using \( b \) at line \( 27 \) is a compile error. <a href="#rustbook"  >[17]</a>(Chapter~4.1)</p>
<h3 id="borrowing">Borrowing</h3>
<p>If you wanted to use a variable without taking its ownership, Rust provides a concept called Borrowing. Borrows are in a sense references or statically checked pointers that allow the use of a non-owned variable as long as only one of the following conditions hold:</p>
<ul>
<li>There is only one mutable reference to a variable</li>
<li>There are any number of immutable references to a variable
In <a href="#lst2-borrowing"  >listing 2</a> a vector is created and is assigned to a variable called \( nums \). At lines \( 4 \) and \( 5 \) two immutable references are created. At line \( 6 \) pushing a new value into \( nums \) fails because using an associated function such as <code>push</code> takes a mutable reference to that variable and thus this violates the borrowing conditions: There cannot be a mutable reference to a variable along with other immutable references. The statement in line \( 7 \) also fails for the same reason. At line \( 11 \) after the references are out of scope, we are allowed to take mutable references to variables.</li>
</ul>
<div class="highlight" id="lst2-borrowing"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> nums <span style="color:#f92672">=</span> vec![<span style="color:#ae81ff">1</span>, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">3</span>];
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> nums1 <span style="color:#f92672">=</span> <span style="color:#f92672">&amp;</span>nums; <span style="color:#75715e">// first reference
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">let</span> nums2 <span style="color:#f92672">=</span> <span style="color:#f92672">&amp;</span>nums; <span style="color:#75715e">// second reference
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// nums.push(4); // ! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// let mut nums3 = &amp;mut nums; // ! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// nums3.push(4); // ! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        println!(<span style="color:#e6db74">&#34;ref1: </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">, ref2: </span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, nums1, nums2);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    nums.push(<span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> nums4 <span style="color:#f92672">=</span> <span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> nums;
</span></span><span style="display:flex;"><span>    nums4.push(<span style="color:#ae81ff">6</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// nums.push(7); ! compile error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    println!(<span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{:?}</span><span style="color:#e6db74">&#34;</span>, nums4);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 2: Borrowing</em></p>
<p>At line \( 13 \) a new mutable reference is created. Since there can only be one mutable reference to a variable at a time (same as above <code>push</code> takes a mutable reference from the associated variable). An important observation is that if we removed the statement at line \( 17 \) then the push operation at line \( 15 \) wouldn&rsquo;t fail; this is because the rust compiler is smart enough to notice that the mutable reference \( num4 \) is not used anymore after the push operation and is immediately freed after the push.</p>
<p>These rules are enforced by the Rust compiler and prevent memory-safety issues described before such as freeing more than once, use after free, and data races. These rules, however, hinder programmers from easily creating data structures such as linked lists or interface with hardware and are forced to use unsafe blocks. In these blocks, Rust ownership and borrowing rules don&rsquo;t apply.<a href="#rustbook"  >[17]</a>(Chapter~4.2)</p>
<h3 id="lifetimes">Lifetimes</h3>
<p>Rust avoids situations where a resource is used after it has been freed in other places using lifetimes. Lifetimes and lifetime annotations allow the compiler to understand the scope in which a variable is valid. The Rust compiler can infer the lifetime of variables in most cases and manual annotation is not needed. For example, the lifetime of \( nums2 \) and \( nums1 \) in <a href="#lst2-borrowing"  >listing 2</a> ends at line \( 10 \).</p>
<p>An example where manual lifetime annotations are needed is described in <a href="#lst3-lifetime"  >listing 3</a>. In this example, the \( smaller \) function takes two references and returns a reference. Without lifetimes annotations we can&rsquo;t make the compiler ensure that when the program runs it avoids cases where the reference that the function returns has been freed beforehand and thus is an invalid reference. Lifetime annotations are like types; sometimes you have to manually specify the type of a variable because the compiler cannot infer it. In our case, the lifetime annotations define the relationship between the inputs and the output that the programmer desires, and then the compiler can analyze it <a href="#rustbook"  >[17]</a>(Chapter~10.3).</p>
<p>The lifetime annotation \( `a \) tells the compiler that the return value should live as long as the smaller lifetime of the two input references.</p>
<div class="highlight" id="lst3-lifetime"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">smaller</span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">&#39;a</span><span style="color:#f92672">&gt;</span>(str1: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span>, str2: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span>) -&gt; <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#66d9ef">str</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> str1.bytes().len() <span style="color:#f92672">&lt;</span> str2.bytes().len() {
</span></span><span style="display:flex;"><span>        str1
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        str2
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> name1 <span style="color:#f92672">=</span> String::from(<span style="color:#e6db74">&#34;Arash&#34;</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> name2 <span style="color:#f92672">=</span> String::from(<span style="color:#e6db74">&#34;Kiarash&#34;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    println!(<span style="color:#e6db74">&#34;</span><span style="color:#e6db74">{}</span><span style="color:#e6db74">&#34;</span>, smaller(<span style="color:#f92672">&amp;</span>name1, <span style="color:#f92672">&amp;</span>name2));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 3: Lifetimes</em></p>
<h3 id="concurrency">Concurrency</h3>
<p>Rust does not provide a runtime library to manage and schedule threads but instead uses a one-to-one mapping model where all its threads are mapped to OS threads. Rust supports synchronization primitives such as mutex, conditional variable, atomic operations, barriers and etc. Rust uses lifetimes to decide whether a resource should be unlocked; if a resource that is behind a lock goes out of scope the lock is unlocked. One can send ownership of variables between threads through message passing mechanisms such as channels. It should be noted that Rust cannot stop the programmer from creating deadlocks using primitive synchronizations for example <a href="#rustbook"  >[17]</a>(Chapter 16.1).</p>
<h3 id="conclusion">Conclusion</h3>
<p>In this section, we introduced Rust, a relatively young systems programming language that provides comparable efficiency and safety guarantees missing from other languages such as C/C++. We outlined the reasons that lead to its creation at Mozilla and discussed the mechanisms and rules by which the Rust compiler can eliminate memory-safety and type-safety issues plaguing the traditional programming languages.</p>
<h2 id="asynchronous-programming">Asynchronous Programming</h2>
<p>In this chapter, I am going to discuss multitasking with which operating systems are able to run multiple tasks at the same time. We explore preemptive and cooperative multitasking and take a peek at how Rust achieves asynchrony.</p>
<h3 id="multitasking">Multitasking</h3>
<p>Outside of the embedded space and in mainstream servers or personal computers, being able to execute multiple tasks at the same time is a must. For example on a physical server or VM, multiple processes could be running at the same time: one for a mail server, the other for serving a webpage, another routing traffic through a virtual private network, etc.</p>
<p>In most cases, there are more tasks than there are CPU cores and thus for the operating system to be able to run all these tasks at the same time, it needs to schedule more than one task on a single core. In order to create a feeling that all these tasks are running at the same time, the OS periodically switches out running tasks for those that are waiting to have their time slice. This is concurrency, an illusion that tasks are running at the same time. Parallelism is when tasks are actually executing at the same time on different cores.</p>
<p>There are two main ways to achieve multitasking:</p>
<ul>
<li>The OS forcefully pauses the execution of a task and switches it with another waiting one.</li>
<li>The tasks themselves give up control of the CPU (yield) so that other tasks can execute.</li>
</ul>
<h3 id="preemptive-scheduling-and-multithreading">Preemptive Scheduling and Multithreading</h3>
<p>In preemptive scheduling, the operating system can decide when to switch out a task based on a hardware interrupt. This interrupt could be the result of a hardware timer timeout or other sources of interrupts. In <a href="#fig1-preemptive"  >figure 1</a> we can see that while the CPU is executing task \( A \) a hardware interrupt occurs and the operating system takes control of the CPU to execute the respecting interrupt handler and switch out task \( A \) with task \( B \) <a href="#osdev"  >[11]</a>.</p>
<figure><img src="./assets/img/asynchronous-multitasking-preemptive.jpg"
         alt="Figure 1: Preemptive Multitasking" id="fig1-preemptive"/><figcaption>
            <p>Figure 1: Preemptive Multitasking</p>
        </figcaption>
</figure>

<p>These tasks in most operating systems are called threads of execution and each have a separate call stack reserved by the operating system. For threads to be resumed later in time, the CPU needs to save the thread&rsquo;s state when it was preempted. This requires saving all the CPU registers at the point of preemption and restoring them when the thread resumes. These threads are multiplexed by the operating system and threads ready to be executed are given CPU cycles. If a thread blocks for some operation or its time slice has ended, the OS changes that thread for another ready thread.</p>
<p>Using threads to read from sockets or write to files are fine for a lot of applications. They have the advantage that their execution is controlled by the operating system and CPU time is shared fairly between them. Also in environments where tasks could be spawned from untrusted applications, it is important for the OS to be able to halt their execution. Their problem is that each thread needs its own call stack and thus, the more threads are spawned the higher the memory usage gets. When switching between threads, there is an overhead in saving the registers and restoring them again for the thread to continue. This back and forth between the thread on the operating system level is costly when applications need high performance.</p>
<p>If you use blocking interfaces for doing I/O, e.g. wait until \( x \) amount of bytes is read from this socket, you would need a separate thread for each call; one thread to read from a socket, another to fetch some records from a database, and so on.</p>
<p>In this method, the application uses the OS APIs to create user threads that map to kernel threads. This way the application does not need to have the facilities for managing threads and the binary sizes are smaller.</p>
<h3 id="cooperative-scheduling-and-asynchrony">Cooperative Scheduling and Asynchrony</h3>
<p>In Cooperative scheduling, tasks themselves yield execution to allow other tasks to run on the CPU. This is different from preemptive scheduling where the OS had to pause the execution of a task by force <a href="#osdev"  >[11]</a>. Cooperation is usually done with the help of the language and compiler and a runtime library. This runtime could either be embedded into the language itself or in the case of Rust, be included as a dependency.</p>
<p>Cooperative scheduling is useful for situations where there is a lot of I/O happening and if threads were used for each blocking operation, most of the time of that thread would simply be spent waiting for that operation (waiting for bytes to arrive from a socket or reading a file from disk). In asynchronous operations, however, the calling thread does not wait for the operation to be available and simply goes to do other things. When the resource associated with the asynchronous operation is ready, it notifies the thread that it can start executing the codes after that asynchronous operation.</p>
<p>In this type of scheduling, tasks are more fine-grained than threads and multiple tasks can be assigned to run on a single thread. For example, we can create a task for listening on a socket \( TaskA \) and another one for saving some information into a database \( TaskB \). Both of these tasks can be run on the same thread. When \( TaskA \) tries to read from the socket and no data is available, it saves its state and yields. After that, since our thread is now not doing anything it can try to execute \( TaskB \); \( TaskB \) executes and tries to write as many bytes as possible and then saves its state yields to the runtime. Now our thread goes to sleep and waits for either of the tasks to be available for execution. If there are new bytes available at the socket, for example, the operating system notifies the runtime and the runtime in turn wakes up \( TaskA \) and executes it on our thread. In <a href="#fig2-cooperative"  >figure 2</a> we can see an example of this scenario.</p>
<p>Saving the state is usually done by the language. In Rust, all the state needed for a task, for example, local variables or some parts of the call stack, is stored in a struct. The code for creating this struct and inserting the values into them is automatically generated by the compiler. In this way, the tasks don&rsquo;t need a separate call stack and use a shared one (that of the thread that they are running on). Now we can generate millions of tasks without having to worry about memory limitations.</p>
<figure><img src="./assets/img/asynchronous-multitasking-cooperative.jpg"
         alt="Figure 2: Cooperative Multitasking" id="fig2-cooperative"/><figcaption>
            <p>Figure 2: Cooperative Multitasking</p>
        </figcaption>
</figure>

<p>This method uses a kind of many-to-one mapping where multiple user tasks are mapped onto a user thread which themselves are mapped to a kernel thread. Its disadvantage is that a rouge task that does not yield, can starve all the other tasks waiting to be executed. Because of this, cooperative scheduling is usually used in environments where tasks can be trusted e.g. inside a project where tasks are created by the developers themselves.</p>
<h3 id="comparison">Comparison</h3>
<p>Let&rsquo;s check out an example that outlines the difference between multithreading and asynchrony.
In listing <a href="#lst4-threaded_tcp"  >listing 4</a> we can see a simple TCP server that listens on a port for new connections. Each time a connection arrives from a client, it creates a new socket for the client and passes that connection to a new thread. The <code>handle_connection</code> function is used to manage a single connection on a separate thread.</p>
<p>Depending on the memory of the machine that this server is run on, this approach is probably fine for thousands of connections; but when the number of connections gets to millions the memory requirements of the server process become infeasible.</p>
<div class="highlight" id="lst4-threaded_tcp"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> listener <span style="color:#f92672">=</span> TcpListener::bind(<span style="color:#e6db74">&#34;127.0.0.1:8090&#34;</span>).unwrap();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> socket_wrapped <span style="color:#66d9ef">in</span> listener.incoming() {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> socket <span style="color:#f92672">=</span> socket_wrapped.unwrap();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        thread::spawn(<span style="color:#f92672">||</span> {
</span></span><span style="display:flex;"><span>            handle_connection(socket);
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 4: Threaded TCP</em></p>
<p>We can use asynchronous tasks in Rust to handle connections concurrently. In this way, a single thread can handle multiple tasks and the maximum number of connections can go up to millions (of course if we ignore other limitations). The code in <a href="#lst5-async_tcp"  >listing 5</a> shows an example of using asynchronous tasks in Rust using the Tokio runtime. As you can see, asynchronous code looks a lot like normal synchronous code.</p>
<div class="highlight" id="lst5-async_tcp"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#75715e">#[tokio::main]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> listener <span style="color:#f92672">=</span> TcpListener::bind(<span style="color:#e6db74">&#34;127.0.0.1:8090&#34;</span>).<span style="color:#66d9ef">await</span>.unwrap();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">loop</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> (<span style="color:#66d9ef">mut</span> socket, _) <span style="color:#f92672">=</span> listener.accept().<span style="color:#66d9ef">await</span>.unwrap();
</span></span><span style="display:flex;"><span>        tokio::spawn(<span style="color:#66d9ef">async</span> <span style="color:#66d9ef">move</span> {
</span></span><span style="display:flex;"><span>            handle_connection(socket);
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 5: Async TCP</em></p>
<h3 id="futures-and-state-machines">Futures and State Machines</h3>
<p>Rust has support for cooperative tasks using futures and async/await. A future is a value that will be available at some time later. Instead of blocking for the value to be available, the caller can advance to do other things and only come back when the future is resolved and the value is ready. The cooperative tasks in Rust are a kind of future and futures are structs that implement a trait (interface) called \( Future \) (<a href="#lst6-future_trait"  >listing 6</a>). Types that implement the \( Future \) trait must implement a method called \( poll \) and specify the value that the future will resolve to. For example, you can call a future that returns the number of open file descriptors of the current process; when this future resolves it returns an integer.</p>
<div class="highlight" id="lst6-future_trait"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">trait</span> Future {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Output</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">poll</span>(self: <span style="color:#a6e22e">Pin</span><span style="color:#f92672">&lt;&amp;</span><span style="color:#66d9ef">mut</span> Self<span style="color:#f92672">&gt;</span>, cx: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">mut</span> Context)
</span></span><span style="display:flex;"><span>                             -&gt; <span style="color:#a6e22e">Poll</span><span style="color:#f92672">&lt;</span>Self::Output<span style="color:#f92672">&gt;</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">enum</span> <span style="color:#a6e22e">Poll</span><span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> {
</span></span><span style="display:flex;"><span>    Ready(T),
</span></span><span style="display:flex;"><span>    Pending,
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 6: Future Trait</em></p>
<p>The \( poll \) method&rsquo;s output type is an enum called \( Poll \) that has two items. Calling the \( poll \) method tries to run the future to completion; if the future completes it returns <code>Ready(T)</code> with the value inside it and if the value is still not ready it returns <code>Pending</code>.</p>
<p>Asynchronous functions in Rust return a structure that implements the \( Future \) trait and its \( poll \) method. If this future resolves, the type of the value in <code>Ready(T)</code> is the same as the return type of the \( async \) function. This is done by the compiler and allows the programmer to write asynchronous code that looks similar to normal synchronous code. We can use the \( await \) keyword inside an \( async \) function to wait for the value of another future.</p>
<p>The Rust compiler converts \( async \) functions into a state machine (a struct) that implements the \( Future  \) trait. This state machine is the future that is returned when an \( async  \) function is called. <a href="#lst7-async_fn_example"  >Listing 7</a> shows an example of such function. At line \( 4 \) we await reading all the contents of a file into a byte array; when reaching this statement while executing the task, since reading from disk is much slower than the speed of our processor, the task returns immediately return <code>Poll::Pending</code> to allow other tasks to proceed. <code>read_all_file</code> is another \( async \) function and calling it returns a future; \( await \)ing on that future stops the outer future (our \( async \) function) from going further and causes the outer function to return <a href="#rustrfccoroutines"  >[13]</a> <a href="#rustrfcfutures"  >[15]</a> <a href="#rustrfcasync"  >[14]</a>.</p>
<p>After the file has been read into the <code>file_bytes</code> buffer, the <code>pipe_to_socket</code> future is polled again it resumes from where it left off, after \( 6 \) and goes to \( await \) another future which tries to create a UDP socket. This goes on until the whole function is executed; each time the function hits an \( await \) point, it \( yields \) to the runtime so that other tasks can advance. The state of the function is saved across \( await \) points. For example, when waiting to receive bytes from the socket, the <code>file_bytes</code> and the <code>socket</code> variables are saved inside the compiler-generated struct and are used after the future (our function) is polled again to resume.</p>
<div class="highlight" id="lst7-async_fn_example"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">pipe_to_socket</span>() -&gt; <span style="color:#66d9ef">i32</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Read all the contents of a file
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">let</span> file_bytes <span style="color:#f92672">=</span> read_all_file(<span style="color:#e6db74">&#34;myFile.txt&#34;</span>).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Create a UDP socket
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">let</span> socket <span style="color:#f92672">=</span> UdpSocket::bind(<span style="color:#e6db74">&#34;0.0.0.0:8080&#34;</span>).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Receive some data from a client
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">let</span> (len, addr) <span style="color:#f92672">=</span> socket.recv_from(<span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> [<span style="color:#ae81ff">0</span>; <span style="color:#ae81ff">1024</span>]).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Send all the contents of the file
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    write_all_socket(socket, addr, file_bytes).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> len;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 7: Async Function Example</em></p>
<p>This yielding and resuming later creates a state machine. The state machine for the \( async \) function in <a href="#lst7-async_fn_example"  >listing 7</a> is shown in <a href="#fig3-state_machine"  >figure 3</a>.</p>
<figure><img src="./assets/img/asynchronous-state-machine.jpg"
         alt="Figure 3: Future State Machine" id="fig3-state_machine"/><figcaption>
            <p>Figure 3: Future State Machine</p>
        </figcaption>
</figure>

<p>As you can see, each time an \( await \) point is hit while executing a future, the control is yielded back to the runtime to execute other tasks. After an event occurs that the future is waiting on, the runtime finds the future waiting on that event and tries to poll it again so the future can progress. Each time a future returns to waiting on a resource, the runtime registers that resource to for example an operating system. The runtime then listens for events. These events come from the operating system signaling the runtime that some resource that has been registered with it, is now ready <a href="#rustrfcasync"  >[14]</a>.</p>
<p>An example of what the compiler-generated state machine could look like is outlined in <a href="#lst8-generated_state_machine"  >listing 8</a> (note that the code might not be semantically correct but nevertheless, it serves as a good example of how futures behave internally). The type of our state machine could be a simple enum with 6 different enumerations. Each enumeration is a state that contains all the necessary data needed to pause and resume the state machine. We implement the \( Future \) trait for this type and add a poll method for it. Each time the poll method is called, it tries to advance the state machine. It first determines which state it is in using pattern matching and then runs the code generated for that state.</p>
<p>For example, if the state machine was on State1 and it was polled by the runtime, first it would extract the variables stored in the current state, in the case of State1 the only variable is a future. This future is the result of calling the \( async \) function <code>read_all_file</code> when transitioning from State0 to State1. It would then try to poll the <code>read_all_file</code> future, if the future was not ready and returned \( Pending \) then the result of our outer future would be \( Pending \). However, if polling <code>read_all_file</code> reloved to a <code>Poll:Ready(file_bytes)</code> then we can transition to the next state State2 by first creating an instance of State2 and passing in the required variables, naming our byte array and the result of calling <code>UdpSocket::bind</code> which is a future. These variables are part of the state that our stat machine carries.</p>
<div class="highlight" id="lst8-generated_state_machine"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">enum</span> <span style="color:#a6e22e">PipeToSocketStateMachine</span> {
</span></span><span style="display:flex;"><span>    Start(),
</span></span><span style="display:flex;"><span>    State1 { read_all_file: <span style="color:#a6e22e">impl</span> Future<span style="color:#f92672">&lt;</span>Output <span style="color:#f92672">=</span> Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">u8</span><span style="color:#f92672">&gt;&gt;</span> },
</span></span><span style="display:flex;"><span>    State2 { file_bytes: Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">u8</span><span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>        bind: <span style="color:#a6e22e">impl</span> Future<span style="color:#f92672">&lt;</span>Output <span style="color:#f92672">=</span> UdpSocket<span style="color:#f92672">&gt;</span> },
</span></span><span style="display:flex;"><span>    State3 { file_bytes: Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">u8</span><span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>        socket: <span style="color:#a6e22e">UdpSocket</span>,
</span></span><span style="display:flex;"><span>        recv_from: <span style="color:#a6e22e">impl</span> Future<span style="color:#f92672">&lt;</span>Output <span style="color:#f92672">=</span> (<span style="color:#66d9ef">usize</span>, SocketAddr)<span style="color:#f92672">&gt;</span> },
</span></span><span style="display:flex;"><span>    State4 { file_bytes: Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">u8</span><span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>        socket: <span style="color:#a6e22e">UdpSocket</span>,
</span></span><span style="display:flex;"><span>        len: <span style="color:#66d9ef">usize</span>,
</span></span><span style="display:flex;"><span>        addr: <span style="color:#a6e22e">SocketAddr</span>,
</span></span><span style="display:flex;"><span>        write_all_socket: <span style="color:#a6e22e">impl</span> Future<span style="color:#f92672">&lt;</span>Output <span style="color:#f92672">=</span> ()<span style="color:#f92672">&gt;</span> },
</span></span><span style="display:flex;"><span>    Return(),
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> Future <span style="color:#66d9ef">for</span> PipeToSocketStateMachine {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Output</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">i32</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">poll</span>(self: <span style="color:#a6e22e">Pin</span><span style="color:#f92672">&lt;&amp;</span><span style="color:#66d9ef">mut</span> Self<span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>            cx: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">mut</span> Context) -&gt; <span style="color:#a6e22e">Poll</span><span style="color:#f92672">&lt;</span>Self::Output<span style="color:#f92672">&gt;</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">loop</span> {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">match</span> self {
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">Start</span>() <span style="color:#f92672">=&gt;</span> {<span style="color:#960050;background-color:#1e0010">…</span>}
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">State1</span>{read_all_file} <span style="color:#f92672">=&gt;</span> {
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">match</span> read_all_file.poll(cx) {
</span></span><span style="display:flex;"><span>                        Poll::Ready(file_bytes) <span style="color:#f92672">=&gt;</span> {
</span></span><span style="display:flex;"><span>                            <span style="color:#75715e">// Proceed to the next state
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>                            <span style="color:#f92672">*</span>self <span style="color:#f92672">=</span> PipeToSocketStateMachine::State2 {
</span></span><span style="display:flex;"><span>                                file_bytes,
</span></span><span style="display:flex;"><span>                                bind: <span style="color:#a6e22e">UdpSocket</span>::bind(<span style="color:#e6db74">&#34;0.0.0.0:8080&#34;</span>)
</span></span><span style="display:flex;"><span>                            }
</span></span><span style="display:flex;"><span>                        },
</span></span><span style="display:flex;"><span>                        Poll::Pending <span style="color:#f92672">=&gt;</span> {
</span></span><span style="display:flex;"><span>                            <span style="color:#66d9ef">return</span> Poll::Pending
</span></span><span style="display:flex;"><span>                        }
</span></span><span style="display:flex;"><span>                    }
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">State2</span>{file_bytes, bind} <span style="color:#f92672">=&gt;</span> {<span style="color:#960050;background-color:#1e0010">…</span>}
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">State3</span>{file_bytes, socket, recv_from}
</span></span><span style="display:flex;"><span>                                                               <span style="color:#f92672">=&gt;</span> {<span style="color:#960050;background-color:#1e0010">…</span>}
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">State4</span>{file_bytes, socket, len,
</span></span><span style="display:flex;"><span>                                       addr, write_all_socket} <span style="color:#f92672">=&gt;</span> {<span style="color:#960050;background-color:#1e0010">…</span>}
</span></span><span style="display:flex;"><span>                PipeToSocketStateMachine::
</span></span><span style="display:flex;"><span>                                <span style="color:#a6e22e">Return</span>(state) <span style="color:#f92672">=&gt;</span> {<span style="color:#960050;background-color:#1e0010">…</span>}
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 7: Generated State Machine</em></p>
<p>This state machine generation is done by <code>generators</code>. <em>A generator is a &ldquo;resumable function&rdquo; that syntactically resembles a closure but compiles to much different semantics in the compiler itself</em> <a href="#rustbook_generators"  >[18]</a>. The Rust compiler inserts \( yield \) operation in place of \( await \)s so that when the result of an \( await \) is <code>Pending</code> then the future pauses and yields; so each yield is in fact a state of our state machine. The Pin type in <a href="#lst6-future_trait"  >listing 6</a> makes sure that the wrapping type does not move around in memory; this is important in the case of self-referential structs where if the object is moved, its internal pointers to itself will be invalidated. The state machine that the compiler generates has these self-referential pointers and thus these futures must be pinned <a href="#rustrfcasync"  >[14]</a>.</p>
<h3 id="executors">Executors</h3>
<p>When a future is polled and it returns <code>Pending</code> something has to poll them again when they are able to make progress, otherwise our state machine won&rsquo;t advance. In the previous sections, we said that the &ldquo;runtime&rdquo; does the polling and that&rsquo;s true; the part of the runtime that polls futures to completion is called the executor. <a href="#lst9-executor"  >Listing 9</a> shows a very basic and primitive executor. It has a queue where futures are pushed into as tasks and it repeatedly tries to pop a task from the start of the queue and run it. Tasks are the futures that the executor works with; an example of a task is outlined in <a href="#lst10-task"  >listing 10</a>. Tasks are structs that usually hold an instance of a future in them, when we say &ldquo;run a task&rdquo; we mean to poll the future inside that task <a href="#rustrfcfutures"  >[15]</a>.</p>
<div class="highlight" id="lst9-executor"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">while</span> <span style="color:#66d9ef">let</span> Some(task) <span style="color:#f92672">=</span> self.queue.pop() {
</span></span><span style="display:flex;"><span>    task.run();
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 9: Executor</em></p>
<div class="highlight" id="lst10-task"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Task</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>    future: <span style="color:#a6e22e">Pin</span><span style="color:#f92672">&lt;</span>Box<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">dyn</span> Future<span style="color:#f92672">&lt;</span>Output <span style="color:#f92672">=</span> ()<span style="color:#f92672">&gt;&gt;&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> Task {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">run</span>(<span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> self) {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">match</span> self.future.poll() {
</span></span><span style="display:flex;"><span>            Poll::Pending <span style="color:#f92672">=&gt;</span> {<span style="color:#f92672">..</span>.},
</span></span><span style="display:flex;"><span>            Poll::Ready(val) <span style="color:#f92672">=&gt;</span> {<span style="color:#f92672">..</span>.}
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 10: Task</em></p>
<p>In <a href="#lst9-executor"  >listing 9</a> when a task is popped and its future is polled, two things can happen, either the task&rsquo;s future returns <code>Poll::Ready(value)</code> in which case there is nothing else to do, since the task has finished to completion, or it returns <code>Poll:Pending</code> indicating that this task has to be polled on a later time (for example it might be waiting on a socket or a read from the disk). For a task to be able to be run again, it needs to be added into the run queue of the executor; the question that remains is who does that?</p>
<h3 id="wakers">Wakers</h3>
<p>Wakers are the mechanism that Rust uses to signal the executor that a given task should be run (its inner future be polled). Wakers have a <code>wake()</code> method that when called, does this signaling. In the context of futures, wakers are usually wrapped in a <code>Context</code> type and are passed to the poll method of that future; <a href="#lst11-context"  >listing 11</a> shows an example of a Context struct. For our basic executor calling <code>wake()</code> on the waker of the context of a task, would simply add that task back to the executor run queue so that it can be polled once again. If the executor was asleep, it would also wake up the executor <a href="#rustrfcfutures"  >[15]</a>.</p>
<div class="highlight" id="lst11-context"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Waker</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Context</span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">&#39;a</span><span style="color:#f92672">&gt;</span> {
</span></span><span style="display:flex;"><span>    waker: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">&#39;a</span> <span style="color:#a6e22e">Waker</span>,
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> Waker {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">pub</span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">wake</span>(self) {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>    } 
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 11: Context</em></p>
<h3 id="future-tree">Future Tree</h3>
<p>The futures that we have seen so far all call other futures. In line 4 of <a href="#lst7-async_fn_example"  >listing 7</a> for example, the async <code>pipe_to_socket</code> function waits for the output of the future that calling <code>read_all_file</code> results; an example of what this function could look like is shown in <a href="#lst12-async_fn_example_sub"  >listing 12</a>. The same thing happens throughout the function. The futures that we are awaiting on themselves can await on other futures. This structure forms a tree <a href="#rustdoccratefuture"  >[3]</a> <a href="#rustdocfuture"  >[12]</a>.</p>
<div class="highlight" id="lst12-async_fn_example_sub"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">8
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">read_all_file</span>(path: <span style="color:#66d9ef">&amp;</span><span style="color:#66d9ef">str</span>) -&gt; Vec<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">u8</span><span style="color:#f92672">&gt;</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> file <span style="color:#f92672">=</span>  File::open(path).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> buffer <span style="color:#f92672">=</span> Vec::new();
</span></span><span style="display:flex;"><span>    file.read_to_end(<span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> buffer).<span style="color:#66d9ef">await</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> buffer;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 12: Nested Async Function Example</em></p>
<p><a href="#fig4-future_tree"  >Figure 4</a> shows this tree for the example in <a href="#lst12-async_fn_example_sub"  >listing 12</a> and <a href="#lst7-async_fn_example"  >7</a>.</p>
<figure><img src="./assets/img/asynchronous-future-tree.jpg"
         alt="Figure 4: Future Tree" id="fig4-future_tree"/><figcaption>
            <p>Figure 4: Future Tree</p>
        </figcaption>
</figure>

<p>As we can see tasks are the root of our future tree and are the futures that our executor is in contact with. Executors provide APIs for spawning new tasks by giving them a future. In <a href="#lst13-root_future"  >listing 13</a> we call our async <code>pipe_to_socket</code> function which returns a future, and pass this future to the spawn method of our executor (in this case Tokio&rsquo;s executor). The spawn method creates a task out of this future and adds it to the run queue of our executor.</p>
<div class="highlight" id="lst13-root_future"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#75715e">#[tokio::main]</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">async</span> <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>    tokio::spawn(pipe_to_socket());
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 13: Root Future</em></p>
<p>As we saw in line 28 of our state machine in <a href="#lst8-generated_state_machine"  >listing 8</a> when we call poll on our main task&rsquo;s future, it in turn, tries to poll its inner futures. But we can&rsquo;t keep polling other futures, somewhere in this tree there are futures that when they are polled, other than returning <code>Poll:Pending</code> they also make sure that the task that polled them will be run again when the resource its waiting on is available. These are the futures at the leaf nodes of our future tree. In <a href="#fig4-future_tree"  >figure 4</a> when we poll our task for the first time and give it a waker, which when its wake() method is called adds this task back to the run queue, it tries to poll the <code>read_all_file</code> future. The <code>read_all_file</code> future in turn tries to poll the <code>open(path)</code> future. The <code>open(path)</code> future is a leaf future so when it is polled, instead of polling another future it registers its waker and the resource it&rsquo;s waiting on with the driver (also called the reactor). In this case, the future asks the driver to open a file with the given path and the driver in turn asks the operating system to open the given file. The waker registered with the driver is passed down from the main task and the driver keeps a record of which wakers are related to which waiting resources. The leaf future then returns <code>Poll:Pending</code> and this return value is propagated back to the task and back to the executor. The executor then tries polling other tasks.</p>
<p>The driver periodically waits for the operating system to return a set of events. It then iterates through the events and dispatches all the wakers that have been registered with the given event&rsquo;s resource. In our case, when the file has been opened by the operating system, it returns an event. After seeing this event, the driver calls the wake() method on the waker registered with this event, and the task related to this waker is pushed back into the run queue to be polled again. When the task is polled again, since all of our futures are state machines and the future tree is somewhat a state machine tree, it starts polling from the root future all the way back down to the leaf future. The futures saved their state from the last time they were polled and now they resume from where they left off. This time when the leaf future is polled, it receives the resource it was waiting on (in our example, the file descriptor of the opened file) and returns <code>Poll::Ready(fd)</code> to its parent future. The parent future then goes on to poll the next future and so on.</p>
<h3 id="conclusion-1">Conclusion</h3>
<p>In this section, we discussed different ways that multitasking could be done. We outlined the advantages and disadvantages of preemptive and cooperative scheduling and talked about how asynchrony helps us utilize our memory and CPU cycles. We saw how rust implements asynchronous programming through the use of aync/await keywords and futures. Finally, we saw an example of how the Rust compiler helps us to create state machines from these futures and how executors and runtime libraries run these futures.</p>
<h2 id="tokio">Tokio</h2>
<p>Tokio is an asynchronous runtime for Rust, it provides the executor we talked about in the previous section that allows running futures. It is by far the most widely used runtime in the Rust ecosystem and many other projects are built on top of Tokio.
Tokio provides a whole host of functionalities:</p>
<ul>
<li>Task scheduler</li>
<li>An I/O driver (reactor) for interfacing with the operating system</li>
<li>Asynchronous network interfaces such as sockets</li>
<li>Communication and synchronization primitives for working with asynchronous tasks such as different kinds of channels, mutex, barrier, condvar, and &hellip;</li>
</ul>
<p>Tokio is broken into modules each providing different functionalities. Here we will be taking a closer look at the <code>runtime</code> module. This module does not expose a lot of APIs to the user of the library; most of them are for creating a runtime or spawning tasks unto the runtime. The runtime module is where the magic that allows writing high-performance asynchronous code in Rust happens and it itself consists of multiple parts <a href="#tokio"  >[19]</a>.</p>
<ul>
<li>A scheduler for assigning tasks to be run on the available cores</li>
<li>The I/O driver that wakes up waiting tasks when new events come form the operating system,</li>
<li>A time driver with a resolution of one millisecond used for time-based scheduling</li>
</ul>
<p>In the remainder of this chapter, we will be taking a closer look at the inner workings of the scheduler and the I/O driver of the Tokio runtime.</p>
<h3 id="scheduler">Scheduler</h3>
<p>The scheduler has the job of assigning tasks to the CPU cores until they yield back to the scheduler. The future inside the task is polled and it runs on the CPU until it hits an inner future that needs an external resource to be resolved. Tokio provides two kinds of schedulers: Multithreaded and Single-threaded. Here we will be taking a look at the multithreaded scheduler (the inner workings of the single-threaded one is similar).</p>
<h3 id="multithreaded-scheduler">Multithreaded scheduler</h3>
<p>When using the multithreaded scheduler (the default) Tokio creates a number of threads to scheduler tasks on. It then assigns a local run queue to each thread; threads then enter a loop where they constantly pop tasks from the start of their queue and run the task until it yields and then pops another one. When tasks are scheduled unto the runtime they usually come in batches by the I/O driver (when new events from the OS are received and corresponding tasks are woken to be added to a run queue) all these tasks get scheduled unto the local queue of one of the threads. Without any mechanism to distribute this load across all the available threads, we may experience resource underutilization where some threads are idle and others are doing much of the work.</p>
<p>To solve this issue and distribute the work uniformly, the Tokio scheduler uses work-stealing. When a thread has nothing else to do (its local run queue is empty), before going to sleep it checks the run queue of other threads for work and tries to steal some of their tasks. This is outlined in <a href="#fig5-workstealing"  >figure 5</a>. Thread 2 has run out of tasks and before going to sleep it checks other threads for work; it iterates through all the threads in descending order and finds right away that thread 4 has work to steal so it steals half of the tasks of thread 4 from the beginning of the queue.</p>
<p>The good thing about this approach is that synchronization and cross-thread communication is mostly avoided as the load on the system increases and threads never reach an empty queue to try to steal from others.
What happens when a thread tries to steal from other threads, doesn&rsquo;t find any work to steal, goes to sleep, and then a batch of tasks is pushed unto the run queue of other threads? A mechanism must be implemented so that threads with work can notify other sleeping threads so that they can wake up and steal work <a href="#tokio_scheduler"  >[5]</a>.</p>
<figure><img src="./assets/img/tokio-multithreaded.jpg"
         alt="Figure 5: Stealing Work" id="fig5-workstealing"/><figcaption>
            <p>Figure 5: Stealing Work</p>
        </figcaption>
</figure>

<h3 id="queue-and-work-stealing-implementation">Queue and Work Stealing Implementation</h3>
<p>The run queue is backed by a circular buffer outlined in <a href="#lst14-buffer_circular"  >listing 14</a>. The \( Arc \) type provides shared ownership of a value and is a thread-safe reference-counting pointer. Meaning that it&rsquo;s a reference to an object in the heap and can be cloned as many times; once the last reference has gone out of scope the object itself is deleted from the heap. The circular buffer has a tail that is only updated by a single thread and read by multiple threads and a head that can be updated concurrently by multiple threads. It is backed by a constant-sized array of Tasks; the elements of this array are uninitialized at first. The <code>Box</code> type indicates that the value will be allocated in the heap.</p>
<p>Two handles are created from the local queue of each thread, one is a \( Steal \) handle and the other is a \( Local \). The local handle is used by a single thread to push and pop tasks from the queue and the steal handle is available for all other threads so that they can peek into this thread&rsquo;s local queue and steal tasks if necessary. This is why the head and tail values are atomic; because they may be written to or read by multiple threads.</p>
<div class="highlight" id="lst14-buffer_circular"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#e6db74">/// Producer handle. May only be used from a single thread.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span><span style="color:#66d9ef">pub</span>(<span style="color:#66d9ef">crate</span>) <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Local</span> {
</span></span><span style="display:flex;"><span>    inner: <span style="color:#a6e22e">Arc</span><span style="color:#f92672">&lt;</span>Queue<span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/// Consumer handle. May be used from many threads.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span><span style="color:#66d9ef">pub</span>(<span style="color:#66d9ef">crate</span>) <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Steal</span>{
</span></span><span style="display:flex;"><span>    inner: <span style="color:#a6e22e">Arc</span><span style="color:#f92672">&lt;</span>Queue<span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>};
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">pub</span>(<span style="color:#66d9ef">crate</span>) <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Queue</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Concurrently updated by many threads.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    head: <span style="color:#a6e22e">AtomicU32</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Only updated by producer thread but read by many threads.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    tail: <span style="color:#a6e22e">AtomicU16</span>,
</span></span><span style="display:flex;"><span>    buffer: Box<span style="color:#f92672">&lt;</span>[MaybeUninit<span style="color:#f92672">&lt;</span>task::Task<span style="color:#f92672">&gt;</span>; <span style="color:#66d9ef">LOCAL_QUEUE_CAPACITY</span>]<span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 14: Circular Buffer</em></p>
<p>The 32-bit unsigned head of the queue is actually made up of two 16-bit unsigned integers. The left-most 16 bits are called the steal head and the right-most 16 bits are called the real head. These two heads are used for stealing operations and act as a signal to other threads that specify whether someone is currently stealing from the given queue or not. The real head specifies the position of the next task to be popped and the steal head specifies the starting position of the tasks that are going to be stolen from a run queue.</p>
<p>Pushing tasks into the queue is done by first adding the task to the backing array at the position indicated by the tail and then incrementing the tail. Before pushing a task, the value of the real head is subtracted from the tail and is compared with the maximum length of the backing array; if there were enough space available, the pushing continues.</p>
<div class="highlight" id="lst15-steal"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">impl</span> Steal {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">pub</span>(<span style="color:#66d9ef">crate</span>) <span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">steal_into</span>(<span style="color:#f92672">&amp;</span>self, dst: <span style="color:#66d9ef">&amp;</span><span style="color:#a6e22e">mut</span> Local<span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> dst_tail <span style="color:#f92672">=</span> dst.inner.tail.unsync_load();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> prev_packed <span style="color:#f92672">=</span> self.inner.head.load();
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> next_packed;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> (src_head_steal, src_head_real) <span style="color:#f92672">=</span> unpack(prev_packed);
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> src_tail <span style="color:#f92672">=</span> self.inner.tail.load();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// If these two do not match, another thread is concurrently
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// stealing from the queue.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> src_head_steal <span style="color:#f92672">!=</span> src_head_real { <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Number of available tasks to steal
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">let</span> n <span style="color:#f92672">=</span> (src_tail.wrapping_sub(src_head_real)) <span style="color:#f92672">/</span> <span style="color:#ae81ff">2</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// No tasks available to steal
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> n <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> { <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>; }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Update the real head index to acquire the tasks.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">let</span> steal_to <span style="color:#f92672">=</span> src_head_real.wrapping_add(n);
</span></span><span style="display:flex;"><span>        next_packed <span style="color:#f92672">=</span> pack(src_head_steal, steal_to);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Claim all those tasks.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        self.inner.head.compare_exchange(prev_packed, next_packed);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> (first, _) <span style="color:#f92672">=</span> unpack(next_packed);
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> i <span style="color:#66d9ef">in</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">..</span>n {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// Compute the positions
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            <span style="color:#66d9ef">let</span> src_pos <span style="color:#f92672">=</span> first.wrapping_add(i);
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">let</span> dst_pos <span style="color:#f92672">=</span> dst_tail.wrapping_add(i);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// Read the task
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            <span style="color:#66d9ef">let</span> task <span style="color:#f92672">=</span> self.inner.buffer[src_pos].read();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// Write the task to the new slot
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            dst.inner.buffer[dst_pos].write(task);
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> prev_packed <span style="color:#f92672">=</span> next_packed;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Update `src_head_steal` to match `src_head_real`
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">let</span> head <span style="color:#f92672">=</span> unpack(prev_packed).<span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>        next_packed <span style="color:#f92672">=</span> pack(head, head);
</span></span><span style="display:flex;"><span>        self.inner.head.compare_exchange(prev_packed, next_packed);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// No tasks were stolen
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> n <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> { <span style="color:#66d9ef">return</span> None; }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Make the stolen items available to consumers
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        dst.inner.tail.store(dst_tail.wrapping_add(n));
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 15: Stealing</em></p>
<p>Popping is also straightforward, first, it is checked that the value of the real head and tail are not equal, if they are then the buffer is empty and no tasks can be popped. Otherwise, the tasks at position <code>real_head</code> are taken out from the buffer and the value of real head is incremented by one.</p>
<p>A simplified version of the stealing algorithm is outlined in <a href="#lst15-borrowing"  >listing 15</a>. The <code>steal_into</code> function is called by the stealing thread on the steal handle of the run queue of the thread that it wants to steal from. This function takes a local run queue handle as the destination queue into which tasks will be stolen. Stealing threads pass their own run queue to this function.</p>
<p>Lines \( 3 \) through \( 9 \) load the tail and head values for the source and destination queues. The head value is unpacked into steal and real head. Unpacking is simply splitting the 32-bit value into two 16-bit values. At line \( 13 \), if the steal head and the real head of the source queue do not match then this means that another thread is concurrently stealing from this queue and the function returns immediately. At line \( 16 \) the number of tasks to be stolen \( n \) is assigned half of the number of available tasks on the source queue. To signal other threads that a stealing operation is underway, the real head of the source queue is advanced by \( n \) at line \( 22 \) and after repacking the head values into a 32-bit number, it is placed back into the atomic head field of the source queue. We then go through all the claimed tasks and transfer them one by one from the source queue to the destination queue. We then update the steal head of the source queue to match its real head; this signals that the stealing operation has ended. Finally, the tail of the destination queue is updated so that the stolen tasks can be popped and executed by the consumer thread. This procedure is depicted in <a href="#fig6-steal"  >figure 6</a>.</p>
<figure><img src="./assets/img/tokio-steal.jpg"
         alt="Figure 6: Stealing Tasks" id="fig6-steal"/><figcaption>
            <p>Figure 6: Stealing Tasks</p>
        </figcaption>
</figure>

<p>For the sake of simplicity, all the code concerning memory orderings has been removed from the examples. There are also some subtleties that must be noted while pushing a task unto the run queue of a thread:</p>
<ul>
<li>If the queue is not full, then the task is simply pushed back to the queue.</li>
<li>If the queue is full and there is a thread currently stealing from the queue (the steal head and the real head are not equal) then this means that the run queue will be empty soon so the given task is instead pushed to the global queue. The global queue (also called the inject queue) is a shared linked list among all the threads where the insertion or deletion of tasks in the queue is guarded by a mutex.</li>
<li>If the queue is full and no other thread is currently stealing from the local run queue, then <code>push_overflow</code> is called. This function takes half of the tasks of the local run queue and adds them in a batch into the global queue.</li>
</ul>
<h3 id="workers">Workers</h3>
<p>There are a couple of important data structures that are outlined in <a href="#lst16-structs"  >listing 16</a>. When the multithreaded scheduler is created, a number of workers are also created. Each worker is assigned to a newly spawned thread (one thread per worker). An instance of the \( Core \) structure is given to each thread; this struct contains data such as the local run queue, the number of ticks, etc. The \( Shared \) struct contains data that is shared across all workers (threads) such as the global queue (inject queue), a list of \( Steal \) handles corresponding to the queues of all the threads (for example \( remotes[2] \) corresponds to the \( Steal \) handle of the third worker&rsquo;s run queue) and some other structures.</p>
<div class="highlight" id="lst16-structs"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#e6db74">/// Core data
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Core</span> {
</span></span><span style="display:flex;"><span>    tick: <span style="color:#66d9ef">u32</span>,
</span></span><span style="display:flex;"><span>    lifo_slot: Option<span style="color:#f92672">&lt;</span>Task<span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// The worker-local run queue.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    run_queue: <span style="color:#a6e22e">queue</span>::Local,
</span></span><span style="display:flex;"><span>    is_searching: <span style="color:#66d9ef">bool</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/// State shared across all workers
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span><span style="color:#66d9ef">pub</span>(<span style="color:#66d9ef">super</span>) <span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Shared</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Per-worker remote state. All other workers have access
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    <span style="color:#e6db74">/// to this and is how they communicate between each other.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    remotes: Box<span style="color:#f92672">&lt;</span>[Remote]<span style="color:#f92672">&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Global task queue.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    inject: <span style="color:#a6e22e">Inject</span><span style="color:#f92672">&lt;</span>Arc<span style="color:#f92672">&lt;</span>Handle<span style="color:#f92672">&gt;&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">/// Used to communicate with a worker from other threads.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span><span style="color:#66d9ef">struct</span> <span style="color:#a6e22e">Remote</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Steals tasks from this worker.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    steal: <span style="color:#a6e22e">queue</span>::Steal<span style="color:#f92672">&lt;</span>Arc<span style="color:#f92672">&lt;</span>Handle<span style="color:#f92672">&gt;&gt;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/// Unparks the associated worker thread
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"></span>    unpark: <span style="color:#a6e22e">Unparker</span>,
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 16: Structs</em></p>
<p>The LIFO slot in the core structure is an optimization for message passing scenarios. When two tasks are communicating over a channel, the following scenario happens frequently:</p>
<ul>
<li>\( Task1 \) and \( Task2 \) are communicating over a channel.</li>
<li>\( Task2 \) is currently blocked on side of the channel waiting for a message from \( Task1 \)</li>
<li>\( Task1 \) sends a message through the channel</li>
<li>\( Task2 \) is wakened up and is placed at the end of the run queue
The problem here is that since \( Task2 \) is placed at the end of the run queue, there might be a lot of latency between the sending of the message by \( Task1 \) and its receive by \( Task2 \). For this reason, the Tokio scheduler has a LIFO (last in first out) slot where new tasks are placed inside it and when the scheduler wants to pop tasks from the queue, it first checks the LIFO slot for a task and only if it was empty goes for the other task at the head of the queue.</li>
</ul>
<p>Let&rsquo;s now take a look at how workers are created and what they do when they start. <a href="#lst17-workers"  >Listing 17</a> shows this procedure. First of all, each worker is run on a separate new thread. The workers then start executing statements inside a loop until the runtime is shut down. The \( tick \) field of the \( Core \) structure holds the number of iterations that the worker has had inside this loop. At line \( 15 \) the tick is incremented. If the value of tick is multiple of <code>event_interval</code> (part of the shared scheduler configuration) then the worker proceeds to try and run the driver at line \( 19 \). We&rsquo;ll talk about the driver in the next section.</p>
<p>In line \( 23 \) the worker tries to acquire a task. The <code>next_task</code> function first checks the LIFO slot for a task and if it was empty it pops a task from the local run queue of the worker. Running a task as we discussed in the previous chapter, means pulling its associated future.</p>
<p>The <code>steal_work</code> function at line \( 30 \) would first try to steal from sibling workers into its run queue and return one of the stolen tasks (the stealing mechanism was explained previously) if no tasks could be stolen from the siblings, it then checks the global run queue for a task. If no tasks were available, the worker is parked (goes to sleep) until an influx of tasks prompts other threads to wake this worker up. Before going to sleep, some threads may also try to take and run the driver/</p>
<div class="highlight" id="lst17-workers"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#f92672">..</span>. {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// as a part of the staring sequence
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#75715e">// of the runtime.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">for</span> worker <span style="color:#66d9ef">in</span> self.all_workers() {
</span></span><span style="display:flex;"><span>        runtime::spawn_thread(<span style="color:#66d9ef">move</span> <span style="color:#f92672">||</span> run(worker));
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">run</span>(worker: <span style="color:#a6e22e">Arc</span><span style="color:#f92672">&lt;</span>Worker<span style="color:#f92672">&gt;</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> core <span style="color:#f92672">=</span> worker.core.take();
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">while</span> <span style="color:#f92672">!</span>core.is_shutdown {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Increment the tick
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        core.tick();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> core.tick <span style="color:#f92672">%</span> self.worker.shared.handle
</span></span><span style="display:flex;"><span>                       .config.event_interval <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// Run I/O Driver, Timer, ...
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            core <span style="color:#f92672">=</span> self.run_driver(core);
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// First, check work available to the current worker.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">let</span> Some(task) <span style="color:#f92672">=</span> core.next_task(<span style="color:#f92672">&amp;</span>self.worker) {
</span></span><span style="display:flex;"><span>            core <span style="color:#f92672">=</span> self.run_task(task, core)<span style="color:#f92672">?</span>;
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">continue</span>;
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// There is no more **local** work to process, try to
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#75715e">// steal work from other workers.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">let</span> Some(task) <span style="color:#f92672">=</span> core.steal_work(<span style="color:#f92672">&amp;</span>self.worker) {
</span></span><span style="display:flex;"><span>            core <span style="color:#f92672">=</span> self.run_task(task, core)<span style="color:#f92672">?</span>;
</span></span><span style="display:flex;"><span>        } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// Wait for work
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>            core <span style="color:#f92672">=</span> self.park(core);
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">..</span>.
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 17: Worker</em></p>
<h3 id="io-driver">I/O Driver</h3>
<p>The runtime driver is protected by a mutex and only a single worker at a time can have control of the driver. Threads try to take control of the driver on a regular basis (every 64 ticks for example). The runtime driver is composed of different drivers that serve different purposes: I/O driver, time driver, process driver, etc. The I/O driver is responsible for listening to for events from the operating system and dispatching resources associated with those events.</p>
<p>In <a href="#lst17-workers"  >listing 17</a> at line 20, when a worker tries to run the runtime driver, it first has to lock a mutex, if the lock was successful (no other worker is in control of the driver) the worker can proceed. Here we will be focusing on the I/O driver of the runtime driver. (when the <code>run_driver</code> function is called it runs its inner drivers including the I/O driver).</p>
<p>The I/O driver contains a data structure that can save the records that specify which resources are associated with which events. Right now Tokio uses Mio a low-level I/O library for Rust; Mio is an abstraction over different operating systems&rsquo; asynchronous APIs <a href="#mio"  >[10]</a>.
The leaf futures register resources they are interested in with Mio through the data structure that the I/O driver provides. Mio then interfaces with the operating system and passes down these events using whatever API the underlying OS provides. The I/O driver then blocks on a call to <code>poll</code> function from Mio and waits for events to arrive. After receiving the events from the operating system, Mio passes up these events to the caller of <code>poll</code>, and its the caller&rsquo;s job to handle which resources should be notified.</p>
<p>For example in the case of reading from a socket, when a task blocks for a socket to be readable, it is the I/O driver&rsquo;s job to get the events from Mio, see that there is an event associated with the socket saying that the socket is now readable, and call the waiting task&rsquo;s waker <code>wake()</code> method.</p>
<p><a href="#lst18-driver"  >Listing 18</a> shows the function that gets called when running the I/O driver. At line \( 5 \) prepare an array of events (this array is reused across calls to the I/O driver). Then at line \( 9 \) the thread that is running the driver blocks on a call to <code>poll</code> passing the array of events to be filled and waiting for events to arrive from Mio (and hence the operating system). Once the events arrive, it iterates through them one by one and dispatches the sources associated with them (for example rescheduling tasks back on the run queue).</p>
<p>One important thing to notice is that the tasks are all scheduled on the run queue of the worker taking control of the driver, this is why earlier we said that tasks come in batches. Now we let the work-stealing algorithm do the rest and distribute the tasks across workers.</p>
<div class="highlight" id="lst18-driver"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-rust" data-lang="rust"><span style="display:flex;"><span><span style="color:#66d9ef">fn</span> <span style="color:#a6e22e">turn</span>(<span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> self, max_wait: Option<span style="color:#f92672">&lt;</span>Duration<span style="color:#f92672">&gt;</span>) {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    self.tick <span style="color:#f92672">=</span> self.tick.wrapping_add(<span style="color:#ae81ff">1</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> events <span style="color:#f92672">=</span> self.events.take();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Block waiting for an event to happen,
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#75715e">// peeling out how many events happened.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    self.poll.poll(<span style="color:#f92672">&amp;</span><span style="color:#66d9ef">mut</span> events, max_wait);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Process all the events that came in, dispatching appropriately
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">let</span> <span style="color:#66d9ef">mut</span> ready_count <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> event <span style="color:#66d9ef">in</span> events.iter() {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">let</span> token <span style="color:#f92672">=</span> event.token();
</span></span><span style="display:flex;"><span>        self.dispatch(token, Ready::from_mio(event));
</span></span><span style="display:flex;"><span>        ready_count <span style="color:#f92672">+=</span> <span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    self.events <span style="color:#f92672">=</span> Some(events);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 18: Driver</em></p>
<h3 id="conclusion-2">Conclusion</h3>
<p>In this section, we introduced Tokio: an asynchronous runtime for Rust. Tokio plays the role of the executor that we talked about in chapter <a href="#asynchronous-programming"  >Asynchronous Programming</a>.
We took a look at how the multithreaded scheduler works and what the work-stealing algorithm does and why it is important. We then dug deeper into the implementation of the queue used by the scheduler and how work-stealing functions with them. The inner workings of the workers were discussed, how they are created and run on their own thread, what data types they use and how they function. Finally, we took a more in-depth look at the I/O driver that has been discussed since chapter <a href="#asynchronous-programming"  >Asynchronous Programming</a>.</p>
<h2 id="io_uring">io_uring</h2>
<p>Linux provides a set of system calls for doing asynchronous I/O. <code>epoll</code> is an example of such a system call that is used in Mio as its Linux backend (see chapter <a href="#tokio"  >Tokio</a> section <a href="#io-driver"  >I/O Driver</a>, These system calls can monitor a set of file descriptors such as network sockets and check their status for doing I/O, e.g. see whether the socket is readable.</p>
<p><code>epoll</code> takes a set of interests containing the file descriptors that a process wants to monitor. It then returns a ready list (a subset of interest list) which is a set of file descriptors that are ready for I/O; the process can block on the <code>epoll_wait</code> system call until a set of ready file descriptors is returned by the kernel.</p>
<h3 id="epoll-for-files">epoll for Files</h3>
<p>Being able to use asynchronous I/O for file system operations is consequential for performance. Large-scale Webservers, SFTP servers, databases, and a lot of other applications all need the asynchrony that epoll provides; because when you reach a point where there are thousands of requests and concurrent connections, blocking for read and write operations on the file system can have a huge impact on performance.</p>
<p>The problem with <code>epoll</code> is that it always returns a ready status for files. In fact, using <code>epoll</code> is only sensible for file descriptors that normally block when being used for I/O such as network sockets and pipes. Because of this, Tokio and other libraries in different languages use a thread pool for file operations meaning when a future wants to do I/O on files, the request for I/O is sent to another thread and is executed synchronously there. This is where <code>io_uring</code> comes in. <a href="#lorduring"  >[9]</a></p>
<h3 id="the-io-uring">The I/O Uring</h3>
<p><code>io_uring</code> was introduced in Linux Kernel version 5.1 in 2019. The goal of <code>io_uring</code> is to replace old interfaces for async I/O and bring improved performance by reducing overhead for applications. <code>io_uring</code> solves the problem with regular files and brings a uniform API under which programs can enjoy the benefits of asynchrony.</p>
<p><code>io_uring</code> uses two ring buffers. One for submitting requests to the kernel and the other for receiving the completion of those requests.</p>
<p>The <code>io_uring_setup()</code> system call is used by the program to create these two ring buffers. These two buffers are created using <code>mmap</code> with the goal of sharing them between user space and kernel space. This reduces the overhead of copying data structures between the two. <a href="#iouringman"  >[6]</a></p>
<p>Submissions are added to the submission buffer in the form of a submission queue entry (SQE) type. SQE is a struct with fields that can support a lot of the operations that a program would need, e.g. reading from a socket, creating a file, writing to a file, etc. After adding SQEs to the submission buffer, the program can call the <code>io_uring_enter()</code> system call to signal the kernel that there are SQEs available and that it should start reading them. A simplified version of the SQE struct is available in <a href="#lst19-sqe"  >listing 19</a>.</p>
<p>Different fields of this struct serve different purposes depending on the type of the operation. For example, if you wanted to do a rename operation as the opcode you would use <code>IOURING_OP_RENAMEAT</code> (one of the cases in a huge enum called io_uring_op), set <code>addr</code> as the old path and <code>addr2</code> as the new path; other fields may also need to be filled. This is effectively equivalent to the <code>renameat2</code> system call. <a href="#iouringenterman"  >[7]</a></p>
<div class="highlight" id="lst19-sqe"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">struct</span> io_uring_sqe {
</span></span><span style="display:flex;"><span>	__u8	opcode;		<span style="color:#75715e">/* type of operation for this sqe */</span>
</span></span><span style="display:flex;"><span>	__u8	flags;		<span style="color:#75715e">/* IOSQE_ flags */</span>
</span></span><span style="display:flex;"><span>	__s32	fd;		<span style="color:#75715e">/* file descriptor to do IO on */</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>		__u64	addr;	<span style="color:#75715e">/* pointer to buffer or iovecs */</span>
</span></span><span style="display:flex;"><span>        ...
</span></span><span style="display:flex;"><span>	};
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>		__u64	addr2;
</span></span><span style="display:flex;"><span>        ...
</span></span><span style="display:flex;"><span>	};
</span></span><span style="display:flex;"><span>	__u32	len;		<span style="color:#75715e">/* buffer size or number of iovecs */</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>		__kernel_rwf_t	rw_flags;
</span></span><span style="display:flex;"><span>        ...
</span></span><span style="display:flex;"><span>		__u32		rename_flags;
</span></span><span style="display:flex;"><span>        ...
</span></span><span style="display:flex;"><span>	};
</span></span><span style="display:flex;"><span>	__u64	user_data;	<span style="color:#75715e">/* data to be passed back 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">                            at completion time */</span>
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Listing 19: SQE</em></p>
<p>After processing the SQEs, the kernel submits completion queue entries (CQE) to the completion queue. Each CQE in the completion queue has had a corresponding SQE in the submission queue entry. The program then reads these CQEs and takes proper action based on their status. The user space can block and wait for CQEs using the same system call for submitting SQEs <code>io_uring_enter()</code>.</p>
<p><a href="#fig7-uring"  >Figure 7</a> shows a simple view of how these buffers work.</p>
<figure><img src="./assets/img/uring-uring.jpg"
         alt="Figure 7: I/O urings" id="fig7-uring"/><figcaption>
            <p>Figure 7: I/O urings</p>
        </figcaption>
</figure>

<p>This work can be submitted and read in batches and thus, the number of system calls reduces significantly which can improve the performance of the application. One of the reasons that system calls can tax the performance so much is because of the security precautions that are taken by the operating system to avoid vulnerabilities like Specter and Meltdown <a href="#kocher2018spectre"  >[4]</a> <a href="#lipp2018meltdown"  >[8]</a>.</p>
<h3 id="conclusion-3">Conclusion</h3>
<p>We talked about the asynchronous APIs that the Linux kernel provides for applications and took a peek into the inner workings of <code>epoll</code>. We then discussed how <code>epoll</code> falls short when it comes to asynchronous file operations and how runtimes using <code>epoll</code> have to resort to a thread pool for their file I/O. After that, <code>io_uring</code> was introduced as a solution to the shortcomings of previous async I/O APIs of Linux and we developed a view of how <code>io_uring</code> works. Tokio has been working on <code>tokio_uring</code> to experiment with the integration of tokio and <code>io_uring</code> <a href="#tokiouring"  >[1]</a>.</p>
<h2 id="conclusion-4">Conclusion</h2>
<p>In this post, the Rust programming language was introduced; we saw how concepts like ownership and borrowing work together to achieve memory and type safety at compile time. Traditional languages like C/C++ were notorious for easily allowing developers to make mistakes while managing their memory, causing dangerous security flaws and vulnerabilities to be rampant in programs written in those languages.</p>
<p>We then shifted our attention to asynchronous programming and talked about different multitasking methods such as preemptive and cooperative. We outlined the advantages and disadvantages of each method and concluded that to avoid saturating memory when the number of requests increases dramatically, we can use asynchronous tasks (green threads) instead of traditional threads that each had their own call stack. We then took a peek at how Rust allows writing asynchronous programs just as easy as their normal synchronous counterparts. Futures and the state machine that the compiler generates were discussed and saw how we need executors to poll these futures and need wakers to be able to reschedule future on to the runtime.</p>
<p>Next, we talked about Tokio, an asynchronous runtime for Rust, and outlined the different parts of it. We took an in-depth look at how tokio schedules tasks and how workers that run on a thread, manage their run queues. The I/O driver and its job with registering resources was also discussed. In the final chapters, asynchronous interfaces for the Linux operating systems were introduced and their advantages and disadvantages were outlined. We talked about how <code>io_uring</code> was introduced to resolve the shortcomings of the previous async interfaces.</p>
<h2 id="references">References</h2>
<blockquote>
<p>You can cite this work through <a href="http://dx.doi.org/10.13140/RG.2.2.22229.29927"   target="_blank">this</a> DOI.</p>
</blockquote>
<ul>
<li><span id="tokiouring">[1]</span> A crate that provides io-uring for Tokio by exposing a new Runtime that is compatible with Tokio but also can drive io-uring-backed resources. 2022. url: <a href="https://github.com/tokio-rs/tokio-uring"   target="_blank">https://github.com/tokio-rs/tokio-uring</a>.</li>
<li><span id="most_vulnerabilities">[2]</span> Alex Gaynor. What science can tell us about C and C++’s security. 2021. url: <a href="https://alexgaynor.net/2020/may/27/science-on-memory-unsafety-andsecurity/"   target="_blank">https://alexgaynor.net/2020/may/27/science-on-memory-unsafety-andsecurity/</a>.</li>
<li><span id="rustdoccratefuture">[3]</span> Crate futures 0.1.30, Trait futures::future::Future. 2018. url: <a href="https://docs.rs/futures/0.1.30/futures/future/trait.Future.html"   target="_blank">https://docs.rs/futures/0.1.30/futures/future/trait.Future.html</a>.</li>
<li><span id="kocher2018spectre">[4]</span> Paul Kocher et al. “Spectre Attacks: Exploiting Speculative Execution”. In: 40th IEEE Symposium on Security and Privacy (S&amp;P’19). 2019.</li>
<li><span id="tokio_scheduler">[5]</span> Carl Lerche. Making the Tokio scheduler 10x faster. 2019. url: <a href="https://tokio.rs/blog/2019-10-scheduler"   target="_blank">https://tokio.rs/blog/2019-10-scheduler</a>.</li>
<li><span id="iouringman">[6]</span> liburing manual: io uring.7. 2022. url: <a href="https://git.kernel.dk/cgit/liburing/tree/man/io_uring.7"   target="_blank">https://git.kernel.dk/cgit/liburing/tree/man/io_uring.7</a>.</li>
<li><span id="iouringenterman">[7]</span> liburing manual: io uring enter.2. 2022. url: <a href="https://git.kernel.dk/cgit/liburing/tree/man/io_uring_enter.2"   target="_blank">https://git.kernel.dk/cgit/liburing/tree/man/io_uring_enter.2</a>.</li>
<li><span id="lipp2018meltdown">[8]</span> Moritz Lipp et al. “Meltdown: Reading Kernel Memory from User Space”. In: 27th USENIX Security Symposium (USENIX Security 18). 2018.</li>
<li><span id="lorduring">[9]</span> Lord of the io uring: Asynchronous Programming Under Linux. 2022. url: <a href="https://unixism.net/loti/async_intro.html"   target="_blank">https://unixism.net/loti/async_intro.html</a>.</li>
<li><span id="mio">[10]</span> Mio: Metal IO library for Rust. 2022. url: <a href="https://github.com/tokio-rs/mio"   target="_blank">https://github.com/tokio-rs/mio</a>.</li>
<li><span id="osdev">[11]</span> Philipp Oppermann. Writing an OS in Rust: Async/Await Chapter. 2020. url: <a href="https://os.phil-opp.com/async-await/"   target="_blank">https://os.phil-opp.com/async-await/</a>.</li>
<li><span id="rustdocfuture">[12]</span> Rust Documentation, Trait std::future::Future. 2022. url: <a href="https://doc.rust-lang.org/std/future/trait.Future.html"   target="_blank">https://doc.rust-lang.org/std/future/trait.Future.html</a>.</li>
<li><span id="rustrfccoroutines">[13]</span> Rust RFC 2033 experimental coroutines. 2018. url: <a href="https://github.com/rust-lang/rfcs/blob/master/text/2033-experimental-coroutines.md"   target="_blank">https://github.com/rust-lang/rfcs/blob/master/text/2033-experimental-coroutines.md</a>.</li>
<li><span id="rustrfcasync">[14]</span> Rust RFC 2394 async/await. 2018. url: <a href="https://github.com/rust-lang/rfcs/blob/master/text/2394-async_await.md"   target="_blank">https://github.com/rust-lang/rfcs/blob/master/text/2394-async_await.md</a>.</li>
<li><span id="rustrfcfutures">[15]</span> Rust RFC 2592 Future API. 2018. url: <a href="https://github.com/rust-lang/rfcs/blob/master/text/2592-futures.md"   target="_blank">https://github.com/rust-lang/rfcs/blob/master/text/2592-futures.md</a>.</li>
<li><span id="stackoverflow_survey_2021">[16]</span> Stack Overflow. Stack Overflow Developer Survey 2021. 2021. url: <a href="https://insights.stackoverflow.com/survey/2021#section-most-loved-dreadedand-wanted-programming-scripting-and-markup-languages"   target="_blank">https://insights.stackoverflow.com/survey/2021#section-most-loved-dreadedand-wanted-programming-scripting-and-markup-languages</a>.</li>
<li><span id="rustbook">[17]</span> The Rust Book. 2022. url: <a href="https://github.com/rust-lang/book"   target="_blank">https://github.com/rust-lang/book</a>.</li>
<li><span id="rustbook_generators">[18]</span> The Rust Unstable Book. 2022. url: <a href="https://doc.rust-lang.org/beta/unstable-book/language-features/generators.html"   target="_blank">https://doc.rust-lang.org/beta/unstable-book/language-features/generators.html</a>.</li>
<li><span id="tokio">[19]</span> Tokio: A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, &hellip; 2022. url: <a href="https://github.com/tokio-rs/tokio"   target="_blank">https://github.com/tokio-rs/tokio</a>.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>OFMon: Offline-first Smart Energy Monitor with Rust, ESP32, and Thingsboard</title>
      <link>https://moslehian.com/posts/2022/3-ofmon/</link>
      <pubDate>Mon, 23 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://moslehian.com/posts/2022/3-ofmon/</guid>
      <description>Creating an smart energy monitoring platform using embedded Rust, Espressif microcontrollers, and Thingsboard.</description>
      <content:encoded><![CDATA[<blockquote>
<p>The Rust code is available <a href="https://github.com/arashsm79/OFMon"   target="_blank">here</a> and the mobile application can be found in <a href="https://github.com/arashsm79/OFMonMobile"   target="_blank">this</a> repository. This development of this project was in 2022-09.</p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>There have been numerous smart energy monitoring systems based on the Internet of things (IoT). In most of these systems, the end devices are directly connected to a network and are continuously sending out their data. This poses a real challenge in environments where a reliable wireless connection is not always available, e.g., inside containers, remote locations, or even in places where there is simply no proper infrastructure for wireless communication.</p>
<p>I have developed an offline-first energy monitoring system using ESP32 microcontrollers and their bleeding-edge Rust ecosystem to store data locally in their flash. The readings are collected from the devices by connecting to their access point and are saved on the local storage using a smartphone running a fork of the Thingsboard Flutter Mobile application. After collecting the telemetry data from the devices and when a network connection is available, the mobile app can flush the data of all the devices to the Thingsboards server, an IoT platform used for data collection and visualization. Rust is a type-safe and memory-safe system programming language, it provides its safety guarantees at compile time using rules that eliminate many memory-safety issues. There has been a significant adoption using Rust for embedded development after companies like STMicrocontrollers and Espressif Systems introduced their community projects for enabling the use of the Rust programming language on their SoCs and modules.</p>
<p>A Current transformer is connected to the ADC subsystem of the ESP32 microcontroller and is used to calculate the RMS current and voltage and kWh of the power line. These readings are periodically saved to flash storage. The device also creates a Wi-Fi access point using a unique SSID that is a combination of its MAC address and a predefined string. It then spins up a web server to which clients can request telemetry data along with other operations.</p>
<p>The filesystem used for flash storage is of utmost importance. We have chosen LittleFS since it is power-loss resilient and has wear-leveling mechanisms for flash storage. It also uses constant RAM to work with any kind of data. Some parts of the flash storage have been reserved for Over-the-Air (OTA) updates, but the majority of the flash storage is formatted with the LittleFS file system. The devices are identified using their server-side representation token which is given to them on their first-time initialization using the mobile app. The mobile app also maintains a list of the devices it has connected to and fetches their server-side information when a connection is available. This information is shown alongside the devices’ SSID when scanning for access points. After collecting the data from the devices and syncing it with the Thingsboard server, customers with a few devices or operators with tens of devices can view their data both on the mobile app and on the
Thingsboard web app.
<img loading="lazy" src="./assets/img/1-mobile-preview.jpg#center" alt="Mobile App Preview"  />

<img loading="lazy" src="./assets/img/2-thingsboard-iot.jpg#center" alt="Thingsboard Dashboard"  />

<img loading="lazy" src="./assets/img/22-thingsboard-iot.jpg#center" alt="Thingsboard Dashboard"  />
</p>
<h2 id="rust-and-esp32">Rust and ESP32</h2>
<p>Rust programming language has attracted the attention of many companies today. This language allows programmers to write safe programs with concepts such as Ownership and Borrowing and new programming structures. During compilation, this language can guarantee that your program will not encounter many types of errors that were common in older languages such as C.
Espressif has designed a framework for programming its microcontrollers, which includes a set of libraries written in C and other tools written in Python. This framework is called <a href="https://github.com/espressif/esp-idf"   target="_blank">esp-idf</a>, and there is a tutorial on how to install and start working with it on the company&rsquo;s website. This framework provides programmers with all the tools needed to set up a project in C language and easily use different parts of the microcontroller including Wifi and Bluetooth.</p>
<p>Over the last few years, the company has started a movement to make it possible to use esp-idf, which is written in C, in the Rust language using FFI, or Foreign Function Interface. Using FFI, code written in one language can be called in another language and its return value can be retrieved. All the work done in this regard is in the <a href="https://github.com/esp-rs"   target="_blank">esp-rs</a> repository and the development of all these programs is done as open source on Github.</p>
<p>At the time of writing this, two categories of programs are being developed:</p>
<ul>
<li>Programs that are completely written in Rust and are so-called bare-metal. That is, they are very close to hardware and do not need Rust&rsquo;s standard library. Like: <a href="https://github.com/esp-rs/esp-hal"   target="_blank">esp-hal</a></li>
<li>Programs that use the esp-idf API through FFI instead of implementing everything from scratch in Rust. These programs must use the Rust standard library because they use functions needed to communicate with C and esp-idf, and therefore require std. For example: <a href="https://github.com/esp-rs/esp-idf-hal"   target="_blank">esp-idf-hal</a></li>
</ul>
<p>Using the first category is almost impossible due to the immaturity and lack of preparation of many APIs required in industrial work. So currently, most people use the second category, which is based on the tested and advanced esp-idf framework. <a href="#1"  >[1]</a></p>
<h2 id="software-packages-needed-for-rust-development-on-esp32">Software Packages Needed for Rust Development on ESP32</h2>
<p>In the Rust language, a crate is the smallest unit recognized by the Rust compiler. In general, crates can be considered a software package or a project.
The following packages are used in developing Rust applications with esp-idf:</p>
<ul>
<li><a href="https://github.com/esp-rs/embedded-hal"   target="_blank">embedded-hal</a>: This package contains a set of programming interfaces or traits for using HAL in embedded environments and does not include any code related to a specific microcontroller.</li>
<li><a href="https://github.com/esp-rs/esp-idf-hal"   target="_blank">esp-idf-hal</a>: This package is the implementation of embedded-hal for ESP32 microcontrollers through esp-idf.</li>
<li><a href="https://github.com/esp-rs/embedded-svc"   target="_blank">embedded-svc</a>: This package contains a set of programming interfaces or traits for using different services such as wifi, Bluetooth, and httpd in embedded environments and does not include any code related to a specific microcontroller.</li>
<li><a href="https://github.com/esp-rs/esp-idf-svc"   target="_blank">esp-idf-svc</a>: this package is the implementation of embedded-svc for ESP32 microcontrollers through esp-idf.</li>
<li><a href="https://github.com/esp-rs/esp-idf-sys"   target="_blank">esp-idf-sys</a>: This package provides raw and insecure connections to the esp-idf library written in C.</li>
</ul>
<p>Also, since most ESP32 microcontrollers use the Xtensa architecture and this architecture is not supported by default by the Rust compiler and its backend, which is LLVM, Espressif maintains a <a href="https://github.com/esp-rs/rust-build"   target="_blank">fork</a> of the Rust compiler that supports this architecture. To get started, this fork of the Rust compiler must be downloaded and installed.
The rest of the software needed to flash and monitor the microcontroller and other tips can be found in the <a href="https://esp-rs.github.io/book/introduction.html"   target="_blank">Espressif documentation</a> for Rust programming. There is a step-by-step tutorial on how to set up a Rust project in these documents, and it is recommended to read them. <a href="#1"  >[1]</a>
To flash, it is enough to install the espflash program from the tutorial above and use the following command to flash the binary file placed in the project on the microcontroller:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ espflash /dev/ttyUSB0 target/xtensa-esp32-none-elf/release/examples/blinky --monitor
</span></span></code></pre></td></tr></table>
</div>
</div><p>And to create a binary file suitable for OTA use:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ espflash save-image --partition-table partitions_singleapp.csv ESP32 target/xtensa-esp32-espidf/release/sem sem103
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="filesystem">Filesystem</h2>
<p>In order to be able to store and manage a lot of data in the flash memory of the microcontroller, we need a file system. According to our needs, this file system should do three things:</p>
<ul>
<li>Be resistant to power outages. Microcontrollers that are used to monitor the power flow may be interrupted at any moment, and this sudden event should not cause the stored data structures to suffer and the system to be in an unknown state.</li>
<li>RAM memory in microcontrollers is very limited, and regardless of the size of the file in the memory and the number of files, the use of RAM should be constant and not change with the increase of input.</li>
<li>Flash memories have a limited number of write cycles, and if a physical part of the flash is written a large number of times (usually 10,000 to 100,000 times), that part will be damaged. Therefore, the file system must take care to use all memory blocks to spread the depreciation over all blocks.
After my research, I have come to the conclusion that there are generally three file systems used for flash memory in microcontrollers. These three file systems and the NVS method, which stores values in memory as key and value pairs and is not considered a file system, have been compared together. <a href="#2"  >[2]</a></li>
</ul>
<p><a href="https://github.com/pellepl/spiffs"   target="_blank">SPIFFS</a> and <a href="https://github.com/littlefs-project/littlefs"   target="_blank">LittleFS</a> seem to be good options. Examining the repository related to SPIFFS, we find that there is not much development for this file system and the project is almost abandoned. But LittleFS shows a lot of potential.
LittleFS is constantly being developed and has a fairly large community behind it. The MicroPython project also uses this file system by default. This relatively new file system uses the Copy-on-Write method, in the simplest case, it works in such a way that when a branch is changed in the file system tree, the whole branch is copied somewhere else and then the change is applied. The previous branch is marked deleted by changing a flag that indicates it no longer has the correct value. With this method, there is no need to erase the memory unnecessarily and use flash memory writing cycles, and you can also make sure that if a problem occurs during writing or the power is cut off, because the values are copied before changing, the original values will not be tampered with. They remain valid until the write is complete. It should be noted that many optimizations are used in this file system to improve the efficiency of the COW method, the details of which are available in the project documentation. <a href="#3"  >[3]</a></p>
<p>This file system is not suitable for situations where it is necessary to change the middle of a large file, because since the entire file is copied before the change, the entire memory space may be filled due to this copy and the continuation of the file may have problems. But this problem does not exist if we just add something to the end of the file. But it is still generally better to avoid increasing the size of each file, which we will do with the sharding method.</p>
<h2 id="measuring-current-and-voltage-using-sct-sensors">Measuring current and voltage using SCT sensors</h2>
<p>These sensors are connected as a clip around the current carrying wire. The current inside the wire passes through a thick metal ring inside the clip and induces a current inside this ring. Another coil with a specific number of turns is connected to the metal ring, and when a current is induced in the big ring, another current proportional to it is induced in the coil; This ratio is determined by the number of coil turns. So if, for example, 100 amps are passed through the desired wire, depending on the number of small coil loops, the output current of the sensor can be something like 10 milliamps. <a href="#6"  >[6]</a>
To read the output of the sensors, they are connected through a 3.5 mm jack converter to the pins of the microcontroller that have ADC capability. Since we are going to be working with city AC power, we can calculate the RMS current and voltage using readings from several sensor outputs. The point that should be noted is that the ADC output is a positive number between 0 and n depending on its resolution, and therefore it is necessary to find the middle of the sine wave corresponding to the electric current and subtract it from the whole wave to get our numbers. around 0. This number to be subtracted is known as the DC offset, which is shown below. <a href="#7"  >[7]</a></p>
<p><img loading="lazy" src="./assets/img/7-wave.jpg#center" alt="Sine Wave"  />
</p>
<p>The algorithm:</p>
<ul>
<li>First, we find the middle value of the voltage in a loop. This is easily done by having the maximum value that the ADC can output.</li>
<li>Then, in another loop, we continuously read the voltage and current values until the time ends or a certain number of passes through the middle of the wave has been done, then we apply a low-pass filter, and finally, collect the readings in the necessary variables. During this time, we store the minimum and maximum value read for current and voltage, and after the loop is finished, we improve the offset value, which is the middle value in the wave.</li>
<li>At the end, we calculate the RMS values for voltage and current and get the real and apparent energy and kwh. You get the kwh value cumulatively; That is, when the corresponding function is called, the kwh values are added together and whenever we reach an hour, the kwh value will have the correct value for that hour.</li>
</ul>
<h2 id="using-littlefs-in-rust">Using LittleFS in Rust</h2>
<p>To use LittleFS in the esp-idf environment, you can use the <a href="https://github.com/joltwallet/esp_littlefs"   target="_blank">esp-littlefs</a> project. As in normal C projects, you can add this package as a component to your project and use standard C functions to work with the file in the system.
But to use esp-little in Rust, you need the help of esp-idf-sys. In the Rust project settings, we specify that when compiling the program, it should create the necessary binding to use this file system in Rust.</p>
<h2 id="sharding">Sharding</h2>
<p>As explained earlier, using large files to write to LittleFS is not highly recommended; Therefore, instead of having a large file in the system that will be written into for months which reduces the system&rsquo;s performance, we can use sharding to solve this problem. In this way, a fixed size is set for each file, and if the size exceeds that limit when writing, a new file will be created and the system will write the values in that new file from then on. This method is also widely used in databases to avoid handling large files. <a href="#9"  >[9]</a></p>
<h2 id="dealing-with-power-outages">Dealing with power outages</h2>
<p>The hardware that we had at hand did not include a separate RTC module and it was not possible to make any changes to the hardware. Therefore, since the timestamps related to the readings are recorded in the device, to improve the error caused by power failure, the microcontroller periodically stores its RTC value in the flash memory and every time it starts working, the stored RTC value is read from the memory and is set as the system clock. After setting the clock, it appends the RTC value read from the memory in a file called powerloss_log.
When receiving values from the microcontroller by the mobile application, the list of power failure events is also sent, and the mobile application tries to correct the timestamp of the data as much as possible by calculating the total duration of the power failure experienced by the microcontroller.</p>
<h2 id="rust-program-routine">Rust program routine</h2>
<p>At the beginning of the program, we launch the file system. This setup will format the LittleFS partition for the first time and only mounts it the next time.
The Rust program is executed as a Task in the FreeRTOS operating system that esp-idf uses, and other tasks such as handling requests by the web server are done in other tasks. Therefore, since the microcontroller that I was using has more than one core, it is possible to run the main Rust code in parallel with the code related to the web server handlers. Thus, to prevent data race, a Mutex can be used for all operations that need to work with the file system. In the next step, we create a mutex with the LittleFS handle behind it.
It then finds the latest shard to store readings in and executes the RTC and power-down routines discussed earlier.
In the next step, the wifi system is set up. In this step, Micro sets up an access point; The SSID of this access point also includes the MAC address of the micro, so when several micros are together, they can still be distinguished individually.
After that, the web server and all its handlers are started and registered, and then the ADC microsystem is started. Web server handlers are explained in more detail below.
In the next part, after making sure that the above steps are started, the firmware version that is currently running is confirmed. This is to ensure the correct OTA update. For example, if a wrong update is done through OTA and the initial setup fails or the micro is reset due to an error because the current version is not verified, the micro will automatically go to the previous version that worked properly.
In the final stage, the micro enters a loop that periodically reads and aggregates the values from the sensor, and stores the aggregated values in the memory after one hour.</p>
<h3 id="webserver">Webserver</h3>
<p>After running the web server, the following handlers are registered in it:</p>
<ul>
<li>/telemetry: the data of all shards are sent to the requester in binary form and in HTTP chunk format.</li>
<li>/powerloss_log: All data related to power loss is sent to the requester.</li>
<li>/time: The new clock is received in UNIX epoch time format and RTC is set with it.</li>
<li>/token: if the request is a GET, the current token is sent, and if it is a POST, the sent token is stored in the current token array. The use of the token is explained below.</li>
<li>/reset: All information except time is erased from the memory.</li>
<li>/ota: The data concerning to the new version of the program is received as a chunk and placed in the next OTA partition. If the binary file is received correctly, the new partition will be set as a bootable partition in the OTA header. OTA update happens only when the received version is higher than the current version.</li>
<li>/version: Sends the current version to the requester.</li>
</ul>
<h2 id="flash-memory-partitioning">Flash memory partitioning</h2>
<p>The file below is given as a partition table to the software that flashes the program to create the partitions in the flash memory:</p>
<pre tabindex="0"><code class="language-config" data-lang="config">## Name, Type, SubType, Offset, Size, Size in Bytes
nvs, data, nvs, 0x9000, 0x4000, 16k
otadata, data, ota, 0xd000, 0x2000, 8k
phy_init, data, phy, 0xf000, 0x1000, 4k
ota_0, app, ota_0, 0x10000, 1M, 1M
ota_1, app, ota_1, , 1M, 1M
littlefs, data, spiffs, , 0x1e0000,1.9M
</code></pre><p>As you can see, two partitions are considered for OTA; Each time a new program is downloaded as a binary file, one of the OTA partitions is used. The otadata partition specifies which partition the bootloader should run from during boot.
nvs partition is used for wifi and phy_init partition is used for the physical layer and radio. Finally, the littlefs partition corresponds to the littlefs file system where data is stored. <a href="##5"  >[5]</a></p>
<h2 id="thingsboard-platform">Thingsboard platform</h2>
<p>Thingsboard is one of the most famous Internet of Things platforms that is completely open source and is used all over the world. Installation and commissioning of Thingsboard server were done through docker on a VM created in proxmox.
Thingsboard can be used for:</p>
<ul>
<li>Device management</li>
<li>Receive and store data that devices send</li>
<li>Process data from devices and perform various tasks based on that data, such as sending an email or running a piece of code.</li>
<li>Displaying data on different graphs</li>
<li>Creating and launching firmware updates through OTA</li>
<li>Creating different user accounts with different access levels</li>
<li>And …
Devices in this platform have names and descriptions, and each device is given a unique access token when it is created. Devices can send their data directly to the server with their token to the following endpoint in a specified format:</li>
</ul>
<pre tabindex="0"><code>http://&lt;server-address&gt;/api/v1/&lt;token&gt;/telemetry
</code></pre><p>Each device is also located in a profile; Profiles are used to separate and group devices that perform the same task and must be managed together. For example, when using OTA update, we can present a new version of the binary file uploaded to the server to all devices that are in a profile, or when drawing a graph, we can display the data of all devices that are in a specific profile. <a href="#4"  >[4]</a><a href="#8"  >[8]</a></p>
<h2 id="thingsboard-flutter-mobile-app">Thingsboard Flutter mobile app</h2>
<p>Thingsboard also has a mobile app written with the flutter framework called <a href="https://github.com/thingsboard/flutter_thingsboard_app"   target="_blank">thingsboard_flutter</a>, which allows users to view and interact with their dashboards and see graphs of device data. One of the things that were done, and we will talk about it further, is to fork this program and add the ability to collect offline data from devices and send it to the server. In the figure below, you can see a view of the added tab called collect:
<img loading="lazy" src="./assets/img/1-mobile-preview.jpg#center" alt="Mobile Preview"  />
</p>
<h3 id="scan-nearby-access-points">Scan nearby access points</h3>
<p>The <a href="https://github.com/flutternetwork/WiFiFlutter/tree/master/packages/wifi_iot"   target="_blank">wifi_iot</a> library is used to scan and find nearby devices. This library can return the list of all nearby APs and connect to the requested AP by giving it an SSID. By default, the SSID of all devices with <code>SEM-</code> in the beginning is displayed, and therefore it is easy to display only the APs related to the required devices from the list of all nearby APs. Finally, the user can connect to the desired AP by clicking on it.</p>
<h3 id="initial-setup-of-the-device">Initial setup of the device</h3>
<p>After connecting to the device&rsquo;s AP and before doing anything else, three things need to be done with the device:</p>
<ul>
<li>The token related to the device representation on the server should be given to the device. With this, every time the mobile application wants to get data from a device, it also gets the token and stores it in its database. To copy the token, a section has been added in the Devices tab through which users can click on the desired device and copy the corresponding token. After copying the token, it can be pasted into the field specified during the initial startup of the device.</li>
<li>Send the current time in UNIX epoch time format to the device to update its RTC. If you are connected to the Internet, this time is taken online, and otherwise, the time of the mobile phone itself is used.</li>
<li>The memory of the device should be reset to make sure that no unwanted data remains in the memory.
Finally, a record is created in the database for this device that associates the SSID of the AP we are connected to to the device token. Also, the timestamp of the last connection to this SSID is also recorded in this record. With this, for example, when scanning, we can separate all the devices that we have connected to in the last 10 minutes with a different color.</li>
</ul>
<h3 id="receiving-data-from-the-device">Receiving data from the device</h3>
<p>To receive information from the device, the following procedure is performed:</p>
<ul>
<li>First, the device token is taken.</li>
<li>Then all the information about the readings is taken from the device.</li>
<li>The updated time is sent to the device.</li>
<li>A list of all power outage events is taken.</li>
<li>Binary readings are converted to their corresponding objects.</li>
<li>The difference between the time of the last data sent and the current time indicates the amount of power outage. If this amount is more than one hour, we divide it by the number of power outage events; The obtained number should be placed in the places where there is a power outage, which we obtain using the power outage event.</li>
<li>Finally, the readings are stored in the mobile database and a request is sent to reset the device&rsquo;s memory.</li>
</ul>
<h3 id="er-diagram-and-database-architecture">ER diagram and database architecture</h3>
<p>The ER diagram of the database used in mobile is as follows:
<img loading="lazy" src="./assets/img/5-database.jpg#center" alt="ER Diagram"  />
</p>
<p>As you can see, all the devices are placed in the devices table. The token given to each device is a combination of the access token and its device profile id on the thingsboard server. So after connecting to a device, its token is first taken and placed in this table along with its SSID. This feature has been added so that after connecting to the Internet and entering the All Devices section of the mobile app, the name assigned to each device on the server is added to this database; This is actually a link between a device&rsquo;s SSID and its name on the server, which can be used to display each device&rsquo;s name next to it when scanning for APs.
<img loading="lazy" src="./assets/img/4-green.jpg#center" alt="Mobile Preview"  />
</p>
<p>The last_checked field shows the time of the last time the mobile phone was connected to the device. If this time is less than ten minutes ago, when scanning for APs, the corresponding AP of the device will turn green to make it easier for the user to identify which device to connect to in the next step.</p>
<h3 id="perform-ota-via-mobile">Perform OTA via mobile</h3>
<p>The ota table is for managing otas and their binary files. Every time the user enters the Devices tab, the mobile application automatically checks through the server whether there is a new OTA update for the devices registered in the mobile database, and if there is, it downloads it.
OTA updates work based on the device profile, and when checking for OTA, it is checked that the version on the server is greater than the version stored on the device, and if it is, the new version is downloaded and replaces the previous version.
When connecting to the device, the program version of the device and its device profile id are taken first, and if there is a newer update file for it, the user can update the device by selecting the Update Device Firmware option.
<img loading="lazy" src="./assets/img/3-ota.jpg#center" alt="OTA"  />
</p>
<h3 id="sending-readings-to-the-server">Sending readings to the server</h3>
<p>By selecting the Sync With Server option, the user can send readings related to any device stored in their database to the server. This is possible because in the mobile database, all access tokens of the devices are also stored, and as mentioned earlier, to send the readings to the server, it is enough to send the data in the specified format to the following address:</p>
<pre tabindex="0"><code>http://&lt;server-address&gt;/api/v1/&lt;token&gt;/telemetry
</code></pre><h2 id="display-data-on-the-server-side">Display data on the server side</h2>
<p>To display data on the thingsboard server, we need to design a dashboard so that the graph of all the devices that are in the SEM profile can be displayed on this dashboard. The designed charts are:</p>
<ul>
<li>Pie chart to compare the total energy consumption of devices</li>
<li>Three graphs to display kwh in time intervals: hourly, daily and monthly</li>
<li>Graph of average hourly current and voltage consumption (the voltage value is constant)
Below is an image of the designed dashboard:
<img loading="lazy" src="./assets/img/2-thingsboard-iot.jpg#center" alt="Thingsboard Dashboard"  />

<img loading="lazy" src="./assets/img/22-thingsboard-iot.jpg#center" alt="Thingsboard Dashboard"  />
</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>I have implemented an Internet of Things platform for power consumption monitoring based on ESP32 processors and Thingsboard server. One of the main problems that current IoT systems have is the need to constantly connect to a server or gateway; My method solves this problem by means of mobile application and using the AP capability of ESP32 microcontrollers with emphasis on offline operation. In this way, the mobile application acts as a gateway that connects to the devices and receives their data. In the future, an autopilot mode can be created for the mobile app to collect data from devices automatically; Of course, this is not possible in the Android operating system because applications do not have the right to do this without notifying the user and approving the application.</p>
<h2 id="references">References</h2>
<ul>
<li><span id="1">[1]</span> <a href="https://esp-rs.github.io/book/introduction.html"   target="_blank">esp-rs book</a></li>
<li><span id="2">[2]</span> <a href="https://docs.espressif.com/projects/espressif-esp-iot-solution/en/latest/storage/file_system.html"   target="_blank">Espressif Documentations about file systems.</a></li>
<li><span id="3">[3]</span> <a href="https://github.com/littlefs-project/littlefs/blob/master/DESIGN.md"   target="_blank">LittleFS Design Guide.</a></li>
<li><span id="4">[4]</span> <a href="https://thingsboard.io/docs/reference/http-api/"   target="_blank">Thingsboard Documentation.</a></li>
<li><span id="5">[5]</span> <a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html"   target="_blank">Espressif Documentation about partition tables.</a></li>
<li><span id="6">[6]</span> <a href="https://learn.openenergymonitor.org/electricity-monitoring/ac-power-theory/arduino-maths"   target="_blank">Open energy monitor guides.</a></li>
<li><span id="7">[7]</span> <a href="https://docs.espressif.com/projects/esp-idf/en/v3.3/api-reference/peripherals/adc.html"   target="_blank">Espressif Documentation About ADC.</a></li>
<li><span id="8">[8]</span> <a href="https://thingsboard.io/docs/user-guide/telemetry/"   target="_blank">Thingsboard Documentation for Sending Telemetry Data.</a></li>
<li><span id="9">[9]</span> <a href="https://en.wikipedia.org/wiki/Shard_%28database_architecture%29"   target="_blank">Sharding methods.</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Screen Sharing in Linux on Unsupported Platforms</title>
      <link>https://moslehian.com/posts/2022/1-screen-sharing-linux/</link>
      <pubDate>Wed, 21 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://moslehian.com/posts/2022/1-screen-sharing-linux/</guid>
      <description>A lot of conferencing or chatting platforms do not have a native Linux client and do not allow you to share your screen through their web apps either. An example of such a platform is Adobe Connect.
You could use Wine (vanilla wine or a wrapper like lutris, bottles, playonlinux, and etc.) to install the native client and share your screen that way, but sometimes getting that to work is just way too much of a hassle.</description>
      <content:encoded><![CDATA[<p>A lot of conferencing or chatting platforms do not have a native Linux client and do not allow you to share your screen through their web apps either. An example of such a platform is <a href="https://www.adobe.com/products/adobeconnect.html"   target="_blank">Adobe Connect</a>.</p>
<p>You could use Wine (vanilla wine or a wrapper like lutris, bottles, playonlinux, and etc.) to install the native client and share your screen that way, but sometimes getting that to work is just way too much of a hassle.</p>
<p>Here are two ways that I managed to share my screen on Adobe Connect and other platforms that don&rsquo;t have a native linux client:</p>
<h2 id="virtual-camera">Virtual Camera</h2>
<p>If there is a web app available and it allows you to share your webcam (like Adobe Connect), here&rsquo;s how you can use this feature to share your screen on the web app using a virtual camera.</p>
<p>1. Install <a href="https://obsproject.com/"   target="_blank">OBS Studio</a>. I highly recommend installing it via the official <a href="https://flathub.org/apps/details/com.obsproject.Studio"   target="_blank">Flatpak</a> package, mainly because the binaries provided by various distributions are sometimes compiled with certain features turned off and are not always up to date.</p>
<p>2. Since version <a href="https://github.com/obsproject/obs-studio/releases/tag/26.1.0"   target="_blank">26.1</a> OBS supports built-in Virtual Camera output on Linux. In order to use it, you have to install the <a href="https://github.com/umlaeute/v4l2loopback"   target="_blank">v4l2loopback</a> module. (depending on your distribution you may want to use <a href="https://wiki.archlinux.org/title/Dynamic_Kernel_Module_Support"   target="_blank">DKMS</a>). You need to find out how you can install this module for your distribution (you can also build it yourself).
This could be as simple as:</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo pacman -Syu v4l2loopback-dkms
</span></span></code></pre></td></tr></table>
</div>
</div><p>for Arch-based distros,</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install -y v4l2loopback-dkms
</span></span></code></pre></td></tr></table>
</div>
</div><p>for debian-based distros, or</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>boot<span style="color:#f92672">.</span>kernelModules <span style="color:#960050;background-color:#1e0010">=</span> [ <span style="color:#e6db74">&#34;v4l2loopback&#34;</span> ];
</span></span><span style="display:flex;"><span>boot<span style="color:#f92672">.</span>extraModulePackages <span style="color:#960050;background-color:#1e0010">=</span> [ config<span style="color:#f92672">.</span>boot<span style="color:#f92672">.</span>kernelPackages<span style="color:#f92672">.</span>v4l2loopback<span style="color:#f92672">.</span>out ];
</span></span></code></pre></td></tr></table>
</div>
</div><p>for NixOS.</p>
<p>After the installation, you need to make sure that the <code>v4l2loopback</code> module is loaded.</p>
<p>3. Now open OBS Studios. You should see a <code>Start Virtual Camera</code> button. If you don&rsquo;t see such a button, open OBS using a terminal, read the log messages, and diagnose why OBS can&rsquo;t enable its virtual camera functionality.</p>
<p><img loading="lazy" src="./assets/01-virt-cam-button.jpg#center" alt="OBS Virtual Camera"  />
</p>
<p>4. Create a <code>Scene</code> and add a <code>Screen Capture</code> source to it. Then, start the virtual camera.</p>
<p>5. Join a webinar using a browser (I use <code>Firefox</code>. Some people have reported that their virtual cameras don&rsquo;t show up on chromium-based browsers).
Either get the host to make you a host as well or ask them to do the following:</p>
<ul>
<li>Go to <code>Preferences -&gt; Video</code> and change the aspect ratio to <code>16:9</code>.</li>
</ul>
<p><img loading="lazy" src="./assets/02-preferences-aspect-ratio.jpg" alt="Aspect Ratio"  />
</p>
<ul>
<li>Create a new layout and add your desired pods to it along with a large video pod.</li>
</ul>
<p><img loading="lazy" src="./assets/03-video-layout.jpg" alt="Layout"  />
</p>
<p>6. Click on the webcam button and allow the site to use your virtual camera.</p>
<p><img loading="lazy" src="./assets/04-select-webcam.jpg" alt="webcam"  />
</p>
<p>7. Click on <code>Start Sharing</code> to share your screen.</p>
<p><img loading="lazy" src="./assets/05-start-share.jpg" alt="share"  />
</p>
<blockquote>
<p>You can control the output resolution of OBS in its settings. Turning down the resolution may help reduce the needed bandwidth to stream your desktop.</p>
</blockquote>
<h2 id="virtual-machine">Virtual Machine</h2>
<p>If there are no web apps, you can use a Windows virtual machine to share your Linux desktop. This is a little bit more involved and requires more resources.
Here is the basic idea:</p>
<p>1. Create a Windows guest VM
I use <a href="https://libvirt.org/"   target="_blank">libvirt</a> managed by <a href="https://virt-manager.org/"   target="_blank">virt-manager</a>.</p>
<p>2. Install Adobe Connect in the VM</p>
<p>3. Install a remote desktop sharing client in the VM (e.g. <a href="https://tigervnc.org/"   target="_blank">TigerVNC</a>)</p>
<p>4. Make sure there is network connectivity between the guest VM and host (the default NAT is okay)
You need the IP address of the host machine in the virtual network. You can do a simple
<code>ip a</code>
on the host machine to find the IP address of the interface connected to the virtual network.</p>
<p>5. Install a remote desktop sharing server in the host (e.g. VNC Server, TigerVNC)
I use <a href="https://tigervnc.org/"   target="_blank">TigerVNC</a>. First, create a password using <code>vncpasswd</code> and then run
<code>x0vncserver -PasswordFile=.vnc/passwd</code>
to start a VNC server connected directly to your running x-server without creating a virtual desktop.</p>
<p>Now you can share the screen of your Windows guest in a webinar and connect to the VNC server on the host machine using its IP address in the virtual network and share the screen of your Linux machine through the Windows VM.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
