r6:Function:abstraction thread start

From liblfds.org
Jump to navigation Jump to search

Source Files

/test/src/abstraction_thread_start.c
/test/src/abstraction.h

Prototype

int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state );

Parameters

thread_state_t *thread_state

The address of a thread_state_t into which the thread state will be placed. Thread states are operating systems defined types (such as a HANDLE under Windows, or a pthread_t under pthreads) and these are allocated on the heap or the stack by the user and the address of the variable is passed.

unsigned int cpu

The CPU number this thread should show affinity to. This will be a value from 0 to one less than the value returned by abstraction_cpu_count. Not all systems can set CPU affinity; as such, this behaviour is desirable but not essential. If your system can set the thread affinity, do so; it makes for a better test. If not, then the test relies on the operating system balancing the threads out over CPUs.

thread_function_t thread_function

The thread function. The function pointer type will automatically be correct for your platform if thread_return_t is correctly set and if your platform's thread function prototype takes a single void pointer as an argument. If your thread function prototypes takes a different set of arguments, the test program will not in its current form compile on your platform.

void *thread_user_state

A single void pointer of user state which is passed into the thread function.

Return Value

Returns 1 on successful thread start. Returns 0 on failure.

Notes

This function provides the test program with a way to start a thread. It is assumed that the thread function prototype takes a single void pointer as an argument (this is true for Windows and pthreads). The return value of the thread function is specified by the thread_return_t typedef and the combination of the assumed single void pointer argument and thread_return_t leads to the thread_function_t typedef being correct.

Examples

Under Windows (32-bit and 64-bit), using the Microsoft C compiler, the function CreateThread is used to create threads and this function has following prototype;

HANDLE WINAPI CreateThread( __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
                            __in       SIZE_T dwStackSize,
                            __in       LPTHREAD_START_ROUTINE lpStartAddress,
                            __in_opt   LPVOID lpParameter,
                            __in       DWORD dwCreationFlags,
                            __out_opt  LPDWORD lpThreadId );

Furthermore, there is also the function SetThreadAffinityMask which is used to assign CPU affinity to threads, which has the following prototype;

DWORD_PTR WINAPI SetThreadAffinityMask( __in  HANDLE hThread,
                                        __in  DWORD_PTR dwThreadAffinityMask );

As such, the implementation of abstraction_thread_state() on user-mode Windows, for all CPUs, using the Microsoft C compiler, looks like this;

#if (defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)

  /* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler

           _WIN32             indicates 64-bit or 32-bit Windows
           _MSC_VER           indicates Microsoft C compiler
           !WIN_KERNEL_BUILD  indicates Windows user-mode
  */

  int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
  {
    int
      rv = 0;

    DWORD
      thread_id;

    DWORD_PTR
      affinity_mask,
      result;

    assert( thread_state != NULL );
    // TRD : cpu can be any value in its range
    assert( thread_function != NULL );
    // TRD : thread_user_state can be NULL

    affinity_mask = (DWORD_PTR) (1 << cpu);

    *thread_state = CreateThread( NULL, 0, thread_function, thread_user_state, NO_FLAGS, &thread_id );

    result = SetThreadAffinityMask( *thread_state, affinity_mask );

    if( *thread_state != NULL and result != 0 )
      rv = 1;

    return( rv );
  }

#endif

See Also