On renderscripts and thread-safety - renderscript

I have always assumed that renderscripts are threadsafe with forEach across an allocation. To aid in my debugging, can someone confirm this?
(I'm seeing a static array value check succeed, but using rsDebug shows that the check should have failed.
static uint32_t state[16];
static void f(); // modifies state.
/* snip... */
void
root(const uint32_t *in, uint32_t *out)
{
/* snip... */
f();
if(state[0] == 0)
{
rsDebug("state[0]", state[0]);
*out = 1;
}
}
I see printed state[0] with a nonzero value!)

Each cell is expected to execute independently of the other cells. If you are writing to other cells of your input (or output) Allocation, you can certainly trigger undefined behavior. This is no different than any other multithreaded computation model, however. Can you show your kernel code exactly and describe how you are calling it?

Related

Are only types with trivial destructor suited for storage for placement new?

The examples for placement new often use unsigned char arrays as the underlying storage. The steps can be:
create the unsigned char array with new
create an object in this storage with placement new
use object
destroy object
call delte for the unsigned char array to free the array
Point 5. seems only to work if we use a type for the underlying storage with a trivial destructor. Otherwise, we would call the destructor of the underlying storage type but with no object existing there. Technically, we are destructing a bunch of unsigned chars which are not present and we are lucky that the desturctor of the unsigned char type is trivial and so no-op.
What about the following code:
struct A{ /* some members... */ };
struct B{ /* some members... B shall be same size as A */ };
int main()
{
auto ptr_to_a = new A; // A object lives # ptr_to_a
ptr_to_a->~A(); // A object destroyed. no object living # ptr_to_a, but storage is preserved
new (ptr_to_a) B; // B object living # ptr_to_a.
std::launder(reinterpret_cast<b*>(ptr_to_a))->/*...*/; // use B. for this purpose we need std::launder in C++17 or we would store the pointer returned by the placement new and use it without std::launder
std::launder(reinterpret_cast<b*>(ptr_to_a))->~B(); // B object destroyed. no object living # ptr_to_a, but storage is preserved
// at this point there is no object living # ptr_to_a, but we need to hand back the occupied storage.
// a)
delete ptr_to_a; // undefined behavior because no object is sitting # ptr_to_a
// b)
new (ptr_to_a) A; // create an object again to make behavior defined. but this seems odd.
delete ptr_to_a;
// c)
// some method to just free the memory somehow without invoking destructors?
return 0;
}
On https://en.cppreference.com/w/cpp/language/lifetime is written:
As a special case, objects can be created in arrays of unsigned char or std::byte (in which case it is said that the array provides storage for the object) if... .
Does this imply, that its only allowed to use placement new on unsigned char and byte arrays and because they have a trivial destructor my code sample is obsolete?
Otherwise, how about my codesample? Is option b) the only valid solution?
Edit: second examlpe:
struct A{ /* some members... */ };
struct alignas(alignof(A)) B{ /* some members... */ };
int main()
{
static_assert(sizeof(A) == sizeof(B));
A a;
a.~A();
auto b_ptr = new (&a) B;
b_ptr->~B();
return 0;
// undefined behavior because a's destructor gets called but no A object is "alive" (assuming non trivial destructor)
// to make it work, we need to placement new a new A into a?
}
Generally, you wouldn't use the storage returned by an allocation of an unrelated class A to put your B in. You don't even have to have an allocation at all
int main ()
{
char storage[sizeof(B)];
std::aligned_storage<sizeof(B), alignof(B)>::type aligned_storage;
auto b_ptr1 = new (&storage) B; // potentially unaligned
auto b_ptr2 = new (&aligned_storage) B; // guaranteed safe
// use b_ptr1, b_ptr2
b_ptr1->~B();
b_ptr2->~B();
// storage ceases to exist when main returns
}
If you do need to dynamically allocate, I would suggest wrapping the storage in a holder struct, so that you don't end the lifetime of the thing you newed.
struct B_holder
{
std::aligned_storage<sizeof(B), alignof(B)>::type storage;
B * make_B() { return new(&storage) B; }
}
int main()
{
auto holder = std::make_unique<B_holder>();
auto * B_ptr = B_holder->make_B();
// use B_ptr
B_ptr->~B();
// holder ceases to exist when main returns
}
For the most part yes.
You can however do something like this.
struct placed {
char stuff[100];
};
struct stupid {
std::aligned_storage_t<sizeof(placed), alignof(placed)> data;
~stupid() {
std::cout << "stupid gone\n";
}
};
int main() {
auto* pstupid = new stupid;
auto* pplaced = ::new( (void*)&pstupid->data ) placed;
pplaced->~placed();
auto* pstupid2 = ::new( (void*)pstupid ) stupid;
delete pstupid2;
}
but that is, as implied by the type name, pretty stupid. And exceedingly hard to make exception safe without a lot of noexcept guarantees I didn't include above.
I am also not completely certain if delete pstupid2 is legal, as it was created via placement new and not via a simple new expression.

