next up previous contents index
Next: 18.4.1 oskit_wrap_socket: Wrap an Up: 18 POSIX Threads: liboskit_threads.a Previous: 18.3.46 osenv_process_unlock: Unlock the

18.4 Thread-safe Adaptors

 

To facilitate the use of the device driver framework within a multithreaded client operating system, a number of adaptors are provided. An adaptor acts as COM interface wrapper on another COM interface. Adaptors are intended to provide thread-safety with respect to the device driver framework. The thread system is expected to provide an implementation of a process lock that is used to prevent concurrent execution inside the device driver framework. An adaptor method simply takes the process lock, calls the appropriate method in the underlying COM interface, and then releases the process lock when the method returns. If a thread blocks inside a device driver (osenv_sleep), the process lock is released at that time, allowing another thread to enter the driver set. When the original thread is woken up, it will reacquire the process lock before being allowed to return from the sleep. Thus, only one thread is allowed to operate inside the driver set at a time.

Implementationally, an adaptor is a COM interface that maintains a reference to the original, non thread-safe COM interface. Operations using the adaptor behave just like the original, invoking the corresponding method in the original. It should be noted that the query, addref, and release methods all operate on the adaptor itself. When the last reference to an adaptor is released, the reference to the underlying COM interface is released. As an example, consider the oskit_dir_t adaptor as it is used when mounting the root filesystem in a multithreaded client operating system. In order to provide a thread-safe implementation to the C library, the root directory that is passed to fs_init is first wrapped up in a thread-safe adaptor. All subsequent references to the corresponding filesystem go through the adaptor, and are thus thread-safe. A sample code fragment follows:

#include <oskit/c/fs.h>
#include <oskit/com/wrapper.h>
#include <oskit/threads/pthread.h>

oskit_error_t
mountroot(oskit_dir_t *fsroot)
{
    oskit_dir_t    *wrappedroot;
    oskit_error_t  err;

    rc = oskit_wrap_dir(fsroot,
                (void (*)(void *))osenv_process_lock, 
                (void (*)(void *))osenv_process_unlock,
                0, &wrappedroot);
    if (rc)
        return rc;

    /* Don't need the root anymore, the wrapper has a ref. */
    oskit_dir_release(fsroot);

    return fs_init(wrappedroot);
}

The adaptor prototypes are found in <oskit/com/wrapper.h>, and have a common format. Each one takes the COM interface to be wrapped up, and returns the adaptor. Additional arguments are the process lock and unlock routines, as well as an optional cookie to be passed to the lock and unlock routines. It should be noted that the process lock is specific to the thread implementation, and thus the adaptor interface is intended to be as generic as possible. For the pthread interface, the process lock does not need a cookie value.




next up previous contents index
Next: 18.4.1 oskit_wrap_socket: Wrap an Up: 18 POSIX Threads: liboskit_threads.a Previous: 18.3.46 osenv_process_unlock: Unlock the

University of Utah Flux Research Group