#ifndef UTL_SYS_CRIT_SECT_H
#define UTL_SYS_CRIT_SECT_H
 #include <stdint.h>
 #include <string.h>    // NULL

 #define CSECT_IMPLEMENTATION_SIMPLE   1
 
 #if CSECT_IMPLEMENTATION_SIMPLE == 0
 struct __sCRITICALSECTION
 {
    const uint32_t __reserved1[1];
    const uint16_t __reserved2[1];
 };

 typedef struct __sCRITICALSECTION xCSect_t;
 typedef struct __sCRITICALSECTION xCSectCnt_t;
 
 void csect_create( xCSect_t * pObj );  // create a critical section
 void csect_delete( xCSect_t * pObj );  // delete a critical section
 void csect_enter( xCSect_t * pObj  );  // enter a critical section
 void csect_leave( xCSect_t * pObj  );  // leave a critical section
 
 void csectcnt_create( xCSectCnt_t * pObj );  // create a counting critical section
 void csectcnt_delete( xCSectCnt_t * pObj );  // delete a counting critical section
 void csectcnt_enter( xCSectCnt_t * pObj  );  // enter a counting critical section
 void csectcnt_leave( xCSectCnt_t * pObj  );  // leave a counting critical section
 #else
   void csect_enter();
   void csect_leave();
   #define disable_interrupt()    csect_enter()
   #define enable_interrupt()     csect_leave()
   #define DI()                   csect_enter();
   #define EI()                   csect_leave();
   #define __DI__                 { csect_enter();
   #define __EI__                 csect_leave(); }
   #define __EI__Return__         {csect_leave(); return;} }
   #define __EI__ReturnArg__(arg) {csect_leave(); return(arg);} }

   // Usage:
   //
   // Use csect_enter/DI and csect_leave/EI as a classical critical section like
   //  you used __disable_interrupt/__enable_interrupt.
   // Or use safe version __DI__/__EI__, that requires to close the scope with __DI__,
   // you can use it as multiline section, or single-line compact section:
   //   __DI__ ...user-command... __EI__
   // or
   //   __DI__
   //      ..user-command-1..
   //      ..user-command-2..
   //      etc
   //   __EI__
 #endif
#endif