/* 
 *------------------------------------------------------------------
 * svm.c - shared VM allocation, mmap(...MAP_FIXED...) 
 * library
 *
 * Copyright (c) 2009 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/fifo.h>
#include <vppinfra/time.h>
#include <vppinfra/mheap.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>

#include "svm.h"

static svm_region_t *root_rp;
static int root_rp_refcount;

#define MAXLOCK 2
static pthread_mutex_t *mutexes_held [MAXLOCK];
static int nheld;

svm_region_t *svm_get_root_rp (void)
{
    return root_rp;
}

#define MUTEX_DEBUG

static void region_lock(svm_region_t *rp, int tag)
{
    pthread_mutex_lock(&rp->mutex);
#ifdef MUTEX_DEBUG
    rp->mutex_owner_pid = getpid();
    rp->mutex_owner_tag = tag;
#endif    
    ASSERT(nheld < MAXLOCK);
    /* 
     * Keep score of held mutexes so we can try to exit
     * cleanly if the world comes to an end at the worst possible
     * moment
     */
    mutexes_held [nheld++] = &rp->mutex;
}

static void region_unlock(svm_region_t *rp)
{
    int i,j;
#ifdef MUTEX_DEBUG
    rp->mutex_owner_pid = 0;
    rp->mutex_owner_tag = 0;
#endif    

    for (i = nheld-1; i >= 0; i--) {
        if (mutexes_held[i] == &rp->mutex) {
            for (j = i; j < MAXLOCK-1; j++)
                mutexes_held[j] = mutexes_held[j+1];
            nheld--;
            goto found;
        }
    }
    ASSERT(0);

found:
    CLIB_MEMORY_BARRIER();
    pthread_mutex_unlock(&rp->mutex);
}


static u8 * format_svm_flags (u8 * s, va_list * args)
{
    uword f = va_arg (*args, uword);

    if (f & SVM_FLAGS_MHEAP)
        s = format (s, "MHEAP ");
    if (f & SVM_FLAGS_FILE)
        s = format (s, "FILE ");
    if (f & SVM_FLAGS_NODATA)
        s = format (s, "NODATA ");
    if (f & SVM_FLAGS_NEED_DATA_INIT)
        s = format (s, "INIT ");
        
    return (s);
}

static u8 * format_svm_size (u8 * s, va_list * args)
{
    uword size = va_arg (*args, uword);

    if (size >= (1<<20)) {
        s = format (s, "(%d mb)", size >> 20);
    } else if (size >= (1<<10)) {
        s = format (s, "(%d kb)", size >> 10);
    } else {
        s = format (s, "(%d bytes)", size);
    }
    return (s);
}

u8 * format_svm_region (u8 * s, va_list * args)
{
    svm_region_t *rp = va_arg (*args, svm_region_t *);
    int verbose = va_arg (*args, int);
    int i;
    uword lo, hi;

    s = format (s, "%s: base va 0x%x size 0x%x %U\n",
                rp->region_name, rp->virtual_base,
                rp->virtual_size, format_svm_size, rp->virtual_size);
    s = format (s, "  user_ctx 0x%x, bitmap_size %d\n", 
                rp->user_ctx, rp->bitmap_size);

    if (verbose) {
            s = format (s, "  flags: 0x%x %U\n", rp->flags, 
		format_svm_flags, rp->flags);
            s = format (s, 
                        "  region_heap 0x%x data_base 0x%x data_heap 0x%x\n",
                        rp->region_heap, rp->data_base, rp->data_heap);
    }

    s = format (s, "  %d clients, pids: ",
                vec_len(rp->client_pids));

    for (i = 0; i < vec_len(rp->client_pids); i++)
        s = format (s, "%d ", rp->client_pids[i]);
    
    s = format (s, "\n");

    if (verbose) {
        lo = hi = ~0;

        s = format (s, "  VM in use: ");

        for (i = 0; i < rp->bitmap_size; i++) {
            if (clib_bitmap_get_no_check (rp->bitmap, i) != 0) {
                if (lo == ~0) {
                    hi = lo = rp->virtual_base + i*MMAP_PAGESIZE;
                } else {
                    hi = rp->virtual_base + i*MMAP_PAGESIZE; 
                }
            } else {
                if (lo != ~0) {
                    hi = rp->virtual_base + i*MMAP_PAGESIZE -1;
                    s = format (s, "   0x%x - 0x%x (%dk)\n", lo, hi,
                                (hi - lo)>>10);
                    lo = hi = ~0;
                }
            }
        }
        s = format (s, "  rgn heap stats: %U", format_mheap, 
                    rp->region_heap, 0);
        if ((rp->flags & SVM_FLAGS_MHEAP) && rp->data_heap) {
            s = format (s, "\n  data heap stats: %U", format_mheap, 
                        rp->data_heap, 1);
        }
        s = format (s, "\n");
    }

    return(s);
}

