Click here to Skip to main content
13,772,645 members
Click here to Skip to main content
Add your own
alternative version

Stats

7.6K views
5 bookmarked
Posted 5 Jan 2016
Licenced CPOL

Atomic Function Calls

, 5 Jan 2016
Rate this:
Please Sign up or sign in to vote.
Call a function atomically with a generic template

Quickly to the Point

#include <thread>
#include <cstdio>
using namespace std;

void foo()
 {
 printf("Goodbye world.\r\n");
 }

int main()
 {
 thread t1(foo);
 thread t2(foo);
 t1.join();
 t2.join();
 }

Very simple. You would expect:

Goodbye world.
Goodbye world.

and it did work in YOUR PC, but in your customer's PC, this is what happened:

Goodbye woGoodbyrld.
e world.

The reason of course is that the calls to printf() were simultaneous. How to make them atomic?

Template Solution

#include <thread>
#include <cstdio>
using namespace std;

static std::recursive_mutex InterlockedCallMutex;
template <typename R,typename... Args>
R InterlockedCall(void* pfoo,Args... args)
    {
    std::lock_guard<std::recursive_mutex> lock(InterlockedCallMutex);
    typedef R(__stdcall * function_pointer)(Args...);
    function_pointer P = (function_pointer)pfoo;
    const auto return_value = (*P)(std::forward<Args>(args)...);
    return (R)return_value;
    }

void foo()
 {
 InterlockedCall<int,const char*>(printf,"Goodbye world.\r\n");
 }

int main()
 {
 thread t1(foo);
 thread t2(foo);
 t1.join();
 t2.join();
 }

This also works with a void-returning function, for return (void)return_value is valid.

Perhaps for integer-returning functions, which are the most common, you might want to specialize:

template <typename... Args>
size_t InterlockedCall(void* pfoo,Args... args)
    {
    std::lock_guard<std::recursive_mutex> lock(InterlockedCallMutex);
    typedef size_t(__stdcall * function_pointer)(Args...);
    function_pointer P = (function_pointer)pfoo;
    const auto return_value = (*P)(std::forward<Args>(args)...);
    return (size_t)return_value;
    }

Now, you can call without the types in the <>, because they are automatically deduced:

void foo()
 {
 InterlockedCall<>(printf,"Goodbye world.\r\n");
 }

A Catch

It works only for __cdecl calling convention. You must create another template for __stdcall or other conventions.

History

  • 05/01/201: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael Chourdakis
Engineer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS and Android.

I 've a PhD in Digital Signal Processing and Artificial Intelligence and I specialize in Pro Audio and AI applications.

My home page: http://www.michaelchourdakis.com

You may also be interested in...

Comments and Discussions

 
Questionbuild a test application and failed.... Pin
YDLU7-Sep-18 11:02
memberYDLU7-Sep-18 11:02 
Suggestion[My vote of 1] I do not understand what it should be! Pin
AlBundyLoves696-Jan-16 3:07
professionalAlBundyLoves696-Jan-16 3:07 
GeneralRe: [My vote of 1] I do not understand what it should be! Pin
Michael Chourdakis6-Jan-16 5:21
mvpMichael Chourdakis6-Jan-16 5:21 
GeneralRe: [My vote of 1] I do not understand what it should be! Pin
AlBundyLoves696-Jan-16 5:29
professionalAlBundyLoves696-Jan-16 5:29 
GeneralRe: [My vote of 1] I do not understand what it should be! Pin
Michael Chourdakis6-Jan-16 5:35
mvpMichael Chourdakis6-Jan-16 5:35 
QuestionNot generally a good idea. PinPopular
William E. Kempf5-Jan-16 12:11
memberWilliam E. Kempf5-Jan-16 12:11 
AnswerRe: Not generally a good idea. Pin
Michael Chourdakis5-Jan-16 12:17
mvpMichael Chourdakis5-Jan-16 12:17 
GeneralRe: Not generally a good idea. Pin
AlBundyLoves696-Jan-16 3:28
professionalAlBundyLoves696-Jan-16 3:28 
GeneralRe: Not generally a good idea. Pin
Michael Chourdakis6-Jan-16 5:40
mvpMichael Chourdakis6-Jan-16 5:40 
GeneralRe: Not generally a good idea. Pin
William E. Kempf6-Jan-16 3:33
memberWilliam E. Kempf6-Jan-16 3:33 
PraiseRe: Not generally a good idea. Pin
AlBundyLoves696-Jan-16 3:22
professionalAlBundyLoves696-Jan-16 3:22 
GeneralRe: Not generally a good idea. Pin
William E. Kempf6-Jan-16 3:36
memberWilliam E. Kempf6-Jan-16 3:36 
GeneralRe: Not generally a good idea. Pin
Michael Chourdakis6-Jan-16 5:45
mvpMichael Chourdakis6-Jan-16 5:45 
PraiseSimple and Clean Pin
balasubramanian.m5-Jan-16 11:09
memberbalasubramanian.m5-Jan-16 11:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.181119.1 | Last Updated 5 Jan 2016
Article Copyright 2016 by Michael Chourdakis
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid