/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef INCLUDE_ECXX_PLATFORM_SPECIFIC_ATOMIC_GUARD_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_SPECIFIC_ATOMIC_GUARD_H


#ifndef ECXX_PLATFORM_AVR_COMMON_ATOMIC_GUARD_H
#define ECXX_PLATFORM_AVR_COMMON_ATOMIC_GUARD_H


#include <eCxx/CTL/UninstantiableUncopyable.h>


namespace eCxx {


//
// A simple atomic guard
//
class AtomicGuard : public Uncopyable {
    public:
        inline AtomicGuard() __ECXX_ATTR_ALWAYS_INLINE
        {
            __asm__ __volatile__ (
                "in %0, __SREG__ \n\t"
                "cli             \n\t"
                : "=r"(_state)
                :
                : "memory"
            );
        }

        inline ~AtomicGuard() __ECXX_ATTR_ALWAYS_INLINE
        {
            __asm__ __volatile__ (
                "out __SREG__, %0 \n\t"
                :
                : "r"(_state)
                : "memory"
            );
        }

    private:
        uint8_t _state;
};


} // namespace eCxx


#endif
