All files / TRANSPILE/3-Render/codegen/helpers InterruptMask.ts

100% Statements 1/1
100% Branches 0/0
100% Functions 1/1
100% Lines 1/1

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37                                              33x                          
/**
 * ADR-050: a region run with interrupts masked, through the `__cnx_` IRQ
 * wrappers -- the one lowering a `critical` block and an atomic
 * read-modify-write on a target without LDREX/STREX share.
 *
 * #1146: the atomic path emitted raw CMSIS names (`__get_PRIMASK()`,
 * `__disable_irq()`) with no platform guard, beside `<cmsis_gcc.h>`, while a
 * `critical` block took the wrappers' ARM, AVR and fallback arms. So on AVR
 * the same masking was SREG in one and CMSIS, which avr-libc does not have,
 * in the other.
 */
import type IGeneratorOutput from "../generators/IGeneratorOutput";
 
class InterruptMask {
  /**
   * `inner` bracketed by saving the mask, disabling interrupts, and
   * restoring the mask; its effect asks for the wrappers.
   *
   * @param inner - The statements run masked, without braces
   * @param line - The construct's source line, for the deferred toolchain
   *   report (Issue #1143), when there is one
   */
  static wrap(inner: string, line: number | undefined): IGeneratorOutput {
    return {
      code: `{
    uint32_t __primask = __cnx_get_PRIMASK();
    __cnx_disable_irq();
    ${inner}
    __cnx_set_PRIMASK(__primask);
}`,
      effects: [{ type: "include", header: "irq_wrappers", line }],
    };
  }
}
 
export default InterruptMask;