Starting with RUST Programming

Rust: A memory safe Systems Programming Language
rustup: An installer for the systems programming language Rust
cargo: Rust’s package manager and build system

Rust Installation

1. Installing rustup:
$ curl https://sh.rustup.rs -sSf | sh

– info: latest update on 2019-08-15, rust version 1.37.0
– info: downloading component ‘rustc’
– Rust is installed now. Great!

– The installation script automatically adds Rust to the system PATH after the next login.
– To start using Rust right away instead of restarting the terminal:
$ source $HOME/.cargo/env

OR

– Add the PATH to your bash file ( ~/.bash_profile )
$ export PATH=”$HOME/.cargo/bin:$PATH”

2. Version check
$ rustc –version

=> rustc x.y.z(abcabcabc yyyy-mm-dd)

3. Check the PATH system variable to ensure that RUST is present
$ echo $PATH
=> $HOME/.cargo/bin. ( You should see this directory in the PATH )

4. Rust Local Documentation
$ rustup doc

5. Updating Rust
$ rustup update

6. Uninstalling Rust and rustup
$ rustup self uninstall
Customary Hello World Program:

1. Creation of a project directory to store the Rust code

$ mkdir ~/RUST/projects
$ cd ~/RUST/projects
$ mkdir hello_world
$ cd hello_world/

2. Writing the first program
– Rust files always end with “.rs” extension
– File naming convention : abc_def_gh.rs
– Example: hello_world.rs

– Create a new src file : hello_world.rs

fn main() {
    println!(“Hello world!”);
}

3. Compiling the code:
$ rustc hello_world.rs

4. Running the code:
$ ./hello_world

Parts of a Rust Program:

1. fn main() { } :

  • Defines a function main in Rust. main function is special and it is the one that runs first in every Rust executable program
  • Declaring a function named main that has no parameters and returns nothing
  • Parameters if needed to be passed then they go inside the parentheses ()
  • Function body is wrapped in curly brackets {}

2. println!(“Hello world!”);

  • Calls a Rust macro
  • Function call would have been println ( without !)
  • Using ! implies calling a macro instead of a normal function
  • String “Hello world!” is being passed as an argument to macro println!
  • The line ends with a semicolon(;), similar to C language

3. rustc hello_world.rs

  • Invoking Rust compiler on hello_world.rs to obtain the executable
  • Generates hello_world executable file ( can be seen with “ls -l” command )

4. ./hello_world
– Running the executable code

Stepping through Code

As the code goes on changing with time by various different programmers working on the same source code, the chances of code getting broken, increases. So the best way to ensure bug-free code is to actively step through the new or modified code as soon as it is written.  Stepping and watching the code execute line by line verifies that every instruction getting executed does what it is intended for. The major issue is that we programmers think that stepping through the code is a time-consuming process and we skip it thinking that the unit tests or other tests written by us or any other programmer for the code will make sure the code works, but we don’t realize that investing a little bit more time during development of code can save us a lot of time debugging the issues later on in the production code.

Earlier I had the same attitude about the code development and relied a lot on unit tests for the code coverage and raise the alarms on breakages of it whenever it gets changed by me or anyone in future instead of stepping through the code at the time of writing or modifying and making sure the integrity and the exact behaviour of the program.

First thing which we should make sure is that each line of new code or modified code gets executed by the tests which we add or already exists, since many a time it happens that even the CPU control does not reach the code line which we have modified or added because of some condition getting or not getting satisfied. Few examples are like dual code path operators ( &&, ||, ?: ), if else, exception handling code.

So learning from our mistakes of bugs getting skipped, we should always put the breakpoints in the code, step through it, and watch the input data getting transformed into the output. The best moment to catch bugs is to look for them the moment we write or change code.

Make the following your new motto when writing code “Don’t wait to step through the code until the bug gets cropped up”.

Either we can write test cases to cover each and every code path flow to make sure the code is bug-free but if it is not possible then at least we should simulate all possible code path by stepping through the code.

gdb ( GNU Debugger ) is the best open source debugger for C and C++ code. There are a lot of descriptive tutorials on the internet on gdb to look out for. One of the following is:

Click to access gdb-tutorial-handout.pdf

 

 

 

 

 

Catching the double code path bugs

As the size and complexity of software are increasing, there is a need to catch the bugs as soon as possible in the development phase itself, in order to provide more reliable and bug-free code to the customers. So this article is about one kind of bugs which get skipped by the programmers because we the programmers don’t step through the code line by line and only rely mostly on the test code we wrote, which not always cover the complete code.

This article focuses on few C operators that provides two code paths like &&, || and ?: operators and the resulting bugs that get skipped without proper testing of the two code paths.

Since many times, our tests don’t simulate all the scenarios and all the code paths don’t get tested. So we need to be careful with such code segment which results in two different code paths and try to add test scenarios so that both of the paths get tested but in order to make sure we never get skip with these bugs, we should always step through code in a source code debugger like gdb.

In the debugger, we should force the program control to pass through each possible path but we need to pay a bit more attention that since the source code debuggers steps through both paths of the &&, || and ?: operators in a single step.

 

 

PFC ( Priority Flow Control )

In this article, I will be explaining the need for the Priority Flow Control, an advanced flow control mechanism with use of very basic and limited Networking concepts and jargon.

Semantics at Ethernet Medium

As the traditional ethernet medium ( Layer 2 ) provides an unreliable communication medium, it’s up to the upper layer protocols to handle drop-detection and retransmission logic. But not all applications builds reliability on upper layers, so there is a need to have a kind of flow control mechanism at Layer 2 to provide them with reliability.

Causes of Unreliability  in a network

Since a network path consists of multiple hops between the source and the destination, lack of feedback between the transmitter and the receiver at each hop becomes a major source of unreliability in the network. Transmitters send packets faster than the receivers can absorb them, and therefore the available receive buffers get exhausted resulting in the silent drop of traffic.

To avoid the incoming traffic flow packets to get silently dropped, there arises a need of a flow control mechanism.

Flow Control Mechanism

Flow control provides a feedback mechanism for a receiver to its sender to communicate the dynamic buffer availability. The first implementation of flow control was the use of PAUSE control frames. If simply put, a receiver generates a MAC control frame ( PAUSE frame ) and sends it to a sender when it predicts a potentiality of overflowing of the buffer. And the sender, upon receiving the PAUSE frame responds by stopping the transmission of packets until the receiver again notifies the sender to send packets. Everything good up to this point, until we realize that after a link is paused by the receiver by sending the PAUSE frame,  the sender cannot send any packets on the link. All traffic flows passing through that link gets stopped completely, irrespective of them belonging to different flows requiring different quality of service ( QoS ). Thus enabling PAUSE for one of the application will result in the performance hit of all the applications.

So the solution to the above problem of not differentiating flows requiring different QoS is dealt by the PFC ( Priority Flow Control ).

PFC

So PFC extends the functionality provided by the PAUSE frame and extends it to multiple Class of Services ( CoS ).  PFC uses the CoS values in the VLAN tags to differentiate up to 8 CoSs that can be subjected to flow control independently.

So the receiver can just simply ask the sender to stop the traffic for a particular CoS, unaffecting the transmission of other CoS frames.

Both PAUSE and PFC control frames are MAC frames ( L2 frames ) with same protocol type 0x8808 ( EtherType ) but different protocol subType. The receiver can put the duration of pause time ( numeric value ) which gets translated to time on the sender side depending on the current network speed. Since PFC acts independently on 8 different CoSs, the PFC frame describes the pause duration for each CoS.

A Pause duration of zero implies unpausing a CoS to the sender.