Programming


C/C++: Set and Get the name of a pthread

Naming a pthread using meaningful names, can be a very useful feature for debugging multi-threaded applications as it can make your logs very informative.
For this reason, we are presenting two examples demonstrating the use of names in pthreads.

  • [download id=”3786″]
  • [download id=”3788″]

Example 1: The pthread decides for its name

The following code, creates a pthread which later, it will give itself a meaningful name.

[download id=”3786″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    const int setname_rv = pthread_setname_np(thread_info->thread_id, "Tom Hanks");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and I gave me my name by myself\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }
    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3786″]

Example 2: The parent decides for the pthread name

The next code, creates a pthread and the parent gives the thread a meaningful name.

[download id=”3788″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <unistd.h> is needed for the resolution of unsigned int sleep(unsigned int seconds);
#include <unistd.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    //Added an artificial delay for the sake of the example.
    //Making sure the parent thread gave the pthread a name.
    sleep(1);

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and my parent gave me my name\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }

    const int setname_rv = pthread_setname_np(thread_info.thread_id, "Bob Marley");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3788″]


Forcing user to remove trailing spaces in git

There are simple ways to force the user in removing trailing spaces before committing code in git using hooks.
Below we will present a solution that is applied at the local computer before the commit stage, which each developer needs to perform in each repository clone they own.
Note: If you would like to have the hooks on the server, you will need extra access rights to modify the hooks on the remote machine, maybe you will even need your systems administrator to configure it.

Solution

Attached you will find a file named pre-commit ([download id=”3933″]) it is a hook that get applied before the user is allowed to even commit.
That file you need to copy it (after you extract it) in the .git/hooks folder of your cloned repositories and you are done!

What this script does is simple, if there are whitespace errors, it prints the offending file names and fails.
What are considered whitespace errors is controlled by core.whitespace configuration.
By default, trailing whitespaces (including lines that solely consist of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors.

In case you need to commit files that have whitespace errors, you can bypass the checks that are applied by the hooks using the --no-verify flag as follows:

git commit -m "Some informative message" --no-verify;

There are more ways to achieve this result, others are more verbose but this one is the simplest and more flexible as you can configure it using the git configuration variables.

[download id=”3933″]

#!/bin/sh
#
# This hook script verifies that there are no whitespace errors in the files to be committed

if git rev-parse --verify HEAD >/dev/null 2>&1
then
 against=HEAD
else
 # Initial commit: diff against an empty tree object
 against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Redirect output to stderr.
exec 1>&2

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

[download id=”3933″]


C/C++: Change position of bytes 1 and 2 with bytes 3 and 4 in a 32bit unsigned integer

The following function will produce a new 32bit value where bytes 1 and 2 were moved in place of bytes 3 and 4 and vice versa.

[download id=”3642″]

#include <stdio.h>
#include <stdlib.h>

const unsigned int move_bytes_1_2_after_4 (const unsigned int input) {
  //We get the two leftmost bytes and move them to the positions of the two rightmost bytes.
  const unsigned int first_two_bytes = (input >> 16) & 0x0000FFFF;
  //We get the two rightmost bytes and move them to the positions of the two leftmost bytes.
  const unsigned int last_two_bytes = (input << 16) & 0xFFFF0000;
  //We combine the two temporary values together to produce the new 32bit value where bytes 1 and 2 were moved in place of bytes 3 and 4 and vice versa.
  return (first_two_bytes | last_two_bytes);
}

int main(void) {
  const unsigned int value = 0xABCD0123;
  printf ("Original: 0x%08x\n", value);
  const unsigned int modified = move_bytes_1_2_after_4(value);
  printf ("Modified: 0x%08x\n", modified);
  return EXIT_SUCCESS;
}

Executing the above code will produce the following output:

Original: 0xabcd0123
Modified: 0x0123abcd

[download id=”3642″]