What operations are unsafe before __libc_init_array is invoked?

I want to run some code before main begins, and before constructors for static variables run. I can do with with code like this (ideone)
extern "C" {
static void do_my_pre_init(void) {
// something
}
__attribute__ ((section (".preinit_array"))) void(*p_init)(void) = &do_my_pre_init;
}
Are there any language features that will not work correctly when executed in this function, due to _init and .init_array not yet having been executed?
Or is it only user code that should be hooking into this mechanism?
Some background on __libc_init_array
The source for a typical __libc_init_array is something like:
static void __libc_init_array() {
size_t count, i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++)
__preinit_array_start[i]();
_init();
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++)
__init_array_start[i]();
}
Where the __... symbols come from a linker script containing
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
Are there any language features that will not work correctly when executed in this function, due to _init and .init_array not yet having been executed?
This question is impossible to answer in general, because the language itself has no concept of .preinit_array, or _init, or .init_array. All of these concepts are implementation details for a particular system.
In reality, you aren't guaranteed to have anything work at all. Things as simple as malloc may not work (e.g. because the malloc subsystem itself may be using .preinit_array to initialize itself).
In practice, using dynamic linking on a GLIBC-based platform most everything will work (because libc.so.6 initializes itself long before the first instruction of the main executable runs).
For fully-static executable, all bets are off.
For non-GLIBC platform, you'll need to look into specifics of that platform (and you are very unlikely to find any guarantees).
Update:
Can I make function calls,
Function calls need no setup with fully-static linking, and need dynamic loader to have initialized in dynamic linking case. No dynamic loader will start executing code in the application before it has fully initialized itself, so function calls should be safe.
assign structs
In C, at best, this is a few instructions. At worst, this is a call to memcpy or memset. That should be safe.
use array initializers.
This is just a special case of struct assignment, so should be safe.

Using boost::python::handle as temporary?

In a custom converter, I am checking whether a sequence item is some type. So far I've had this code (simplified)
namespace bp=boost::python;
/* ... */
static void* convertible(PyObject* seq_ptr){
if(!PySequence_Check(seq_ptr)) return 0;
for(int i=0; i<PySequence_Size(seq_ptr); i++)
if(!bp::extract<double>(PySequence_GetItem(seq_ptr,i)).check()) return 0;
/* ... */
}
/* ... */
but this is leaking memory, since PySequence_GetItem is returning a new reference. So either I can do something like this in the loop:
PyObject* it=PySequence_GetItem(seq_ptr,i);
bool ok(bp::extract<double>(it).check();
Py_DECREF(it); // will delete the object which had been newly created
if(!ok) return 0;
but that is quite clumsy; I could make a stand-alone function doing that, but that is where I recalled bp::handle implementing the ref-counting machinery; so something like this might do:
if(!bp::extract<double>(bp::handle<>(PySequence_GetItem(seq_ptr,i))).check()) return 0;
but this page mentions using handles as temporaries is discouraged. Why? Can the object be destroyed before .check() is actually called? Is there some other elegant way to write this?
The object will not be destroyed before the .check() is called and is safe in the posted context.
The recommendation to not use temporaries is due to the unspecified order of evaluation of the arguments and exception safety. If there is only one order in which arguments can be evaluated, such as in your example, then it is safe. For instance, consider function bad() which always throws an exception:
f(boost::python::handle<>(PySequence_GetItem(...)), bad());
If bad() gets evaluated between PySequence_GetItem(...) and boost::python::handle<>(...), then the new reference will be leaked as the stack will begin to unwind before the construction of boost::python::handle<>. On the other hand, when a non-temporary is used, there is no chance for something to throw between PySequence_GetItem() and boost::python::handle<>(), so the following is safe in the presence of exceptions:
boost::python::handle<> item_handle(PySequence_GetItem(...));
f(item_handle, bad());
Consider reading Herb Sutter's GotW #56: Exception-Safe Function Calls for more details.

Register function that will be called before system call

How can we register function such that it will be called before executing system call.
For example, pthread_atfork() registers functions that will be called before and after fork().
Below is the example on Linux system.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
//http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html
void prepare_function() {
printf("%d : In Prepare Function\n", getpid());
}
void parent_fuction() {
printf("%d : In Parent Function\n", getpid());
}
void child_function() {
printf("%d : In Child Function\n", getpid());
}
int main() {
pthread_atfork(prepare_function, parent_fuction, child_function);
if (fork() == 0) {
//sleep(1);
printf("%d : In Child\n", getpid());
return 0;
}
//sleep(1);
printf("%d : In Parent\n", getpid());
return 0;
}
I'm curious about how this can be implemented.
What is the actual goal here?
Fork has hooks because the state of the child with presence of threads in undefined. So by hooking yourself up you can ensure whatever mechanisms you want to use remain operational (for instance, if the fork happened after one of your threads takes a lock, the lock will remain taken within the child - what now?).
In general there is no mechanism which provides hooks for all syscalls.
For the most part syscalls are wrapped in glibc so there are few entry points which actually call the kernel. Someone bored enough could hack this up by e.g. inserting a jump in generated code to which would land the execution in their routine. But such a routine would have to have its own way of calling syscalls or a hack.
But wait, any piece of code is free to call a syscall without the use of such wrappers and such code could be dynamically generated, so you can't binary patch it prior to execution.
You can trace syscall entry/exit with ptrace, but you need a separate process for that.

Call function in main program from a library in Arduino

I've just started making libraries in Arduino. I've made a library named inSerialCmd. I want to call a function named delegate() that is defined in the main program file, stackedcontrol.ino, after the inSerialCmd library is included.
When I try to compile, one error is thrown:
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: In member function
'void inSerialCmd::serialListen()':
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: error:
'delegate' has not been declared
After doing a bit of searching, it seemed that adding the scope resolution operator might do the trick. So I added the "::" before delegate(), now "::delegate()", but the same error is thrown.
Now I'm stumped.
You cannot and should not directly call a function in a program from a library. Keep in mind a key aspect that makes a library into a library:
A library does not depend on the specific application. A library can be fully compiled and packaged into the .a file without the existence of a program.
So there is a one way dependency, a program depends on a library. This at first glance may seem to prevent you from achieving what you want. You can achieve the functionality you are asking about through what is sometimes referred to as a callback. The main program would provide to the library at runtime a pointer to the function to execute.
// in program somwehere
int myDelegate(int a, int b);
// you set this to the library
setDelegate( myDelegate );
You see this in the arduino if you look at how interrupt handlers are installed. This same concept exists in many environments - event listeners, action adapters - all with the same goal of allowing a program to define the specific action that a library cannot know.
The library would store and call the function via the function pointer. Here is a rough sketch of what this looks like:
// in the main program
int someAction(int t1, int t2) {
return 1;
}
/* in library
this is the delegate function pointer
a function that takes two int's and returns an int */
int (*fpAction)(int, int) = 0;
/* in library
this is how an application registers its action */
void setDelegate( int (*fp)(int,int) ) {
fpAction = fp;
}
/* in libary
this is how the library can safely execute the action */
int doAction(int t1, int t2) {
int r;
if( 0 != fpAction ) {
r = (*fpAction)(t1,t2);
}
else {
// some error or default action here
r = 0;
}
return r;
}
/* in program
The main program installs its delegate, likely in setup() */
void setup () {
...
setDelegate(someAction);
...