rwlock.hpp 2.51 KB
Newer Older
Matthieu Dorier's avatar
Matthieu Dorier committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright (c) 2017 UChicago Argonne, LLC
 *
 * See COPYRIGHT in top-level directory.
 */

#ifndef __THALLIUM_RWLOCK_HPP
#define __THALLIUM_RWLOCK_HPP

#include <abt.h>

namespace thallium {

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/**
 * Exception class thrown by the rwlock class.
 */
class rwlock_exception : public exception {

    public:

    template<typename ... Args>
        rwlock_exception(Args&&... args)
        : exception(std::forward<Args>(args)...) {}
};

#define TL_RWLOCK_EXCEPTION(__fun,__ret) \
    rwlock_exception(#__fun," returned ", abt_error_get_name(__ret),\
            " (", abt_error_get_description(__ret),") in ",__FILE__,":",__LINE__);

#define TL_RWLOCK_ASSERT(__call) {\
    int __ret = __call; \
    if(__ret != ABT_SUCCESS) {\
        throw TL_RWLOCK_EXCEPTION(__call, __ret);\
    }\
}

Matthieu Dorier's avatar
Matthieu Dorier committed
37 38 39 40 41
/**
 * @brief The rwlock class wraps and managed an ABT_rwlock.
 */
class rwlock {

42 43 44
    ABT_rwlock m_lock;

    public:
Matthieu Dorier's avatar
Matthieu Dorier committed
45 46 47 48 49 50 51 52 53

    /**
     * @brief Native handle type.
     */
    typedef ABT_rwlock native_handle_type;

    /**
     * @brief Constructor.
     */
54
    explicit rwlock() {
55
        TL_RWLOCK_ASSERT(ABT_rwlock_create(&m_lock));
56
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
57 58 59 60

    /**
     * @brief Copy constructor is deleted.
     */
61
    rwlock(const rwlock&) = delete;
Matthieu Dorier's avatar
Matthieu Dorier committed
62 63 64 65

    /**
     * @brief Move constructor.
     */
66 67 68 69
    rwlock(rwlock&& other) {
        m_lock = other.m_lock;
        other.m_lock = ABT_RWLOCK_NULL;
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
70 71 72 73 74 75 76 77 78 79 80

    /**
     * @brief Copy assignment operator is deleted.
     */
    rwlock& operator=(const rwlock&) = delete;

    /**
     * @brief Move assignment operator.
     */
    rwlock& operator=(rwlock&& other) {
        if(this == &other) return *this;
81
        TL_RWLOCK_ASSERT(ABT_rwlock_free(&m_lock));
Matthieu Dorier's avatar
Matthieu Dorier committed
82 83
        m_lock = other.m_lock;
        other.m_lock = ABT_RWLOCK_NULL;
Matthieu Dorier's avatar
Matthieu Dorier committed
84
        return *this;
Matthieu Dorier's avatar
Matthieu Dorier committed
85 86 87 88 89
    }

    /**
     * @brief Destructor.
     */
90 91 92
    ~rwlock() noexcept {
        ABT_rwlock_free(&m_lock);
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
93 94 95 96

    /**
     * @brief Lock for reading.
     */
97
    void rdlock() {
98
        TL_RWLOCK_ASSERT(ABT_rwlock_rdlock(m_lock));
99
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
100 101 102 103

    /**
     * @brief Lock for writing.
     */
104 105 106
    void wrlock() {
        TL_RWLOCK_ASSERT(ABT_rwlock_wrlock(m_lock));
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
107 108 109 110

    /**
     * @brief Unlock.
     */
111 112 113
    void unlock() {
        TL_RWLOCK_ASSERT(ABT_rwlock_unlock(m_lock));
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
114 115 116 117 118 119 120 121 122 123 124 125 126

    /**
     * @brief Get the underlying native handle.
     *
     * @return the underlying native handle.
     */
    native_handle_type native_handle() const noexcept {
        return m_lock;
    }
};

} 

127 128 129
#undef TL_RWLOCK_EXCEPTION
#undef TL_RWLOCK_ASSERT

Matthieu Dorier's avatar
Matthieu Dorier committed
130
#endif /* end of include guard */