Skip to content
This repository has been archived by the owner on Mar 22, 2023. It is now read-only.

Simplify throwing exception mechanism in libpmemobj-cpp #1145

Open
KFilipek opened this issue Jul 8, 2021 · 2 comments
Open

Simplify throwing exception mechanism in libpmemobj-cpp #1145

KFilipek opened this issue Jul 8, 2021 · 2 comments
Labels
Type: Bug Something isn't working Type: Feature New feature or request

Comments

@KFilipek
Copy link
Contributor

KFilipek commented Jul 8, 2021

Generally (comment taken from #1144):

class transaction_out_of_memory : public transaction_alloc_error,
				  public std::bad_alloc {

All of those: transaction_alloc_error -> transaction_error -> std:runtime_error has constructor(const std::string&), but std::runtime_error not, it is designed to not take additional memory (hey, we have OOM, so we should be careful).
Second thing:
throw new transaction_out_of_memory().with_pmemobj_errormsg(); will create 3 objects instead of 1 causing unnecessary object creation during OOM situation.

My point is to make this simply to use and add proper constructors like these in std::runtime_error. std::bad_alloc dosn't have it for known reason.

@KFilipek KFilipek added the Type: Bug Something isn't working label Jul 8, 2021
@igchor
Copy link
Contributor

igchor commented Jul 8, 2021

What exactly do you propose? I don't think there is any problems with creating multiple objects (which most likely will be optimized anway anyway). And we don't need to be so careful about the memory usage since the OOM is from PMEM and std::string comes from dram.

@KFilipek
Copy link
Contributor Author

KFilipek commented Jul 9, 2021

With -O3 still it's not optimized.

Simply as is:

int main() {
    try {
        throw PolymorphicException("Error: ").decorate("Bonjour");
    } catch(const std::exception &e) {
        std::cout << e.what() << std::endl;

    }
}

Can be achieved by such implementation:

class PolymorphicException : public std::runtime_error {
public:
    std::string what_message = "";
    PolymorphicException() : std::runtime_error("") {
        std::cout << "Constructor of: " << this << std::endl;
    }
    PolymorphicException(const std::string &what_arg) : std::runtime_error(what_arg), what_message(what_arg) {
        std::cout << "Constructor of: " << this << std::endl;
    }
    virtual PolymorphicException & decorate(std::string additional_string) {
        what_message += additional_string;
        return *this;
    }
    virtual ~PolymorphicException() {
        std::cout << "Destructor of: " << this << std::endl;
    }

    virtual const char* what() const noexcept {
        return what_message.c_str();
    }
};

Output:

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
Constructor of: 0x7fff4b88d888
Destructor of: 0x7fff4b88d888
Error: Bonjour
Destructor of: 0x1437f30

Notice: 1 derivate object creates whole tree, in libpmemobj-cpp for transaction_out_of_memory you will create:

                    transaction_out_of_memory
                    /                   \
 transaction_alloc_error                std::bad_alloc
                    |                    |
    transaction_error                   std::exception
                    |
    std::runtime_error
                    |
    std::exception (second copy, because we don't use virtual inheritance here)

so, you will create 7 objects, 2-3 times instead of 1.

@lukaszstolarczuk lukaszstolarczuk added the Type: Feature New feature or request label Jul 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Bug Something isn't working Type: Feature New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants