Porting InterlockedExchange, using GCC intrinsics only - c

Windows API offers InterlockedExchange, which sets a value in memory atomically. Using only GCC intrinsics, I’d like to create an equivalent of that function. Would setting the value and then calling a memory barrier be sufficient (see the code below) ?
template <typename T>
T InterlockedExchange(volatile T& _data, T _value)
{
const T oldValue = _data;
_data = _value;
__sync_synchronize();
return oldValue;
}
Thank you.
EDIT: The proposed snippet is NOT a correct solution to the problem, as it is clearly not atomic (but, well, I had to give a try at least).

Use __sync_val_compare_and_swap __sync_lock_test_and_set, not __sync_synchronize.
This has exactly the same function as InterlockedExchange.
Something like this (untested code!):
template<typename T> T InterlockedExchange(T& data, T& new_val)
{
return __sync_lock_test_and_set(&data, new_val);
}
EDIT:
Oi, I read wrong, you wanted InterlockedExchange, not InterlockedCompareExchange ... so that is __sync_lock_test_and_set (the name is a misleading Intel-nomer, but it's exactly what you want).
See here, bottom of the page.

Your proposed example is not equivalent, because it is not atomic. Two racing threads executing your function can both retrieve the same old value, with one of the new values being "lost".

Related

if/else strive for logical completeness in single return function

I'm attempting to exist at the crossroads of MISRA C and CERT C and setting the lofty goal of no exceptions. The two rules most against my normal patterns are (paraphrased):
MISRA : A function should only have one return
CERT : Strive for logical completeness
The CERT rule keeps catching me when I have nothing to say in an else. For example:
static int32_t SomeFunc()
{
int32_t retval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval == PROJECT_SUCCESS)
{
retval = ChildFuncTwo();
}
//Common cleanup
return retval;
}
Assuming there is no specific cleanup for the failure of ChildFuncOne, I have nothing to say in else. Am I missing another way to lay out this function?
Option 1 is an else with an empty body:
static int32_t SomeFunc(void)
{
int32_t retval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval == PROJECT_SUCCESS)
{
retval = ChildFuncTwo();
}
else
{
// yes, I did consider every possible retval
}
//Common cleanup
return retval;
}
Option 2 is to add a second variable, and then set that variable in the if and the else. Note that I reversed the sense of the if, since that order makes more sense to me. YMMV.
static int32_t SomeFunc2(void)
{
int32_t retval = PROJECT_ERROR_GENERIC;
int32_t finalretval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval != PROJECT_SUCCESS)
{
finalretval = retval;
}
else
{
finalretval = ChildFuncTwo();
}
//Common cleanup
return finalretval;
}
The problem with option 2 is that it's easy to mix up the two variables that have similar names and uses. Which is where these coding standards make your code more likely to have bugs, rather than less.
The only problem with your code I can find is the obsolescent style function definition. static int32_t SomeFunc() should be static int32_t SomeFunc(void). The former has been obsolescent form in C since some 25-30 years back and also violates MISRA 8.2 for that reason. Other than that, the code is fine and MISRA compliant.
A style comment beyond MISRA is that I would use an enum over int32_t.
Regarding CERT I assume you refer to MSC01-C. This is a fuzzy and unclear rule, with just a bunch of non-related code examples. I would just ignore it.
The corresponding MISRA C:2012 15.7 and 16.1 are much clearer and can be summarized as:
All else if should end with an else.
All switch should contain default.
The rationale is defensive programming and self-documenting code: "yes, I have definitely considered this outcome". Likely this is what CERT C tried (and failed) to say as well. They refer to various "else if with else" rules in their crossref.
This isn't applicable to your code. Nobody requires that every if ends with an else, that would be a ridiculous requirement.
Am I missing another way to lay out this function?
It's sound practice to set the result variable to a known default state at the beginning of a function and later overwrite it if needed. So your function is not only compliant, but also fairly canonical style as safety-related programming goes.
So other than the () to (void), there's no need to change a thing.
My attempt:
static int32_t SomeFunc()
{
int32_t retval = ChildFuncOne();
retval = (retval == PROJECT_SUCCESS)? ChildFuncTwo() : retval;
retval = (retval == PROJECT_SUCCESS)? ChildFuncThree() : retval;
return retval;
}
Basically, the retval is set by the first function, and only if that result is PROJECT_SUCCESS, will the second function get called and set the retval.
If the retval is anything other than success, it remains unchanged, the second function is never called, and retval is returned.
I even show how it can be chained for an arbitrary number of functions.
I'm a bit unclear what you mean bye "common cleanup", so if you need different cleanup operations depending on what functions succeeded and failed, that will take extra work.
You should stop trying to appease the MISRA and CERT gods and just write clear code. The code that you posted is fine. Keep it that way.

Force if statement to execute only once

