fork download
  1. #include <stdio.h>
  2.  
  3. struct NormalContext {};
  4. struct InterruptContext {};
  5.  
  6. template <typename Context>
  7. struct LockHelper {
  8. template <typename Func, typename... Args>
  9. static void call (Func f, Args... args)
  10. {
  11. printf("CLI\n");
  12. //cli();
  13. f(InterruptContext(), args...);
  14. //sei();
  15. printf("SEI\n");
  16. }
  17. };
  18.  
  19. template <>
  20. struct LockHelper<InterruptContext> {
  21. template <typename Func, typename... Args>
  22. static void call (Func f, Args... args)
  23. {
  24. f(InterruptContext(), args...);
  25. }
  26. };
  27.  
  28. #define CRITICAL_SECTION(this_context, lock_context, body) \
  29.   LockHelper<decltype(this_context)>::call([&](InterruptContext lock_context) body)
  30.  
  31. template <typename Context>
  32. void function1 (Context c)
  33. {
  34. CRITICAL_SECTION(c, lock_c, {
  35. // do your stuff
  36. // could also call other functions, but use lock_c
  37. // function3(lock_c, ...);
  38. // lock_c is always an InterruptContext() so no cli/sei will be done from inside here
  39. });
  40. }
  41.  
  42. template <typename Context>
  43. void function2 (Context c)
  44. {
  45. function1(c);
  46. }
  47.  
  48. int main ()
  49. {
  50. {
  51. printf("Calling function from NormalContext, this one does CLI/SEI\n");
  52. NormalContext c;
  53. function2(c);
  54. }
  55.  
  56. {
  57. printf("Calling function from InterruptContext, this one doesn't do CLI/SEI\n");
  58. InterruptContext c;
  59. function2(c);
  60. }
  61. }
  62.  
  63.  
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
Calling function from NormalContext, this one does CLI/SEI
CLI
SEI
Calling function from InterruptContext, this one doesn't do CLI/SEI