/*
 * rnd_pagesize
 * Round to a pagesize multiple, presumably 4k works
 */
static unsigned int rnd_pagesize(unsigned int size)
{
    unsigned int rv;

    rv = (size + (MMAP_PAGESIZE-1)) & ~(MMAP_PAGESIZE-1);
    return(rv);
}

/* 
 * svm_data_region_setup
 */
static int svm_data_region_create (svm_map_region_args_t *a, 
                                   svm_region_t *rp)
{
    int fd;
    u8 junk = 0;
    uword map_size;

    map_size = rp->virtual_size - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE);
                
    if (a->flags & SVM_FLAGS_FILE) {
        struct stat statb;

        fd = open (a->backing_file, O_RDWR | O_CREAT, 0777);

        if (fd < 0) {
            clib_unix_warning ("open");
            return -1;
        }

        if (fstat(fd, &statb) < 0) {
            clib_unix_warning("fstat");
            return -2;
        }

        if (statb.st_mode & S_IFREG) {
            if (statb.st_size == 0) {
                lseek(fd, map_size, SEEK_SET);
                if (write(fd, &junk, 1) != 1)
                    clib_unix_warning ("set region size");
            } else {
                map_size = rnd_pagesize (statb.st_size);
            }
        } else {
            map_size = a->backing_mmap_size;
        }
        
        ASSERT(map_size <= rp->virtual_size - 
               (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE));
        
        if (mmap (rp->data_base, map_size, PROT_READ | PROT_WRITE,
                  MAP_SHARED | MAP_FIXED, fd, 0) == MAP_FAILED) {
            clib_unix_warning("mmap");
            return -3;
        }
        close(fd);
        rp->backing_file = (char *) format(0, "%s\0", a->backing_file);
        rp->flags |= SVM_FLAGS_FILE;
    }
        
    if (a->flags & SVM_FLAGS_MHEAP) {
        rp->data_heap = 
            mheap_alloc_with_flags ((void *)(rp->data_base), map_size,
                                    MHEAP_FLAG_DISABLE_VM);
        rp->flags |= SVM_FLAGS_MHEAP;
    }
    return 0;
}

static int svm_data_region_map (svm_map_region_args_t *a, 
                                   svm_region_t *rp)
{
    int fd;
    u8 junk = 0;
    uword map_size;
    struct stat statb;

    map_size = rp->virtual_size - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE);
                
    if (a->flags & SVM_FLAGS_FILE) {

        fd = open (a->backing_file, O_RDWR, 0777);

        if (fd < 0) {
            clib_unix_warning ("open");
            return -1;
        }

        if (fstat(fd, &statb) < 0) {
            clib_unix_warning("fstat");
            return -2;
        }

        if (statb.st_mode & S_IFREG) {
            if (statb.st_size == 0) {
                lseek(fd, map_size, SEEK_SET);
                if (write(fd, &junk, 1) != 1)
                    clib_unix_warning ("set region size");
            } else {
                map_size = rnd_pagesize (statb.st_size);
            }
        } else {
            map_size = a->backing_mmap_size;
        }
        
        ASSERT(map_size <= rp->virtual_size 
               - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE));
        
        if (mmap (rp->data_base, map_size, PROT_READ | PROT_WRITE,
                  MAP_SHARED | MAP_FIXED, fd, 0) == MAP_FAILED) {
            clib_unix_warning("mmap");
            return -3;
        }
        close(fd);
    }
    return 0;
}

u8 *shm_name_from_svm_map_region_args (svm_map_region_args_t *a)
{
    u8 *path;
    u8 *shm_name;
    u8 *split_point;
    u8 *mkdir_arg = 0;
    int root_path_offset = 0;
    int name_offset = 0;

    if (a->root_path) {
        /* Tolerate present or absent slashes */
        if (a->root_path[0] == '/')
            root_path_offset++;
        
        /* create the root_path under /dev/shm
           iterate through path creating directories */

        path = format (0, "/dev/shm/%s%c", &a->root_path[root_path_offset], 0);
        split_point = path+1;
        vec_add1(mkdir_arg, '-');
        
        while (*split_point) {
            while (*split_point && *split_point != '/') {
                vec_add1 (mkdir_arg, *split_point);
                split_point++;
            }
            vec_add1 (mkdir_arg, 0);
            
            /* ready to descend another level */
            mkdir_arg[vec_len(mkdir_arg)-1] = '-';
            split_point++;
        }
        vec_free(mkdir_arg);
        vec_free(path);

        if (a->name[0] == '/')
            name_offset = 1;
        
        shm_name = format (0, "/%s-%s%c", a->root_path, 
                           &a->name[name_offset], 0);
    }
    else
        shm_name = format (0, "%s%c", a->name, 0);
    return (shm_name);
}

/*
 * svm_map_region
 */
