Archive for the 'Applications' Category

Using proccess specific APIs on threads

Gilad Ben-Yossef May 15th, 2008

A lot of POSIX API’s require a PID, or process ID, as a parameter. Sometime it is useful to use such an API on a thread, rather then a process.

Since Linux internally implements all processes and threads as tasks, one can use the Linux specific gettid(2) system call to get the “Thread ID” of a thread, which is really equal to a process PID, at least so much as to be useful as a parameter for a POSIX system call that requires a PID.

The use is Linux specific, non portable and it is not clear if it is a stable API or an undocumented coincidence. Use with care.

This post originally appeared in the Codefidence Technoblog

Determining PThread Library Type

Gilad Ben-Yossef May 15th, 2008

Linux kernel versions prior to 2.6 did not offer good internal support for threads. Therefore a threading library called LinuxThreads was used to provide most of the POSIX PThread API.

Since Linux 2.6 good threading support was added to the Linux kernel and a new library, called NPTL for New Posix Threading Library was created to provide scalable, robust POSIX compliant threading support in Linux.

As both libraries use the same POSIX API, code written for one will usually work with the other as is, but not always. It is therefore some time desirable to be able to learn in run time which threading library is being used.

The following code example shows how this can be done:

#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
 
int main(void)
{
char name[128];
confstr (_CS_GNU_LIBPTHREAD_VERSION, 
  name, sizeof(name));
printf ("Pthreads lib: %s\n", name);
return 0;
}

This post originally appeared in the Codefidence Technoblog

Using O_DIRECT

Gilad Ben-Yossef May 15th, 2008

It is sometime useful for a user program to request that to be able to read and write directly from a storage device. All DMA operation, if any, will be performed directly into the application memory space, without being going through the kernel page cache.

Here is a small code example showing how this can accomplished if proper support is provided by the file system and storage device.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fcntl.h>
#include <sys/mman.h>
 
static char * progname;
#define PAGE_SIZE (4096)
 
void usage(void) {
    printf("Usage: %s [filename]\n", progname);
    return;
}
 
int main(int argc, char * argv[]) {
 
    const char * filename;
    int fd, ret;
    char *buffer;
 
    progname = argv[0];
    if (argc != 2) {
        usage();
        exit(0);
    }
    filename = argv[1];
    ret = posix_memalign(&amp;buffer, 512, PAGE_SIZE);
    if(ret) {
      printf("%s: %s", progname, strerror(ret));
      exit(-5);
    }
    printf("%s: Got aligned buffer %p\n",
       progname, buffer);
    fd = open(filename, O_RDWR|O_CREAT|O_DIRECT,
        S_IRWXU);
    if(-1 == fd) {
        perror(progname);
        exit(-1);
    }
    strcpy(buffer, "testing testing 1 2 3!");
    ret = write(fd, buffer, PAGE_SIZE);
 
    if(-1 == ret) {
      perror(progname);
      exit(-2);
    }
 
        printf("%s: Written: %s\n", progname, buffer);
 
    lseek(fd, SEEK_SET, 0);
    ret = read(fd, buffer, PAGE_SIZE);
    if(-1 == ret) {
       perror(progname);
       exit(-2);
     }
 
    printf("%s: Got %s\n", progname, buffer);
    return 0;
}

This post originally appeared in the Codefidence Technoblog

« Prev