vendredi 1 février 2019

What is the modern C++ way of having a constexpr const pointer to a volatile memory location for embedded applications?

In building libraries for controlling hardware on embedded microprocessors, a common task is manipulating bits at specific memory locations for controlling hardware features.

In AVR processors, Atmel (now Microchip) provides macros that expand to something like this:

#define PORTA (*(volatile uint8_t *)(0x25))

Which enables things like:

PORTA |= 1;

Now in C++11 (and newer), it is desirable to replace almost any usage of #define with constexpr.

In older versions of the GCC C++ compiler (4.9.2), the following compiled:

#include <avr/io.h>
constexpr volatile uint8_t *const PortA = &PORTA;

In version 8.2.0, the above does not compile and gives errors:

error: reinterpret_cast from integer to pointer

I'm not looking for explanations of why you cannot use reinterpret_cast inside a constexpr context or why integer to pointer conversion is illegal.

What is the correct way to have a constexpr pointer to volatile memory in modern C++?

I've seen suggestions of storing the memory address of PORTA in a constexpr uintptr_t and then reinterprect_casting that to volatile uint8_t * const at runtime for bit manipulation.

For instance, this works and even compiles to a single sbi instruction in avr-gcc as expected.

#include <stdint.h>
constexpr uintptr_t PortA = 0x25;
void set() { *((volatile uint8_t *)(PortA)) |= 1; }

However it takes a decent amount of ugly boilerplate to use Foo as the pointer it is intended to be.

This also has the problem that it seem to be impossible to use the PORTA macro directly. We're instead forced to hard-code the memory address 0x25 which breaks certain desirable portability features.

It feels like I'm missing something obvious buy my searches have not yielded anything fruitful.

For instance, this feels like an "address constant expression", but that seems to relate to referring to statically allocated const values like which is not quite what I want.

const char str[] = "FooBar";
constexpr const char * x = str + 2;

Initialize a class with an array

I have a class like this:

class MyClass {
    MyClass(double *v, int size_of_v){
        /*do something with v*/
    };
};

My question: Is there any way, I can initialize such class without defining an array of double and feeding it to the constructor?

I would like to do something like:

auto x = MyClass({1.,2.,3.}, 3);

Handle different count of different types in a C++ object

I am trying to write a framework in C++ which will be used by my team to define various processes. A process will be made up of various fundamental steps. Something like this:

Steps = {Step1, Step2, Step3...StepN}

Processes = {ProcessA, ProcessB, ProcessC..ProcessN}

ProcessA = {Step1, Step3, Step5}
ProcessB = {Step3, Step5, Step7}

I am planning that each step will implement an IStep interface which will have a Perform() method. And a process will be a list of steps. In order to complete a process, you would iterate through steps and call the Perform method. The problem is when a step is performed it changes the state of the process. The variables which would define the state of the process are of different types and they are not fixed.

Example of states of a process

Process A
    Pointer to the next empty box (Some pointer)
    Number of cylinders (number)
    Color of the box (string)
Process B
    Process name (string)
    Number of boxes (number)
    Pointer to list of boxes (Some other pointer type)

Had it been a service, I could have stored this information in JSON format. I think what I am looking for is dynamic type like we have in C# (maybe some magic with void pointers but I am not sure if that's the best practice). I read somewhere about using the factory pattern to solve this problem. Is that the best way to do it? Or maybe should I consider changing my design.

difference b/w () and {} when creating objects c++?

Is there any difference in initializing the object with () and {} ?

A simple program

#include <iostream>
#include <string>
using namespace std;

class Demo {
    int n;
public:

Demo(int x): n{x}{
    cout << "Object is initialized by a number: " << n << endl; 
    }
};


int main()
{
   Demo a(4);
   Demo b{3};
}

the output of Demo a(4) and Demo b(3) works same but is there any difference b/w them and which one is efficient to use?

void boost::coroutines::detail::push_coroutine_impl

Subject

