Linux Device Drivers

Linux Device Drivers


Linux
Modules
Character drivers
IO & Memory
Linux Kernel
Process Management
Process Address space

Linux Scheduler
Memory Management
Interrupts
Signals
System Calls
Kernel Synchronization
Linux Inter Process Communications




Serial Ports
Parallel Ports
Introduction to Hardware
Linux Timers
DMA in Linux
Linux Threads
Linux Thread Synchronization

Linux Multi Threading
Debugging in Linux
GDB GNU Debugger
KDB Kernel Debugger
KGDB Kernel GNU Debugger
Example Ethernet Driver




Threads

Threads

 

In the traditional Unix model, when a process needs something performed by another entity, it forks a child process. There are problems with a fork:

 

ü     Fork is expensive. Memory is copied from the parent to the child, all the descriptors are duplicated in the child. Current implementation use a technique called copy-on-write, which avoids a copy of the parent’s data space to the child until the child needs its own copy.

ü     Intrer-process-communication is required to pass information between the parent and child after the fork.

 

Threads help with both problems. Threads are sometimes called lightweight processes. That’s is a thread creation can be 10-100 times faster than process creation time.

 

All threads with in a process share the same global memory. This makes the sharing of information easy between the threads, but along with this simplicity comes the problem of synchronization.

 

All threads with in a process share:

ü     Process instructions

ü     Most data

ü     Open files (e.g. descriptors)

ü     Signal handlers

ü     Current working directory

ü     User and group Ids

 

But each thread has its own:

ü     Thread ID

ü     Set of registers, including program counter and stack pointer

ü     Stack (for local variables and return addresses)

ü     Errno

ü     Signal mask

ü     Priority

 

pthreadsLibrary

 

Linux implements the POSIX standard thread API (known as pthreads). All thread functions and data types are declared in the header file <pthread.h>.

 

The pthread functions are not included in the standard C library. Instead, they are in libpthread, so you should add -lpthreadto the command line when you link your program.

 

pthread_create

 

When a program is started by exec, a single thread is created, called the initial thread or main thread. Additional threads are created by pthread_create.

 

#include <pthread.h>

intpthread_create(pthread_t*tid, const pthread_attr_t*attr,

void *(*func) (void *), void *arg);

Returns 0 if OK, positive Exxxvalue on Error

 

Each thread within a process is identified by a thread ID, whose data type is pthread_t. On successful creation of a new thread, its ID is returned through the pointer tid.

 

Each thread has numerous attributes: its priority, its initial stack size, whether it should be daemon thread or not, and so on. When a thread is created, we can specify these attributes by initializing a pthread_attr_t variable that overrides the default. We normally take the default, we specify the attr argument as a null pointer.

 

When we create a thread, we specify a function for it to execute, called its thread start function. The thread starts by calling this function and then terminates either explicitly (by calling pthread_exit) or implicitly (by letting this function return).

 

The address of the function is specified as the func argument, and this function is called with a single pointer argument, arg.

 

pthread_join

 

We can wait for a given thread to terminate by calling pthread_join.

Comparing threads to Unix processes, pthread_createis similar to fork, and pthread_joinis similar to waitpid.

 

#include <pthread.h>

int pthread_join(pthread_t tid, void **status);

 

Returns 0 if OK, positive Exxxvalue on error

 

pthread_self

 

Each thread has an ID that defines it with in a given process. The thread ID is returned by pthread_create. A thread fetches this value for itself using pthread_self.

 

#include <pthread.h>

pthread_t pthread_self(void);

 

Returns thread ID of calling thread

 

pthread_detach

 

A thread is either joinable (the default) or detached. When a joinable thread terminates its thread ID and exit status are retained until another thread in the process calls pthread_join. But a detached thread is like a daemon process: when it terminates, all its resources are released, and we cannot wait for it to terminate.

 

#include <pthread.h>

int pthread_detach(pthread_t tid);

 

Returns 0 if OK, positive Exxx value on error

 

pthread_exit

 

One way for a thread to terminate is to call pthread_exit.

 

#include <pthread.h>

void pthread_exit(void *status);

 

Does not return to caller

If the thread is not detached, its thread ID and exit status are retained for a later pthread_join by some other thread in the calling process.