Question about pthreads & pointers - multithreading

Here is an example of thread creation code that is often seen. pthread_create uses a lot of pointers/addresses and I was wondering why this is so.
pthread_t threads[NUM_THREADS];
long t;
for(t=0; t<NUM_THREADS; t++){
rc = pthread_create(&threads[t], NULL, &someMethod, (void *)t);
}
Is there a major advantage or difference for using the '&' to refer to the variable array 'threads' as well as 'someMethod' (as opposed to just 'threads' and just 'someMethod')? And also, why is 't' usually passed as a void pointer instead of just 't'?

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
You need to pass a pointer to a pthread_t variable to pthread_create. &threads[t] and threads+t achieve this. threads[t] does not. pthread_create requires a pointer so it can return a value through it.
someMethod is a suitable expression for the third argument, since it's the address of the function. I think &someMethod is redundantly equivalent, but I'm not sure.
You are casting t to void * in order to jam a long into a void *. I don't think a long is guaranteed to fit in a void *. It's definitely a suboptimal solution even if the guarantee exists. You should be passing a pointer to t (&t, no cast required) for clarity and to ensure compatibility with the expected void *. Don't forget to adjust someMethod accordingly.
pthread_t threads[NUM_THREADS];
long t;
for (t=0; t<NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, someMethod, &t);
}

Related

Confused use of memcpy in ext2fs library

I am reading the source code implementation of libext2fs, which is part of the project e2fsprogs used to debug Ext2/3/4 file systems. And came across one confused point about the use of method memcpy as follows.
In the library, it maintains one function ext2fs_get_mem which is used to allocate dynamic memories:
_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
{
void *pp;
pp = malloc(size);
if (!pp)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &pp, sizeof (pp));
return 0;
}
The caller will call it like:
retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs)
In the above case, variable fs is just type of struct struct_ext2_filsys, all right.
The confused point is why the function ext2fs_get_mem need to call memcpy and what's the purpose? Why not directly allocate memory to the pointer void *ptr by malloc?

gtk 3.0 use the same callback for several switches

