call_once()

Updated: April 19, 2023

Dynamic package initialization

Synopsis:

#include <threads.h>

void call_once( once_flag *flag,
                void (*func)(void) );

Arguments:

once_flag
A pointer to a once_flag object that the function uses to determine whether or not to run the initialization code.
Note:
  • You must set the once_flag object to ONCE_FLAG_INIT before using it for the first time.
  • It's always safe, and typically faster, to assure that once_flag is 32-bit aligned.
func
The function that you want to call to do any required initialization.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The call_once() function uses the once-control object once_flag to determine whether the initialization routine func should be called.

CAUTION:
You should allocate the control object only in normal memory mappings. Doing otherwise will cause a fault on certain processors.

The first call to call_once() by any thread in a process, with a given once_flag, calls func with no arguments. Subsequent calls of call_once() with the same once_flag won't call func.

Note: No thread will execute past this function until the func returns.

Examples:

This example shows how you can use once-initialization to initialize a library; both library_entry_point1() and library_entry_point2() need to initialize the library, but that needs to happen only once:

#include <stdio.h>
#include <pthread.h>

once_flag once_flag = ONCE_FLAG_INIT;

void library_init( void )
{
    /* initialize the library */
}

void library_entry_point1( void )
{
    call_once( &once_flag, library_init );
    
    /* do stuff for library_entry_point1... */
}

void library_entry_point2( void )
{
    call_once( &once_flag, library_init );
    
    /* do stuff for library_entry_point2... */
}

This initializes the library once; if multiple threads call call_once(), only one actually enters the library_init() function. The other threads block at the call_once() call until library_init() has returned. The call_once() function also ensures that library_init() is only ever called once; subsequent calls to the library entry points skip the call to library_init().

Classification:

C11

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes