Why is volatileWrite necessary inside Atomic{Type}Array constructor - java.util.concurrent

For example the constructor that takes array size of java.util.concurrent.atomic.AtomicLongArray is defined as following:
public AtomicLongArray(int length) {
array = new long[length];
// must perform at least one volatile write to conform to JMM
if (length > 0)
unsafe.putLongVolatile(array, rawIndex(0), 0);
}
Snippet taken from AtomicLongArray.java.
Why is volatileWrite necessary inside this constructor when array field is final ?

There is no need for it, and this line of code was removed in later versions of of the JDK
This how it looks in JDK 1.7 and 1.8
public AtomicLongArray(int length) {
array = new long[length];
}

Related

I want to make instance with array in SystemC

I want to make instance with array in SystemC.
I want to write as follows:
module name = new module[10];
or
for(int i = 0; i < 10; i++){
module name[i]("any names")
}
However, I did this, the compiler said:
error: no matching function for call to 'module::module()'
Please tell me how to make an instance with array.
In SystemC, you can use sc_vector instead of a plain C array, see e.g.
https://standards.ieee.org/standard/1666-2011.html (Section 8.5)
https://complex.offis.de/documents/doc_details/29-scvector-and-the-ieee-p1666-2011-systemc-standard.html
SC_MODULE(top)
{
sc_vector<module> m; // e.g. class member
SC_CTOR(top)
: m("modules", 10) // constructor
{}
};

How is building an array of objects working? I'm stuck with this example

I'm trying to understand some code that is for an ESP32 EPaper module(TTGO T5 V2.2). This program makes use of the Button2 library for handling events when one of the three buttons is pressed. It initializes an object for each button and stores it in an array of pointers. when I want to compile the code, I get the following error:
error: no matching function for call to 'Button2::Button2()'
(info: Button2 *pBtns = nullptr; args = 3; )
The codeline where the error occures is:
pBtns = new Button2 [args];
So far I understood, should this line reserve the memory on the heap for that new object. So why should there be a function and what's the purpose of it?
I tried so far using a fixed array size and use a sniplet from some example found somewhere on the internet:
//Button2 pBtns[5] = {nullptr,nullptr,nullptr,nullptr,nullptr};
//Button2 pBtns[5];
//Button2* pBtns = static_cast<Button2*>( ::operator new ( sizeof(Button2) * (sizeof(g_btns) / sizeof(g_btns[0]))));
// g_btns[] is the array of gpio pins of the buttons
Due to the lack of examples I have still no clue if I am missing something, but the "no matching function for call"-error hints to a problem with the object itself, if I'm not wrong ...
// in Button2.h:
class Button2 {
private:
.// some private defs ...
public:
Button2(byte attachTo, byte buttonMode = INPUT_PULLUP, unsigned int debounceTimeout = DEBOUNCE_MS);
.// some methods here ...
bool operator==(Button2 &rhs);
void loop();
};
// in program code:
#define BUTTONS_MAP {37,38,39}
Button2 *pBtns = nullptr;
uint8_t g_btns[] = BUTTONS_MAP;
void button_init()
{
uint8_t args = sizeof(g_btns) / sizeof(g_btns[0]);
pBtns = new Button2 [args]; //<<<<<<< COMPILER-ERROR is HERE
//pBtns = new Button2;
for (int i = 0; i < args; ++i) {
pBtns[i] = Button2(g_btns[i]);
pBtns[i].setPressedHandler(button_callback);
}
}
I want in the above example that pBtns contains an array with 3 Pointers to new created and initialized objects. Additionaly I want to know what function is ment in the error message. I like the idea of storing objects in arrays and want to use it in my own development, when I understood the principle and practised - so what are the pros and cons of technique?
(sri for the long text - just don't yet know whats relevant, so pimp my brain!)
When an array is allocated, the program will attempt to default construct the elements.
You cannot default construct Button2 because defining another constructor disables the automatically generated default constructor. You need to either add a default constructor or move to a smarter container like std::vector.
Example:
Button2 *pBtns = nullptr;
becomes
std::vector<Button2> btns;
And then later buttons are created in the vector with
btns.emplace_back(<arguments>);
As an added bonus, vector removes all of the memory management work that a dynamically allocated array saddles you with.
The problem is the lack of default (no argument) constructor called by operator new [].
To define one add this line to the class Button2 definition:
Button2() = default; // after C++11
or
Button2() {} // before C++11
Assuming all your members also have default constructors (most likely), this should JustWork(TM)
Button2 *pBtns is not an array of pointers, but a pointer to one or more actual Button2 objects. That is why new[] tries to construct such objects.
You would need
Button2 **pBtns=nullptr;
...
pBtns=new *Button2[args];
and then could the loop with pBtns[i]=new Button2(...); work.
But this is rather C-ish (minus the use of new), contemporary C++ code would more likely use std::vector, as comments and other answer(s) suggest.

"ISO C++ forbids initialization in array new": How to directly initialize an template object with its own constructor as an array in C++

So my intention was to build a "Multibuffer" which has a definable amount of "SingleBuffers". The type that is stored is free, so I want to use templates for that reason. I am just playing around a bit.
But I don't know how to initialize the Singlebuffers in the Constructor of the Multibuffer directly.
I won't write down the complete classes, but the Constructors to show the problem. I defined the both classes in the header, as it should be done, when working with template classes.
So my Singlebuffer-Constructor looks like this:
enum BufferState_E
{
BUFFER_WRITE = 0,
BUFFER_READ,
BUFFER_FORCED_READ // buffer is forced for reading
};
template<typename T>
class SingleBuffer
{
public:
/*
* Constructor
* constructs a Buffer with the concrete data field
*/
SingleBuffer( unsigned int buffer_size )
: entry_ptr_ ( new T[buffer_size]() ) //default constructor works?
, end_entry_ptr_ ( &entry_ptr_[buffer_size-1] )
{
read_entry_ptr_ = &entry_ptr_[0];
write_entry_ptr_ = &entry_ptr_[0];
state_ = BUFFER_WRITE;
}
private:
/* The pointer to the buffer */
T * entry_ptr_;
/* the pointers to the entry which is currently read/written */
T *read_entry_ptr_;
T *write_entry_ptr_;
/* the pointer to the end of the buffer */
T * end_entry_ptr_;
/* The state of the buffer */
BufferState_E state_;
}
and my Multibuffer-Constructor which instantiates an amount of Singlebuffers (I wrote a comment after the problematic line of code):
template<typename T>
class MultiBuffer : public BufferBase
{
public:
MultiBuffer( unsigned int buffer_size = 2000 // size of one buffer
, unsigned char number_of_buffers = 5 // how many buffers are there?
, const char* name = "MultiBuffer"
)
: buffer_ptr_ ( new SingleBuffer<T>[number_of_buffers](buffer_size) ) // the problem line!
, end_buffer_ptr_ ( &buffer_ptr_[number_of_buffers-1])
, buffer_size_ ( buffer_size )
, number_of_buffers_ ( number_of_buffers )
{
read_buffer_ptr_ = &buffer_ptr_[0];
write_buffer_ptr_ = &buffer_ptr_[0];
}
private:
/* the normal buffer-pointer */
SingleBuffer<T> *buffer_ptr_;
/* the pointer to the end of the buffers */
SingleBuffer<T> *end_buffer_ptr_;
/* the pointer to the current read-buffer */
SingleBuffer<T> *read_buffer_ptr_;
/* the pointer to the current write-buffer */
SingleBuffer<T> *write_buffer_ptr_;
/* the buffer-size */
unsigned int buffer_size_;
/* the number of buffers */
unsigned char number_of_buffers_;
}
So my Compiler always tells me: "ISO C++ forbids initialization in array new" in the marked line of code. Looking up the cpp-reference for "new" doesn't really help, neither do the other asked questions that have to do with templates.
If I just use the default constructor, like you see in the Singlebuffer initialization it seems to work but as soon as I want to pass a value to the constructor of my own defined template-class it crashes. I did manage to force it to build when not initializing in the Multibuffer-Constructor directly but with a loop which iterates the "number of buffers" and allocates memory in every iteration, but that's not how it should work, besides I don't really know if that really works error-free.
And I don't want to use std::-functions, because I'm working on an embedded system. The compiler is a GCC 4.8.1 and is not changeable too, and lambda-expressions are not supported too...
I hope there will be a possibility. Thanks so far.
The error message says it: You can't provide initialisation in new[]. You will have to assign to those objects later, probably in the body of MultiBuffer::MultiBuffer.
But you shouldn't do that. You should just use std::vector for your dynamic array needs. Your compiler provides it, and the library writers know what they are doing. "Standard library functions are bloated" hasn't been true this century

NodeJS Addon Unordered_map not supported?

I am working with the Laurena library for C++ to add serialization to JSON to my Node Addon. When I initialize the library, it gets to a particular point in the code where it defines two unordered_map objects. They aren't initialized, but instead immediately used (as in the code below). ANY access to any data or any methods within the unordered_maps causes a vector subscript out of range failure.
But ONLY in nodejs.
If I pull the addon code and dump it into a Visual Studio 2013 C++ Console application, without ANY changes, it runs perfectly. Can anyone point me in the direction of what it is about these unodered_maps that isn't supported in node that is in a regular console app?
using namespace laurena;
std::unordered_map<std::string, const descriptor*> classes::_classes_by_name;
std::unordered_map<size_t, const descriptor*> classes::_classes_by_typeid;
void classes::add(const descriptor* myClass)
{
for(int i = 0; i< _classes_by_typeid.size(); i++)
{
printf("in array I (%d) : %Iu", i, _classes_by_typeid[i]); //FAILS!
}
// also failes
printf("Access ANYTHING? %s \n", _classes_by_typeid.hash_function());
// Doesn't fail? WTF??
printf("Post Set array size :: %d\n", _classes_by_name.size());
printf("Post Set array size :: %d\n", _classes_by_typeid.size());
}
I'm Laurena's author.
Laurena's library in this current version has a big flaw as it use global static variables to store classes descriptors. A better implementation would have been to store them into a singleton initialized dynamically.
A possible explain is you call laurena::classes::add from another library's static member/global data constructor. Static / global datas constructors are executed before int main (...)
In this case, if your data's constructor is called before laurena's static maps constructors, then yes you can have the error you describe. See
What’s the “static initialization order fiasco”? at https://isocpp.org/wiki/faq/ctors#static-init-order for more details about this problem.
Then there is two options:
1) laurena::classes static datas must be wrapped into a singleton dynamically created.
laurena::classes::add method should looks then
void classes::add(const descriptor* myClass) // classes::add is a static class function
{
classes* p = classes::get_or_create_instance ();
p->_classes_by_name[myClass->name()] = myClass;
p->_classes_by_typeid[std::type_index(myClass->type()).hash_code()] = myClass;
}
2) Move calls to classes::add into int main ( ... ) :
int main ()
{
// laurena's initialization
laurena::classes::init();
// let's declare TheNerd serializables classes :
declare_TheNerd_classes();
...
}
If you can't use option 2, option 1 is something i could fix.

Iterate over all structs in a module

I'm writing a ModulePass and I need to analyze every struct defined in the given module.
I understand that identified structs with a name are inserted in the ValueSymbolTable, but how can I iterate over all the other structs (identified with no name and literal structs)?
The correct way of doing this is:
#include "llvm/IR/TypeFinder.h"
llvm::TypeFinder StructTypes;
StructTypes.run(M, true);
for (auto *STy : StructTypes)
STy->dump();
You should not use any private/opaque types (like LLVMContextImpl) whose headers are not published.
The LLVMContextImpl instance associated with your current context should have two data structures, one containing all the identified structs in the current context (whether or not they have an explicit name), and the other containing all the literal structs.
To get the LLVMContextImpl instance:
Module& M = ...
LLVMContextImpl* C = M.getContext().pImpl;
For the identified structs:
C->NamedStructTypes
For the literal structs:
C->AnonStructTypes
Both return iterable types (StringMap for the first, DenseMap for the second), allowing you to iterate over them and get all the types out.
bool runOnModule(Module &M) override
{
for(auto *S : M.getIdentifiedStructTypes())
{
S->dump();
}
return false;
}
Complementing Oak's answer, here's a more complete code example:
Module& M = ...
LLVMContextImpl* C = M.getContext().pImpl;
for (StringMap<StructType *>::iterator i = C->NamedStructTypes.begin(); i != C->NamedStructTypes.end(); ++i)
{
StructType *t = i->getValue();
t->dump(); fprintf(stderr, "\n");
}
LLVMContextImpl.h, being the header for a private implementation, isn't one of LLVM's public headers. You can get it from the LLVM source code — either copy it from there into your header search path or, for quick & dirty testing, do:
#include "/path/to/llvm/src/lib/VMCore/LLVMContextImpl.h"