I'm creating a Linux GUI using GTK3.0 and C and I want to use the same callback for several switches. In order to differentiate the switch that was clicked, I am trying to use the gpointer argument in g_signal_connect, but the callback doesn't seem to receive the right value.
I create the signals this way:
g_signal_connect(led1_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED1");
g_signal_connect(led2_switch, "state-set", G_CALLBACK(on_gpio_btn_click), (gpointer)"LED2");
And the callback tries to get the gpointer passed:
static void on_gpio_btn_click(GtkWidget *wid, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
...
But when I debug the application, the ptr pointer has the value 0x1, a wrong memory address.
Shouldn't it point to the memory address where the constant string "LED1" is stored?
what am I doing wrong? How can I share the same callback for several widgets? I have 8 switches to control GPIOs and I would prefer to have one callback for all of them instead of creating eight.
Your function signature is wrong: the 2nd argument is the value of the switch's state, as can be found in the documentation of the "state-set" signal. That's also the reason why the value is 1: that's the actual value of TRUE.
In other words, your callback will like this:
static void on_gpio_btn_click(GtkSwitch *swtch, gboolean state, gpointer ptr)
{
int gpio;
int val = 0;
char *gpio_switch = ptr;
// ...
}

Linux kernel datastructures

I am new to module writing and need a circular buffer[1] and a vector. Since the Linux kernel apparently provides some data structures (lib) (list, trees), I was wondering if there is a vector equivalent?
While I think I am well capable to write my own, I prefer libraries for such things to prevent the duplication of code and to avoid errors.
[1] Found while composing the question, kfifo, also Queues in the Linux Kernel might be of interest.
As far as I know there is no implementation of vectors till 4.1 Linux kernel. And it does not make any sense to have one as vectors can be designed with the basic data structures whose implementation is already provided in Linux kernel.
I'm a bit late, but if anyone needs to implement a generalized vector in C, it can be done using void pointers and a sizeof operator on initialization. It would look something like this:
struct MyVec {
void *data;
size_t stored_sizeof;
size_t size;
size_t allocated_size
};
#define STARTING_ALLOCATED_SIZE 10
void MyVec_init(struct MyVec *self, size_t sizeof_data_type) {
self->stored_sizeof = sizeof_data_type;
self->data = malloc(self->stored_sizeof * STARTING_ALLOCATED_SIZE);
self->size = 0;
self->allocated_size = STARTING_ALLOCATED_SIZE;
}
void MyVec_deinit(struct MyVec *self) {
free(self->data);
}
bool MyVec_at(struct MyVec *self, size_t index, void *to_fill) {
if (index >= size)
return false;
memcpy(to_fill, self->data + (index * self->stored_sizeof), self->stored_sizeof);
return true;
}
and all the other methods that you might need, just being sure to use stored_sizeof whenever indexing, adding/removing elements, and the like.

Initializing empty polymorphic Singleton type without magic statics

Suppose you had a polymorphic Singleton type (in our case a custom std::error_category type). The type is stateless, so no data members, but it does have a couple of virtual functions. The problem arises when instantiating this type in a multithreaded environment.
The easiest way to achieve this would be to use C++11's magic statics:
my_type const& instantiate() {
static const my_type instance;
return instance;
}
Unfortunately, one of our compilers (VC11) does not support this feature.
Should I expect that this will explode in a multithreaded environment? I'm quite certain that as far as the standard goes, all bets are off. But given that the type does not contain any data members and only virtual functions, what kind of errors should I expect from a mainstream implementation like VC11? For example, neither Boost.System nor VC seem to take any precautions against this in their implementation of error_category. Are they just being careless or is it unreasonably paranoid to worry about races here?
What would be the best way to get rid of the data race in a standard-compliant way? Since the type in this case is an error_category I want to avoid doing a heap allocation if possible. Keep in mind that the Singleton semantics are vital in this case, since equality of error categories is determined by pointer-comparison. This means that for example thread-local storage is not an option.
Here is a possibly simpler version of Casey's answer, which uses an atomic spinlock to guard a normal static declaration.
my_type const& instantiate()
{
static std::atomic_int flag;
while (flag != 2)
{
int expected = 0;
if (flag.compare_exchange_weak(expected, 1))
break;
}
try
{
static my_type instance = whatever; // <--- normal static decl and init
flag = 2;
return instance;
}
catch (...)
{
flag = 0;
throw;
}
}
This code is also easier to turn into three macro's for reuse, which are easily #defined to nothing on platforms which support magic statics.
my_type const& instantiate()
{
MY_MAGIC_STATIC_PRE;
static my_type instance = whatever; // <--- normal static decl and init
MY_MAGIC_STATIC_POST;
return instance;
MY_MAGIC_STATIC_SCOPE_END;
}
Attempt #2b: Implement your own equivalent of std::once_flag, with an atomic<int> (Live at Rextester):
my_type const& instantiate() {
static std::aligned_storage<sizeof(my_type), __alignof(my_type)>::type storage;
static std::atomic_int flag;
while (flag < 2) {
// all threads spin until the object is properly initialized
int expected = 0;
if (flag.compare_exchange_weak(expected, 1)) {
// only one thread succeeds at the compare_exchange.
try {
::new (&storage) my_type;
} catch(...) {
// Initialization failed. Let another thread try.
flag = 0;
throw;
}
// Success!
if (!std::is_trivially_destructible<my_type>::value) {
std::atexit([] {
reinterpret_cast<my_type&>(storage).~my_type();
});
}
flag = 2;
}
}
return reinterpret_cast<my_type&>(storage);
}
This only relies on the compiler to correctly zero-initialize all static storage duration objects, and also uses the nonstandard extension __alignof(<type>) to properly align storage since Microsoft's compiler team can't be bothered add the keyword without the two underscores.
Attempt#1: Use std::call_once in conjunction with a std::once_flag (Live demo at Coliru):
my_type const& instantiate() {
struct empty {};
union storage_t {
empty e;
my_type instance;
constexpr storage_t() : e{} {}
~storage_t() {}
};
static std::once_flag flag;
static storage_t storage;
std::call_once(flag, []{
::new (&storage.instance) my_type;
std::atexit([]{
storage.instance.~my_type();
});
});
return storage.instance;
}
The default constructor for std::once_flag is constexpr, so it's guaranteed to be constructed during constant initialization. I am under the impression [citation needed] that VC correctly performs constant initialization. EDIT: Unfortunately, MSVC up through VS12 still doesn't support constexpr, so this technique has some undefined behavior. I'll try again.
The standard is silent on the question of how statics are constructed when the function is called on multiple threads.
gcc uses locks to make function level statics threadsafe (can be disabled by a flag). Most (all?) versions of Visual C++ do NOT have threadsafe function level statics.
It is recommended to use a lock around the variable declaration to guarantee thread-safety.

user defined struct can't be passed through tid.send

I have created a mutlithreaded simulator that relies heavily on the native message passing between threads (don't go telling me to go single threaded it's for my thesis on D and I need to get this to work)
after a very durty kludge involving a lot of casts of objects to and from shared. which prolly had some ugly race condition bugs. I decided to create an opaque type that represents an object that can receive messages that should be able to be passed around without all that casting...
no such luck
struct OpaqueFaseSim{
Tid tid;
void send(...){...}
}
void foo(){
Tid tid;
long time;
OpaqueFaseSim ofs;
//...
tid.send(ofs,time);//Error: static assert "Aliases to mutable thread-local data not allowed."
}
why can I pass a Tid around but not a struct containing only a Tid?
and how can I fix this
I think it's because Tid has a MessageBox field which is a class type.
You can type OpaqueFaseSim's tid field as shared or ___gshared and it will work:
struct OpaqueFaseSim{
Bar bar;
shared Tid tid;
// __gshared Tid tid;
}

Resources