I have a piece of code that will be executed many times (5,000+), and an if statement that will be true only the first time. I've thought of using a "FIRST" variable and compare it each time, but it just seems like a waste to check it every single time, even if I know it's not needed.
bool FIRST = true;
void foo(){
if(FIRST){
/* do something only once */
FIRST = false;
}
/* something something... */
}
I also don't know if there is some compiler optimization that does this automatically, or another way to do it; if there is, please let me know.
And yes, I know that a mere if statement isn't a big thing, but it just annoys me.
If you're using gcc, there are macros called unlikely and likely that can allow it to make optimizations based on a condition.
In your case the condition will only be true the first time, so you would use unlikely:
if (unlikely(FIRST)) {
From a compiler optimization point of view, I think an if statement is your best bet, as it will probably compile down to something like a single JNZ, so as long as FIRST stays true, it will be pretty optimized.
You might also want to take a look at this thread
You can call the function via a function pointer and remove the if check on the second call by changing the function pointer to a function without the if:
void foo_init(void);
void foo_real(void);
void (*foo)(void) = foo_init;
void foo_init(void) {
foo = foo_real;
/* do something only once */
foo_real();
}
void foo_real(void) {
/* something something... */
}
int main() {
foo();
foo();
}
Make foo and fooFirst, and then call like this
fooFirst();
for (...) {
foo();
}
foo and fooFirst can share code.

Linux Kernel defines everywhere

On linux's kernel we can find this piece of code in linux/sched.h, when I saw it some doubts came to my mind:
Why using define to create functions? Why not using the normal return-type function-name(par1, par2) {} style?
What is the point with the do {} while(0)?
#define set_special_state(state_value)
do {
unsigned long flags;
raw_spin_lock_irqsave(&current->pi_lock, flags);
current->state = (state_value);
raw_spin_unlock_irqrestore(&current->pi_lock, flags);
} while (0)
#endif
This isn't a "function", it's a preprocessor macro.
Sometimes one must use macros to do things that the C language itself doesn't support (usually generating code). This doesn't look like one of those cases though, and should probably be a static inline function. Pergaps the Git history would explain why it is the way it is.
do { ... } while (0) is a common method for swallowing the semicolon which follows a call to a C-function-looking macro like this one.
Functions are usually preferrable because they provide type checking and aren't error prone to things like double evaluation, but macros are more powerful, since they allow you to work at the text/token level.
do{}while(0) is to make an invoked macro grammatically behave like a void-returning function call.
You might think a plain pair of curlies would do that but that doesn't work
with if-else
#define macro_with_curlies() { }
if(x) macro_with_curlies(); else { }
//expands to: if(x) { }; /*else is illegal after the semicolon*/ else { }

Shared pointers and queues in FreeRTOS

A C++ wapper around a FreeRTOS queue can be simplified into something like this:
template<typename T>
class Queue<T>
{
public:
bool push(const T& item)
{
return xQueueSendToBack(handle, &item, 0) == pdTRUE;
}
bool pop(T& target)
{
return xQueueReceive(handle, &target, 0) == pdTRUE;
}
private:
QueueHandle_t handle;
}
The documentation of xQueueSendToBack states:
The item is queued by copy, not by reference.
Unfortunately, it is literally by copy, because it all ends in a memcpy, which makes sense since it is a C API. While this works well for plain old data, more complex items such as the following event message give serious problems.
class ConnectionStatusEvent
{
public:
ConnectionStatusEvent() = default;
ConnectionStatusEvent(std::shared_ptr<ISocket> sock)
: sock(sock)
{
}
const std::shared_ptr<ISocket>& get_socket() const
{
return sock;
}
private:
const std::shared_ptr<ISocket> sock;
bool connected;
};
The problem is obviously the std::shared_ptr which doesn't work at all with a memcpy since its copy constructor/assignment operator isn't called when copied onto the queue, resulting in premature deletion of the held object when the event message, and thus the shared_ptr, goes out of scope.
I could solve this by using dynamically allocated T-instances and change the queues to only contain pointers to the instance, but I'd rather not do that since this shall run on an embedded system and I very much want to keep the memory static at run-time.
My current plan is to change the queue to contain pointers to a locally held memory area in the wrapper class in which I can implement full C++ object-copy, but as I'd also need to protect that memory area against multiple thread access, it essentially defeats the already thread-safe implementation of the FreeRTOS queues (which surely are more efficient than any implementation I can write myself) I might as well skip them entirely.
Finally, the question:
Before I implement my own queue, are there any tricks I can use to make the FreeRTOS queues function with C++ object instances, in particular std::shared_ptr?
The issue is what happens to the original once you put the pointer into the queue.
Copying seems trivial but not optimal.
To get around this issue i use a mailbox instead of a queue:
T* data = (T*) osMailAlloc(m_mail, osWaitForever);
...
osMailPut (m_mail, data);
Where you allocate the pointer explicitly to begin with. And just add the pointer to the mailbox.
And to retrieve:
osEvent ev = osMailGet(m_mail, osWaitForever);
...
osStatus freeStatus = osMailFree(m_mail, p);
All can be neatly warpend into c++ template methods.

Ruby C API `defined? SomeConstant` equivalent?

I'm trying to convert an if condition of:
unless defined? SomeConstant
# do some stuff
end
Into part of a native C extension. Does anybody know how to do the defined? predicate check in the C API?
EDIT | I guess I could invoke:
rb_funcall(rb_cObject, rb_intern("const_defined?"), 1, rb_intern("SomeConstant"))
Though this is obviously slightly different, semantically.
If you trace through the 1.9.3 source, you'll find that defined? is implemented in insns.def:
DEFINE_INSN
defined
(rb_num_t op_type, VALUE obj, VALUE needstr)
/* ... */
switch (type) {
/* ... */
case DEFINED_CONST:
klass = v;
if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
expr_type = "constant";
}
break;
So when you defined? SomeConstant, you trickle through that big switch and end up calling vm_get_ev_const. The function is defined in vm_insnhelper.c:
static inline VALUE
vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq,
VALUE orig_klass, ID id, int is_defined)
That function happens to be static so you can't get at it. Looks like vm_get_ev_const is defined in terms of rb_const_defined and rb_const_defined_from and both of those should be available in your C so you could try those; but you'd have to find the right klass for those.
Or you could go with your idea and just use Object.const_defined?. One problem with that is that it won't do The Right Thing with things like A::B, you'd have to say Object.const_defined? :A && A.const_defined? :B for that as Object.const_defined? :'A::B' will just throw an exception in your face. A general solution here would require iteration and class lookups. However, if the classes that you're looking at are all in the top level namespace, then a simple Object.const_defined? should do the trick.

Resources