This POC app uses Boost ASIO with coroutines to serve HTTP requests. Once a request has been read completely, the connection handler outsources the actual request handling into a separate thread pool for CPU-bound ops and the connection handler coroutine gets paused. Once the response is done, that coroutine gets resumed to send it.

Problem

While being tested with wrk -d 30 -c 100 -t 100 http://127.0.0.1:8910/ the app fails sooner or later with:

grumpycathttpd: /usr/include/boost/coroutine/detail/push_coroutine_impl.hpp:258: void boost::coroutines::detail::push_coroutine_impl<void>::push(): Assertion `! is_running()' failed.

My Questions

  1. Is the app's concept (ASIO thread pool with coroutines + CPU-bound thread pool with queue) possible/realistic at all?
  2. If yes: What exactly am I doing wrong while pausing/resuming the coroutine? Shall I not use async_completion, completion_handler and asio_handler_invoke like the boost libs themselves do?

Code

AFAIK I should post the app's code – so here it is... I hope it doesn't matter that there are 223 lines.

IMO the important lines are 160, 193-198, 92-102 and 106-109.

/* 1 */ #include <condition_variable>
/* 2 */ using std::condition_variable;
/* 3 */ 
/* 4 */ #include <exception>
/* 5 */ using std::exception;
/* 6 */ 
/* 7 */ #include <functional>
/* 8 */ using std::function;
/* 9 */ 
/* 10 */ #include <iostream>
/* 11 */ using std::cout;
/* 12 */ using std::endl;
/* 13 */ 
/* 14 */ #include <limits>
/* 15 */ using std::numeric_limits;
/* 16 */ 
/* 17 */ #include <memory>
/* 18 */ using std::make_shared;
/* 19 */ using std::shared_ptr;
/* 20 */ 
/* 21 */ #include <mutex>
/* 22 */ using std::mutex;
/* 23 */ using std::unique_lock;
/* 24 */ 
/* 25 */ #include <queue>
/* 26 */ using std::queue;
/* 27 */ 
/* 28 */ #include <thread>
/* 29 */ using std::thread;
/* 30 */ 
/* 31 */ #include <utility>
/* 32 */ using std::move;
/* 33 */ 
/* 34 */ #include <vector>
/* 35 */ using std::vector;
/* 36 */ 
/* 37 */ #include <boost/asio/async_result.hpp>
/* 38 */ using boost::asio::async_completion;
/* 39 */ 
/* 40 */ #include <boost/asio/buffer.hpp>
/* 41 */ using boost::asio::mutable_buffer;
/* 42 */ 
/* 43 */ #include <boost/asio/buffered_stream.hpp>
/* 44 */ using boost::asio::buffered_stream;
/* 45 */ 
/* 46 */ #include <boost/asio/handler_invoke_hook.hpp>
/* 47 */ using boost::asio::asio_handler_invoke;
/* 48 */ 
/* 49 */ #include <boost/asio/io_service.hpp>
/* 50 */ using boost::asio::io_service;
/* 51 */ 
/* 52 */ #include <boost/asio/ip/tcp.hpp>
/* 53 */ using boost::asio::ip::tcp;
/* 54 */ 
/* 55 */ #include <boost/asio/spawn.hpp>
/* 56 */ using boost::asio::spawn;
/* 57 */ 
/* 58 */ #include <boost/asio/yield.hpp>
/* 59 */ using boost::asio::yield_context;
/* 60 */ 
/* 61 */ #include <boost/beast/core.hpp>
/* 62 */ namespace beast = boost::beast;
/* 63 */ 
/* 64 */ #include <boost/beast/http.hpp>
/* 65 */ namespace http = beast::http;
/* 66 */ 
/* 67 */ #include <boost/system/error_code.hpp>
/* 68 */ using boost::system::error_code;
/* 69 */ 
/* 70 */ 
/* 71 */ class work_queue {
/* 72 */ public:
/* 73 */    work_queue(io_service& io) : io(io), pool((vector<thread>::size_type)(thread::hardware_concurrency())), stop(false) {
/* 74 */        for (auto& thrd : pool) {
/* 75 */            thrd = thread([this](){ run(); });
/* 76 */        }
/* 77 */    }
/* 78 */ 
/* 79 */    ~work_queue() {
/* 80 */        {
/* 81 */            unique_lock<mutex> ul (mtx);
/* 82 */            stop = true;
/* 83 */            cond_var.notify_all();
/* 84 */        }
/* 85 */ 
/* 86 */        for (auto& thrd : pool) {
/* 87 */            thrd.join();
/* 88 */        }
/* 89 */    }
/* 90 */ 
/* 91 */    template<class Handler>
/* 92 */    void async_run(function<void()> task, Handler&& handler) {
/* 93 */        async_completion<Handler, void(error_code)> init(handler);
/* 94 */ 
/* 95 */        {
/* 96 */            auto completion_handler (make_shared<decltype(init.completion_handler)>(init.completion_handler));
/* 97 */            unique_lock<mutex> ul (mtx);
/* 98 */            tasks.emplace(enqueued_task({move(task), [completion_handler](){ asio_handler_invoke(*completion_handler); }}));
/* 99 */            cond_var.notify_all();
/* 100 */       }
/* 101 */ 
/* 102 */       init.result.get();
/* 103 */   }
/* 104 */ 
/* 105 */ private:
/* 106 */   struct enqueued_task {
/* 107 */       function<void()> task;
/* 108 */       function<void()> on_done;
/* 109 */   };
/* 110 */ 
/* 111 */   mutex mtx;
/* 112 */   condition_variable cond_var;
/* 113 */   io_service& io;
/* 114 */   queue<enqueued_task> tasks;
/* 115 */   vector<thread> pool;
/* 116 */   bool stop;
/* 117 */ 
/* 118 */   void run() {
/* 119 */       unique_lock<mutex> ul (mtx);
/* 120 */ 
/* 121 */       while (!stop) {
/* 122 */           while (!tasks.empty()) {
/* 123 */               auto task (move(tasks.front()));
/* 124 */               tasks.pop();
/* 125 */ 
/* 126 */               ul.unlock();
/* 127 */ 
/* 128 */               try {
/* 129 */                   task.task();
/* 130 */               } catch (...) {
/* 131 */               }
/* 132 */ 
/* 133 */               io.post(move(task.on_done));
/* 134 */ 
/* 135 */               ul.lock();
/* 136 */           }
/* 137 */ 
/* 138 */           cond_var.wait(ul);
/* 139 */       }
/* 140 */   }
/* 141 */ };
/* 142 */ 
/* 143 */ int main() {
/* 144 */   vector<thread> pool ((vector<thread>::size_type)(thread::hardware_concurrency()));
/* 145 */   io_service io;
/* 146 */   work_queue wq (io);
/* 147 */   tcp::acceptor acceptor (io);
/* 148 */   tcp::endpoint endpoint (tcp::v6(), 8910);
/* 149 */ 
/* 150 */   acceptor.open(endpoint.protocol());
/* 151 */   acceptor.set_option(tcp::acceptor::reuse_address(true));
/* 152 */   acceptor.bind(endpoint);
/* 153 */   acceptor.listen(numeric_limits<int>::max());
/* 154 */ 
/* 155 */   spawn(acceptor.get_io_context(), [&acceptor, &wq](yield_context yc) {
/* 156 */       for (;;) {
/* 157 */           shared_ptr<tcp::socket> peer (new tcp::socket(acceptor.get_io_context()));
/* 158 */           acceptor.async_accept(*peer, yc);
/* 159 */ 
/* 160 */           spawn(acceptor.get_io_context(), [peer, &wq](yield_context yc) {
/* 161 */               try {
/* 162 */                   {
/* 163 */                       auto remote (peer->remote_endpoint());
/* 164 */                       cout << "I has conn: [" << remote.address().to_string() << "]:" << remote.port() << endl;
/* 165 */                   }
/* 166 */ 
/* 167 */                   buffered_stream<decltype(*peer)> iobuf (*peer);
/* 168 */ 
/* 169 */                   iobuf.async_fill(yc);
/* 170 */ 
/* 171 */                   if (iobuf.in_avail() > 0) {
/* 172 */                       char first_char;
/* 173 */ 
/* 174 */                       {
/* 175 */                           mutable_buffer first_char_buf (&first_char, 1);
/* 176 */                           iobuf.peek(first_char_buf);
/* 177 */                       }
/* 178 */ 
/* 179 */                       if ('0' <= first_char && first_char <= '9') {
/* 180 */                           cout << "I has JSON-RPC!" << endl;
/* 181 */                       } else {
/* 182 */                           beast::flat_buffer buf;
/* 183 */ 
/* 184 */                           for (;;) {
/* 185 */                               http::request<http::string_body> req;
/* 186 */ 
/* 187 */                               http::async_read(iobuf, buf, req, yc);
/* 188 */ 
/* 189 */                               cout << "I has req: '" << req.body() << '\'' << endl;
/* 190 */ 
/* 191 */                               http::response<http::string_body> res;
/* 192 */ 
/* 193 */                               wq.async_run([&req, &res](){
/* 194 */                                   res.result(http::status::internal_server_error);
/* 195 */                                   res.set(http::field::content_type, "text/plain");
/* 196 */                                   res.set(http::field::content_length, "36");
/* 197 */                                   res.body() = "I like onions. They make people cry.";
/* 198 */                               }, yc);
/* 199 */ 
/* 200 */                               http::async_write(iobuf, res, yc);
/* 201 */                               iobuf.async_flush(yc);
/* 202 */ 
/* 203 */                               cout << "I has res." << endl;
/* 204 */                           }
/* 205 */                       }
/* 206 */                   }
/* 207 */ 
/* 208 */                   peer->shutdown(peer->shutdown_both);
/* 209 */               } catch (const exception& e) {
/* 210 */                   cout << "I has exception: " << e.what() << endl;
/* 211 */               }
/* 212 */           });
/* 213 */       }
/* 214 */   });
/* 215 */ 
/* 216 */   for (auto& thrd : pool) {
/* 217 */       thrd = thread([&io](){ io.run(); });
/* 218 */   }
/* 219 */ 
/* 220 */   for (auto& thrd : pool) {
/* 221 */       thrd.join();
/* 222 */   }
/* 223 */ }

Unimplemented derived function in CRTP

I'm working on making a wrapper to be able to port future code easily to different backend rendering engines. We are currently working in GDI. Currently I am implementing virtual functions on an abstract backend, but I'd like to change that to CRTP since the backend should be known at compile time.

Unfortunately one hiccup I've experienced with CRTP (first time using) is that I must implement all details of derived functions. In contrast, the abstract implementation does not require fully implemented derived children. To demonstrate consider this:

#include <Windows.h>
#include <iostream>

struct AbstractBackend
{
  virtual ~AbstractBackend() = 0;

  virtual void foo()
  {
    throw "implementation missing: failed to override in derived class";
  }

  virtual void bar()
  {
    throw "implementation missing: failed to override in derived class";
  }
};

AbstractBackend::~AbstractBackend() {}

struct ConcreteBackendA : AbstractBackend
{
  int backendResource;

  ConcreteBackendA(int rsc) :
    backendResource(rsc)
  {}

  virtual void foo()
  {
    printf("executing ConcreteBackendA::foo!\n");
  }

  // ConcreteBackendA does not support "bar" feature
};

struct ConcreteBackendB : AbstractBackend
{
  HDC backendResource;

  ConcreteBackendB(HDC hdc) :
    backendResource(hdc)
  {}

  virtual void foo()
  {
    printf("executing ConcreteBackendB::foo!\n");
  }

  virtual void bar()
  {
    printf("executing ConcreteBackendB::bar!\n");
  }

};

struct FrontEnd
{
  AbstractBackend *backend;

  FrontEnd(int rsc) :
    backend(new ConcreteBackendA(rsc))
  {}

  FrontEnd(HDC hdc) :
    backend(new ConcreteBackendB(hdc))
  {}

  ~FrontEnd()
  {
    delete backend;
  }

  void foo()
  {
    backend->foo();
  }

  void bar()
  {
    backend->bar();
  }
};

int main()
{
  int rsc = 0;
  HDC hdc = 0;
  FrontEnd A(rsc);
  FrontEnd B(hdc);

  A.foo();
  A.bar(); // throws an error, A::bar is not a feature of this engine

  B.foo();
  B.bar();

  std::cin.get();
}

In this example, the AbstractBackend supports two features, foo & bar. The ConcreteBackendA only supports foo, bar is a function that it cannot support (maybe something like Draw3dText), but that's ok. The user can catch the exceptions and move on. One small drawback is the usage of virtual functions. I'd like to entertain the thought of using CRTP like this:

#include <Windows.h>
#include <iostream>

template <class Derived>
struct AbstractBackend
{
  virtual ~AbstractBackend() = 0;

  void foo()
  {
    static_cast<Derived*>(this)->foo();
  }

  void bar()
  {
    static_cast<Derived*>(this)->bar();
  }
};

template <class Derived>
AbstractBackend<Derived>::~AbstractBackend() {}

struct ConcreteBackendA : AbstractBackend<ConcreteBackendA>
{
  int backendResource;

  ConcreteBackendA(int rsc) :
    backendResource(rsc)
  {}

  void foo()
  {
    printf("executing ConcreteBackendA::foo!\n");
  }

  // ConcreteBackendA does not support "bar" feature
};

struct ConcreteBackendB : AbstractBackend<ConcreteBackendB>
{
  HDC backendResource;

  ConcreteBackendB(HDC hdc) :
    backendResource(hdc)
  {}

  void foo()
  {
    printf("executing ConcreteBackendB::foo!\n");
  }

  void bar()
  {
    printf("executing ConcreteBackendB::bar!\n");
  }
};

template <class ConcreteBackend>
struct FrontEnd
{
  AbstractBackend<ConcreteBackend> *backend;

  FrontEnd(int rsc) :
    backend(new ConcreteBackendA(rsc))
  {}

  FrontEnd(HDC hdc) :
    backend(new ConcreteBackendB(hdc))
  {}

  ~FrontEnd()
  {
    delete backend;
  }

  void foo()
  {
    backend->foo();
  }

  void bar()
  {
    backend->bar();
  }
};

int main()
{
  int rsc = 0;
  HDC hdc = 0;
  FrontEnd<ConcreteBackendA> A(rsc);
  FrontEnd<ConcreteBackendB> B(hdc);

  A.foo();
  A.bar(); // no implementation: stack overflow

  B.foo();
  B.bar();

  std::cin.get();
}

The problem is that if a derived class fails to implemented a function from the AbstractBackend, then the AbstractBackend will call itself causing a stack overflow.

How can I replicated the behavior of the virtual abstract implementation with CRTP?

Correct way to create and manage look up containers

correct way to create look up maps for instances. I have a structure defined Node as follows

struct Node
{
    int32_t id;
    std::string name;
    ...
}

i want to create 2 look up maps, on based on id and another based on name. There are other attributes in the Node which also needs look up maps but those are dynamic so not every Node instance will have a look entry into those additional maps.

with just one look up map I was planning to create something like

typedef std::unoredered_map<int32_t, std::unique_ptr <Node> > NodesById;

I reason being just I can get this deleted by just erase or [id] = new 'overwrite!' operation and don't have to worry about it. But then how can I add the same Node instance to say another map

typedef std::unoredered_map<std::string, std::unique_ptr <Node> > NodesByName;

I cannot put same Node instance into to unique_ptr. So my question is what is the correct way to store Node instances into multiple look up tables and still achieve smart memory management.