void *svm_map_region (svm_map_region_args_t *a)
{
    int svm_fd;
    svm_region_t *rp;
    pthread_mutexattr_t attr;
    pthread_condattr_t cattr;
    int deadman=0;
    u8 junk = 0;
    void *oldheap;
    int overhead_space;
    int rv;
    uword data_base;
    int nbits, words, bit;
    int pid_holding_region_lock;
    u8 *shm_name;
    int dead_region_recovery = 0;
    int time_left;
    struct stat stat;
    struct timespec ts, tsrem;

    if (CLIB_DEBUG > 1)
      clib_warning ("[%d] map region %s", getpid(), a->name);

    ASSERT((a->size & ~(MMAP_PAGESIZE-1)) == a->size);
    ASSERT(a->name);

    shm_name = shm_name_from_svm_map_region_args (a);

    svm_fd = shm_open((char *) shm_name, O_RDWR | O_CREAT | O_EXCL, 0777);

    if (svm_fd >= 0) {

        vec_free(shm_name);

        lseek(svm_fd, a->size, SEEK_SET);
        if (write(svm_fd, &junk, 1) != 1)
            clib_warning ("set region size");

        rp = mmap((void *)a->baseva, a->size, 
                  PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, svm_fd, 0);
        
        if (rp == (svm_region_t *) MAP_FAILED) {
            clib_unix_warning ("mmap create");
            return (0);
        }
        close(svm_fd);
        memset(rp, 0, sizeof(*rp));

        if (pthread_mutexattr_init(&attr))
            clib_unix_warning("mutexattr_init");
        
        if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED))
            clib_unix_warning("mutexattr_setpshared");

        if (pthread_mutex_init(&rp->mutex, &attr))
            clib_unix_warning("mutex_init");

        if (pthread_mutexattr_destroy(&attr))
            clib_unix_warning("mutexattr_destroy");

        if (pthread_condattr_init(&cattr)) 
            clib_unix_warning("condattr_init");

        if (pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED))
            clib_unix_warning("condattr_setpshared");

        if (pthread_cond_init(&rp->condvar, &cattr))
            clib_unix_warning("cond_init");

        if(pthread_condattr_destroy(&cattr))
            clib_unix_warning("condattr_destroy");
        
        region_lock (rp, 1);
        
        rp->virtual_base = a->baseva;
        rp->virtual_size = a->size;

        rp->region_heap = 
            mheap_alloc_with_flags ((void *)(a->baseva+MMAP_PAGESIZE), 
                                    SVM_PVT_MHEAP_SIZE, 
                                    MHEAP_FLAG_DISABLE_VM);
        oldheap = svm_push_pvt_heap(rp);

        rp->region_name = (char *)format (0, "%s%c", a->name, 0);
        vec_add1(rp->client_pids, getpid());

        nbits = rp->virtual_size / MMAP_PAGESIZE;
        
        ASSERT (nbits > 0);
        rp->bitmap_size = nbits;
        words = (nbits + BITS(uword)-1) / BITS(uword);
        vec_validate (rp->bitmap, words-1);
        
        overhead_space = MMAP_PAGESIZE /* header */ +
            SVM_PVT_MHEAP_SIZE;

        bit = 0;
        data_base = (uword)rp->virtual_base;

        if (a->flags & SVM_FLAGS_NODATA) 
            rp->flags |= SVM_FLAGS_NEED_DATA_INIT;
        
        do {
            clib_bitmap_set_no_check (rp->bitmap, bit, 1);
            bit++;
            overhead_space -= MMAP_PAGESIZE;
            data_base += MMAP_PAGESIZE;
        } while (overhead_space > 0);

        rp->data_base = (void *)data_base;

        /*
         * Note: although the POSIX spec guarantees that only one
         * process enters this block, we have to play games 
         * to hold off clients until e.g. the mutex is ready 
         */
        rp->version = SVM_VERSION;

        /* setup the data portion of the region */

        rv = svm_data_region_create (a, rp);
        if (rv) {
            clib_warning ("data_region_create: %d", rv);
        }

        region_unlock(rp);

        svm_pop_heap(oldheap);
    
        return ((void *) rp);
    } else {
        svm_fd = shm_open((char *)shm_name, O_RDWR, 0777);

        vec_free(shm_name);

        if (svm_fd < 0) {
            perror("svm_region_map(mmap open)");
            return (0);
        }

        time_left = 20;
        while (1) {
            if (0 != fstat(svm_fd, &stat)) {
                clib_warning("fstat failed: %d", errno);
                return (0);
            }
            if (stat.st_size > 0) {
                break;
            }
            if (0 == time_left) {
                clib_warning("waiting for resize of shm file timed out");
                return (0);
            }
            ts.tv_sec = 0;
            ts.tv_nsec = 100000000;
            while (nanosleep(&ts, &tsrem) < 0)
                ts = tsrem;
            time_left--;
        }

        rp = mmap(0, MMAP_PAGESIZE, 
                  PROT_READ | PROT_WRITE, MAP_SHARED, svm_fd, 0);

        if (rp == (svm_region_t *) MAP_FAILED) {
            close(svm_fd);
            clib_warning("mmap");
            return (0);
        }
        /*
         * We lost the footrace to create this region; make sure
         * the winner has crossed the finish line.
         */
        while (rp->version == 0 && deadman++ < 5) {
            sleep(1);
        }

        /*
         * <bleep>-ed? 
         */
        if (rp->version == 0) {
            close(svm_fd);
            munmap(rp, a->size);
            clib_warning("rp->version %d not %d", rp->version,
                         SVM_VERSION);
            return (0);
        } 
        /* Remap now that the region has been placed */
        a->baseva = rp->virtual_base;
        a->size = rp->virtual_size;
        munmap(rp, MMAP_PAGESIZE);

        rp = (void *) mmap ((void *)a->baseva, a->size, 
                            PROT_READ | PROT_WRITE, 
                            MAP_SHARED | MAP_FIXED, svm_fd, 0);
        if ((uword)rp == (uword)MAP_FAILED) {
            clib_unix_warning ("mmap");
            return (0);
        }
        
        if ((uword) rp != rp->virtual_base) {
            clib_warning("mmap botch");
        }
        
        /*
         * Try to fix the region mutex if it is held by
         * a dead process
         */
        pid_holding_region_lock = rp->mutex_owner_pid;
        if (pid_holding_region_lock &&
            kill (pid_holding_region_lock, 0) < 0) {
            clib_warning (
                "region %s mutex held by dead pid %d, tag %d, force unlock",
                rp->region_name, pid_holding_region_lock, rp->mutex_owner_tag);
            /* owner pid is nonexistent */
            rp->mutex.__data.__owner = 0;
            rp->mutex.__data.__lock = 0;
            dead_region_recovery = 1;
        }

        if (dead_region_recovery)
            clib_warning ("recovery: attempt to re-lock region");

        region_lock(rp, 2);
        oldheap = svm_push_pvt_heap (rp);
        vec_add1(rp->client_pids, getpid());
        
        if (dead_region_recovery)
            clib_warning ("recovery: attempt svm_data_region_map");

        rv = svm_data_region_map (a, rp);
        if (rv) {
            clib_warning ("data_region_map: %d", rv);
        }

        if (dead_region_recovery)
            clib_warning ("unlock and continue");

        region_unlock(rp);

        svm_pop_heap(oldheap);

        return ((void *) rp);

    }
    return 0; /* NOTREACHED */
}

