129. Write-1-to-Clear Flag Encapsulation

#include <iostream>
#include <iomanip>
#include <cstdint>

class StatusRegister {
private:
    // Simulates the hardware bus write operation
    void busWrite(uint32_t val) {
        std::cout << "Write: 0x" 
                  << std::hex << std::uppercase << std::setw(8) << std::setfill('0') 
                  << val << std::endl;
    }

public:
    void clearFlag(int bit_index) {
        // In Write-1-to-Clear (W1C) logic:
        // Writing '1' clears the bit. Writing '0' has no effect.
        // We must write a mask with a single '1' at the target position.
        
        // 1. Create a mask with a single 1 at bit_index.
        // 1U ensures it's treated as unsigned to avoid undefined behavior on shift
        uint32_t mask = (1U << bit_index);
        
        // 2. Write directly to the bus. 
        // No Read-Modify-Write (RMW) cycle is performed.
        busWrite(mask);
    }
};

int main() {
    int N;
    if (!(std::cin >> N)) return 0;

    StatusRegister driver;

    for (int i = 0; i < N; ++i) {
        int bit_idx;
        std::cin >> bit_idx;
        
        driver.clearFlag(bit_idx);
    }

    return 0;
}

Explanation & Logic Summary: 

The problem enforces the correct handling of "Write-1-to-Clear" (W1C) hardware registers.

  1. The Trap: In standard memory, clearing a bit involves reading the byte, masking out the bit, and writing it back (var &= ~mask). If applied to a W1C hardware register, this read-modify-write cycle reads all currently set flags and writes them back as 1s (since they were read as 1s). This inadvertently clears every pending interrupt, leading to lost events.
  2. The Encapsulation: By hiding the register access behind clearFlag(int index), the class ensures that only the safe W1C operation (writing a single bit mask directly to the bus) is performed.
  3. Implementation: The solution calculates 1U << bit_index to create a value like 0x00000010 (for bit 4) and writes it. Since 0s have no effect in W1C logic, only the intended flag is cleared.

Firmware Relevance & Real-World Context:

  • Interrupt Controllers: Registers like TIMx_SR (STM32) or TIFR (AVR) use W1C to ensure atomic handling of interrupts.
  • Race Conditions: RMW operations on status registers are a primary cause of "ghost" bugs where unrelated interrupts disappear because one ISR cleared them while acknowledging its own.
  • Bus Efficiency: Direct writes avoid the overhead of a read cycle, which is crucial on slower peripheral buses.

 

 

Loading...

Input

3 0 4 31

Expected Output

Write: 0x00000001 Write: 0x00000010 Write: 0x80000000