Friday, June 18, 2021

Programming: Useful C or C++ Repositories


System Design

Consistent hashing implementation using MD5 & RB trees (C++) - GITHUB link

Message queue implementation (C++) - GITHUB

Hilbert space filling curve implementations (C and others) Link


MIT OCW C Course

Univ Wisconsin Madison OS Course

Saturday, May 8, 2021

WiFi: What is phy restart? Why is it important in dense RF environments?

 Phy restart on radio drivers typically means if the hardware (radio) is able to sync to the preamble of a packet which has a stronger signal strength while it is already in the process of decoding a packet.

This is typically useful in noisy environments to achieve a "capture effect", where the stronger packet is finally decoded at the rx. radio. If the radio does not support PHY restart then typically such a reception would result in a collision on the rx-side at the radio.

Friday, May 7, 2021

Linux: What does IRQ save do in Linux?

 ExcerptUse local_irq_save to disable interrupts on the local processor and remember their previous state. The flags can be passed to local_irq_restore to restore the previous interrupt state.

void local_irq_save(unsigned long flags);
void local_irq_restore(unsigned long flags);

The spinlock version will disable interrupts on all the cores*

Monday, May 3, 2021

Linux: Why do we need an executable stack with nested functions in GCC


  • The stack needs to be writable because the trampoline code is written on the stack which needs to be executed (to jump to the nested function). 
A nested function has no linkage by itself. So the trampoline code actually ensures two things:
  1. The outer () functions stack frame is available in the nested function
  2. Jump and execute code from the nested function.
Some other notes:
  • Nested functions are not a part of ANSI C, however, they are part of Gnu C.
  • The only reason nested functions are possibly useful because they use common stack variables.

Friday, April 30, 2021

Math: Simple technique to implement moving averages in Java, C or C++

 The oneline solution is:

accumulator = (alpha * new_value) + (1.0 - alpha) * accumulator

Accummulator - holds the value being tracked
alpha - value between 0 and 1.

The more aggressive the alpha (closer to 1) the  faster the moving average adapts to the recent values. This is an exponential moving average.

Thursday, April 29, 2021

Linux: Poking the ethernet driver with the ethtool

 1. Get basic information about the interface

[mylinuxbox@mylinuxbox-linux ~]$ ethtool -i eth4
driver: e1000e
version: 2.1.4-k
firmware-version: 0.13-4
bus-info: 0000:00:19.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no

2. Dump all the hardware registers
[root@mylinuxbox-linux mylinuxbox]# ethtool -d eth4
MAC Registers
0x00000: CTRL (Device control register)  0x18100240
      Endian mode (buffers):             little
      Link reset:                        normal
      Set link up:                       1
      Invert Loss-Of-Signal:             no
      Receive flow control:              enabled
      Transmit flow control:             enabled
      VLAN mode:                         disabled
      Auto speed detect:                 disabled
      Speed select:                      1000Mb/s
      Force speed:                       no
      Force duplex:                      no
0x00008: STATUS (Device status register) 0x00080083
      Duplex:                            full
      Link up:                           link config
      TBI mode:                          disabled
      Link speed:                        1000Mb/s
      Bus type:                          PCI
      Bus speed:                         33MHz
      Bus width:                         32-bit
0x00100: RCTL (Receive control register) 0x04008002
      Receiver:                          enabled
      Store bad packets:                 disabled
      Unicast promiscuous:               disabled
      Multicast promiscuous:             disabled
      Long packet:                       disabled
      Descriptor minimum threshold size: 1/2
      Broadcast accept mode:             accept
      VLAN filter:                       disabled
      Canonical form indicator:          disabled
      Discard pause frames:              filtered
      Pass MAC control frames:           don't pass
      Receive buffer size:               2048
0x02808: RDLEN (Receive desc length)     0x00001000
0x02810: RDH   (Receive desc head)       0x00000051
0x02818: RDT   (Receive desc tail)       0x00000040
0x02820: RDTR  (Receive delay timer)     0x00000000
0x00400: TCTL (Transmit ctrl register)   0x3003F0FA
      Transmitter:                       enabled
      Pad short packets:                 enabled
      Software XOFF Transmission:        disabled
      Re-transmit on late collision:     disabled
0x03808: TDLEN (Transmit desc length)    0x00001000
0x03810: TDH   (Transmit desc head)      0x0000007A
0x03818: TDT   (Transmit desc tail)      0x0000007A
0x03820: TIDV  (Transmit delay timer)    0x00000008
PHY type:                                unknown

Monday, April 26, 2021

Linux: Nagle's Algorithm and How to Disable it

 Nagle's algorithm is a TCP optimization in the kernel stack that waits to aggregate small chunks of bytes before sending packets on a TCP connection. This approach optimizes the amount of frame overhead spent in sending very small packets over the network. However, when the data is fairly sporadic, this could also lead to an increase in the average delay experienced.

Nagle's algorithm running on a host can be disabled by:
echo 1 > /proc/sys/net/ipv4/tcp_low_latency