static void svm_mutex_cleanup (void)
{
    int i;
    for (i = 0; i < nheld; i++) {
        pthread_mutex_unlock (mutexes_held[i]);
    }
}

static void svm_region_init_internal (char *root_path)
{
    svm_region_t *rp;
    svm_map_region_args_t *a=0;
    u64 ticks = clib_cpu_time_now();
    uword randomize_baseva;

    /* guard against klutz calls */
    root_rp_refcount++;
    if (root_rp)
        return;

    atexit(svm_mutex_cleanup);

    /* Randomize the shared-VM base at init time */
    if (MMAP_PAGESIZE <= (4<<10))
        randomize_baseva = (ticks & 15) * MMAP_PAGESIZE;
    else
        randomize_baseva = (ticks & 3) * MMAP_PAGESIZE;

    vec_validate(a,0);
    a->root_path = root_path;
    a->name = SVM_GLOBAL_REGION_NAME;
    a->baseva = SVM_GLOBAL_REGION_BASEVA + randomize_baseva;
    a->size = SVM_GLOBAL_REGION_SIZE;
    a->flags = SVM_FLAGS_NODATA;

    rp = svm_map_region (a);
    ASSERT(rp);

    region_lock(rp, 3);

    /* Set up the main region data structures */
    if (rp->flags & SVM_FLAGS_NEED_DATA_INIT) {
        svm_main_region_t *mp = 0;
        void *oldheap;

        rp->flags &= ~(SVM_FLAGS_NEED_DATA_INIT);

        oldheap = svm_push_pvt_heap (rp);
        vec_validate (mp, 0);
        mp->name_hash = hash_create_string (0, sizeof(uword));
        mp->root_path = root_path 
            ? format (0, "%s%c", root_path, 0) : 0 ;
        rp->data_base = mp;
        svm_pop_heap (oldheap);
    }
    region_unlock(rp);
    vec_free (a);
    root_rp = rp;
}

void svm_region_init (void)
{
    svm_region_init_internal (0);
}

void svm_region_init_chroot (char *root_path)
{
    svm_region_init_internal (root_path);
}

void *svm_region_find_or_create (svm_map_region_args_t *a)
{
    svm_main_region_t *mp;
    svm_region_t *rp;
    uword need_nbits;
    int index, i;
    void *oldheap;
    uword *p;
    u8 *name;
    svm_subregion_t *subp;
    
    ASSERT(root_rp);

    a->size +=  MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE;
    a->size = rnd_pagesize(a->size);

    region_lock (root_rp, 4);
    oldheap = svm_push_pvt_heap(root_rp);
    mp = root_rp->data_base;
    
    ASSERT(mp);

    /* Map the named region from the correct chroot environment */
    a->root_path = (char *) mp->root_path;

    /* 
     * See if this region is already known. If it is, we're
     * almost done... 
     */
    p = hash_get_mem (mp->name_hash, a->name);

    if (p) {
        rp = svm_map_region (a);
        region_unlock(root_rp);
        svm_pop_heap (oldheap);
        return rp;
    }
    
    /* Create the region. */
    ASSERT((a->size & ~(MMAP_PAGESIZE-1)) == a->size);

    need_nbits = a->size / MMAP_PAGESIZE;

    index = 1;  /* $$$ fixme, figure out how many bit to really skip */

    /*
     * Scan the virtual space allocation bitmap, looking for a large
     * enough chunk 
     */
    do {
        if (clib_bitmap_get_no_check(root_rp->bitmap, index) == 0) {
            for (i = 0; i < (need_nbits-1); i++) {
                if (clib_bitmap_get_no_check(root_rp->bitmap, 
                                             index+i) == 1) {
                    index = index + i;
                    goto next;
                }
            }
            break;
        }
        index++;
    next:;
    } while (index < root_rp->bitmap_size);

    /* Completely out of VM? */
    if (index >= root_rp->bitmap_size) {
        clib_warning("region %s: not enough VM to allocate 0x%x",
                     root_rp->region_name, a->size);
        svm_pop_heap (oldheap);
        region_unlock (root_rp);
        return 0;
    }
    
    /*
     * Mark virtual space allocated 
     */
#if CLIB_DEBUG > 1
    clib_warning ("set %d bits at index %d", need_nbits, index);
#endif

    for (i = 0; i < need_nbits; i++) {
        clib_bitmap_set_no_check (root_rp->bitmap, index+i, 1);
    }

    /* Place this region where it goes... */
    a->baseva = root_rp->virtual_base + index*MMAP_PAGESIZE;

    rp = svm_map_region (a);
    
    pool_get (mp->subregions, subp);
    name = format (0, "%s%c", a->name, 0);
    subp->subregion_name = name;

    hash_set_mem (mp->name_hash, name, subp - mp->subregions);

    svm_pop_heap (oldheap);

    region_unlock (root_rp);

    return (rp);
}

