Lazy Foo' Productions

SDL Forums external link SDL Tutorials Articles OpenGL Tutorials OpenGL Forums external link
Follow BlueSky Follow Facebook Follow Twitter Follow Threads
Donate
News FAQs Contact Bugs

Atomic Operations

Atomic Operations screenshot

Last Updated: May 28th, 2024

Semaphores operate at an operating system level. Atomic operations are a way to lock data at an efficient CPU level. Here we'll be locking a critical section using CPU spinlocks.
//Data access spin lock
SDL_SpinLock gDataLock = 0;

//The "data buffer"
int gData = -1;
Instead of a semaphore we'll be using a spinlock to protect our data buffer.
bool loadMedia()
{
    //Loading success flag
    bool success = true;
    
    //Load splash texture
    if( !gSplashTexture.loadFromFile( "48_atomic_operations/splash.png" ) )
    {
        printf( "Failed to load splash texture!\n" );
        success = false;
    }

    return success;
}

void close()
{
    //Free loaded images
    gSplashTexture.free();

    //Destroy window    
    SDL_DestroyRenderer( gRenderer );
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;
    gRenderer = NULL;

    //Quit SDL subsystems
    IMG_Quit();
    SDL_Quit();
}
Unlike semaphores, spin locks do not need to be allocated and deallocated.
int worker( void* data )
{
    printf( "%s starting...\n", data );

    //Pre thread random seeding
    srand( SDL_GetTicks() );
    
    //Work 5 times
    for( int i = 0; i < 5; ++i )
    {
        //Wait randomly
        SDL_Delay( 16 + rand() % 32 );
        
        //Lock
        SDL_AtomicLock( &gDataLock );

        //Print pre work data
        printf( "%s gets %d\n", data, gData );

        //"Work"
        gData = rand() % 256;

        //Print post work data
        printf( "%s sets %d\n\n", data, gData );
        
        //Unlock
        SDL_AtomicUnlock( &gDataLock );

        //Wait randomly
        SDL_Delay( 16 + rand() % 640 );
    }

    printf( "%s finished!\n\n", data );

    return 0;
}
Here our critical section is protected by SDL_AtomicLock and SDL_AtomicUnlock.

In this case it may seem like semaphores and atomic locks are the same, but remember that semaphores can allow access beyond a single thread. Atomic operations are for when you want a strict locked/unlocked state.