/*
 * svm_region_unmap
 *
 * Let go of the indicated region. If the calling process
 * is the last customer, throw it away completely.
 * The root region mutex guarantees atomicity with respect to
 * a new region client showing up at the wrong moment.
 */
void svm_region_unmap (void *rp_arg)
{
    int i, mypid = getpid();
    int nclients_left;
    void *oldheap;
    uword virtual_base, virtual_size;
    svm_region_t *rp = rp_arg;
    char *name;

    /* 
     * If we take a signal while holding one or more shared-memory
     * mutexes, we may end up back here from an otherwise
     * benign exit handler. Bail out to avoid a recursive
     * mutex screw-up.
     */
    if (nheld)
        return;

    ASSERT(rp);
    ASSERT(root_rp);

    if (CLIB_DEBUG > 1)
      clib_warning ("[%d] unmap region %s", getpid(), rp->region_name);

    region_lock (root_rp, 5);
    region_lock (rp, 6);
    
    oldheap = svm_push_pvt_heap (rp); /* nb vec_delete() in the loop */

    /* Remove the caller from the list of mappers */
    for (i = 0; i < vec_len(rp->client_pids); i++) {
        if (rp->client_pids[i] == mypid) {
            vec_delete (rp->client_pids, 1, i);
            goto found;
        }
    }
    clib_warning("pid %d AWOL", mypid);

 found:

    svm_pop_heap (oldheap);

    nclients_left = vec_len(rp->client_pids);
    virtual_base = rp->virtual_base;
    virtual_size = rp->virtual_size;

    if (nclients_left == 0) {
        int index, nbits, i;
        svm_main_region_t *mp;
        uword *p;
        svm_subregion_t *subp;

        /* Kill the region, last guy on his way out */

        oldheap = svm_push_pvt_heap (root_rp); 
        name = vec_dup (rp->region_name);

        virtual_base = rp->virtual_base;
        virtual_size = rp->virtual_size;

        /* Figure out which bits to clear in the root region bitmap */
        index = (virtual_base - root_rp->virtual_base)
            / MMAP_PAGESIZE;

        nbits = (virtual_size + MMAP_PAGESIZE - 1)
            / MMAP_PAGESIZE;

#if CLIB_DEBUG > 1
        clib_warning ("clear %d bits at index %d", nbits, index);
#endif
        /* Give back the allocated VM */
        for (i = 0; i < nbits; i++) {
            clib_bitmap_set_no_check (root_rp->bitmap, index+i, 0);
        }

        mp = root_rp->data_base;

        p = hash_get_mem (mp->name_hash, name);
        
        /* Better never happen ... */
        if (p == NULL) {
            region_unlock (rp);
            region_unlock (root_rp);
            svm_pop_heap (oldheap);
            clib_warning ("Region name '%s' not found?", name);
            return;
        }
        
        /* Remove from the root region subregion pool */
        subp = mp->subregions + p[0];
        pool_put (mp->subregions, subp);
        
        hash_unset_mem (mp->name_hash, name);

        vec_free(name);

        region_unlock (rp);
        shm_unlink(rp->region_name);
        munmap ((void *)virtual_base, virtual_size);
        region_unlock (root_rp);
        svm_pop_heap (oldheap);
        return;
    }

    region_unlock(rp);
    region_unlock(root_rp);

    munmap ((void *)virtual_base, virtual_size);
}

/*
 * svm_region_exit
 * There is no clean way to unlink the
 * root region when all clients go away, 
 * so remove the pid entry and call it a day.
 */ 
void svm_region_exit ()
{
    void *oldheap;
    int i, mypid = getpid();
    uword virtual_base, virtual_size;

    /* It felt so nice we did it twice... */
    if (root_rp == 0)
        return;

    if (--root_rp_refcount > 0)
        return;

    /* 
     * If we take a signal while holding one or more shared-memory
     * mutexes, we may end up back here from an otherwise
     * benign exit handler. Bail out to avoid a recursive
     * mutex screw-up.
     */
    if (nheld)
        return;

    region_lock(root_rp, 7);
    oldheap = svm_push_pvt_heap (root_rp);

    virtual_base = root_rp->virtual_base;
    virtual_size = root_rp->virtual_size;

    for (i = 0; i < vec_len(root_rp->client_pids); i++) {
        if (root_rp->client_pids[i] == mypid) {
            vec_delete (root_rp->client_pids, 1, i);
            goto found;
        }
    }
    clib_warning("pid %d AWOL", mypid);

 found:

    region_unlock(root_rp);
    svm_pop_heap (oldheap);

    root_rp = 0;
    munmap ((void *)virtual_base, virtual_size);
}

void svm_client_scan_this_region_nolock (svm_region_t *rp)
{
    int j;
    int mypid = getpid();
    void *oldheap;

    for (j = 0; j < vec_len(rp->client_pids); j++) {
        if (mypid == rp->client_pids[j])
            continue;
        if (rp->client_pids[j] && (kill (rp->client_pids[j], 0) < 0)) {
            clib_warning ("%s: cleanup ghost pid %d",
                          rp->region_name, rp->client_pids[j]);
            /* nb: client vec in rp->region_heap */
            oldheap = svm_push_pvt_heap (rp); 
            vec_delete (rp->client_pids, 1, j);
            j--;
            svm_pop_heap (oldheap);
        }
    }
}


/* 
 * Scan svm regions for dead clients
 */
void svm_client_scan(char *root_path)
{
    int i, j;
    svm_main_region_t *mp;
    svm_map_region_args_t *a = 0;
    svm_region_t *root_rp;
    svm_region_t *rp;
    svm_subregion_t *subp;
    u8 *name=0;
    u8 ** svm_names=0;
    void *oldheap;
    int mypid = getpid();

    vec_validate (a, 0);

    svm_region_init_chroot(root_path);

    root_rp = svm_get_root_rp();

    pthread_mutex_lock (&root_rp->mutex);

    mp = root_rp->data_base;

    for (j = 0; j < vec_len (root_rp->client_pids); j++) {
        if (mypid == root_rp->client_pids[j])
            continue;
        if (root_rp->client_pids[j] 
            && (kill (root_rp->client_pids[j], 0) < 0)) {
            clib_warning ("%s: cleanup ghost pid %d",
                    root_rp->region_name, root_rp->client_pids[j]);
            /* nb: client vec in root_rp->region_heap */
            oldheap = svm_push_pvt_heap (root_rp); 
            vec_delete (root_rp->client_pids, 1, j);
            j--;
            svm_pop_heap (oldheap);
        }
    }

    /* 
     * Snapshoot names, can't hold root rp mutex across
     * find_or_create.
     */
    pool_foreach (subp, mp->subregions, ({
	  name = vec_dup (subp->subregion_name);
	  vec_add1(svm_names, name);
	}));

    pthread_mutex_unlock (&root_rp->mutex);

    for (i = 0; i < vec_len(svm_names); i++) {
	  vec_validate(a, 0);
          a->root_path = root_path;
	  a->name = (char *) svm_names[i];
	  rp = svm_region_find_or_create (a);
	  if (rp) {
	    pthread_mutex_lock (&rp->mutex);

            svm_client_scan_this_region_nolock (rp);

	    pthread_mutex_unlock (&rp->mutex);
	    svm_region_unmap (rp);
            vec_free(svm_names[i]);
	  }
	  vec_free (a);
    }
    vec_free(svm_names);

    svm_region_exit ();

    vec_free (a);
}
