/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "primpl.h"

#include <stdlib.h>
#include <stddef.h>

/* Lock used to lock the monitor cache */
#ifdef _PR_NO_PREEMPT
#define _PR_NEW_LOCK_MCACHE()
#define _PR_DESTROY_LOCK_MCACHE()
#define _PR_LOCK_MCACHE()
#define _PR_UNLOCK_MCACHE()
#else
#ifdef _PR_LOCAL_THREADS_ONLY
#define _PR_NEW_LOCK_MCACHE()
#define _PR_DESTROY_LOCK_MCACHE()
#define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is)
#define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); }
#else
PRLock *_pr_mcacheLock;
#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock())
#define _PR_DESTROY_LOCK_MCACHE()               \
    PR_BEGIN_MACRO                              \
        if (_pr_mcacheLock) {                   \
            PR_DestroyLock(_pr_mcacheLock);     \
            _pr_mcacheLock = NULL;              \
        }                                       \
    PR_END_MACRO
#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock)
#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock)
#endif
#endif

/************************************************************************/

typedef struct MonitorCacheEntryStr MonitorCacheEntry;

struct MonitorCacheEntryStr {
    MonitorCacheEntry*  next;
    void*               address;
    PRMonitor*          mon;
    long                cacheEntryCount;
};

/*
** An array of MonitorCacheEntry's, plus a pointer to link these
** arrays together.
*/

typedef struct MonitorCacheEntryBlockStr MonitorCacheEntryBlock;

struct MonitorCacheEntryBlockStr {
    MonitorCacheEntryBlock* next;
    MonitorCacheEntry entries[1];
};

static PRUint32 hash_mask;
static PRUintn num_hash_buckets;
static PRUintn num_hash_buckets_log2;
static MonitorCacheEntry **hash_buckets;
static MonitorCacheEntry *free_entries;
static PRUintn num_free_entries;
static PRBool expanding;
static MonitorCacheEntryBlock *mcache_blocks;

static void (*OnMonitorRecycle)(void *address);

#define HASH(address)                               \
    ((PRUint32) ( ((PRUptrdiff)(address) >> 2) ^    \
                  ((PRUptrdiff)(address) >> 10) )   \
     & hash_mask)

/*
** Expand the monitor cache. This grows the hash buckets and allocates a
** new chunk of cache entries and throws them on the free list. We keep
** as many hash buckets as there are entries.
**
** Because we call malloc and malloc may need the monitor cache, we must
** ensure that there are several free monitor cache entries available for
** malloc to get. FREE_THRESHOLD is used to prevent monitor cache
** starvation during monitor cache expansion.
*/

#define FREE_THRESHOLD  5

static PRStatus ExpandMonitorCache(PRUintn new_size_log2)
{
    MonitorCacheEntry **old_hash_buckets, *p;
    PRUintn i, entries, old_num_hash_buckets, added;
    MonitorCacheEntry **new_hash_buckets;
    MonitorCacheEntryBlock *new_block;

    entries = 1L << new_size_log2;

    /*
    ** Expand the monitor-cache-entry free list
    */
    new_block = (MonitorCacheEntryBlock*)
        PR_CALLOC(sizeof(MonitorCacheEntryBlock)
        + (entries - 1) * sizeof(MonitorCacheEntry));
    if (NULL == new_block) return PR_FAILURE;

    /*
    ** Allocate system monitors for the new monitor cache entries. If we
    ** run out of system monitors, break out of the loop.
    */
    for (i = 0, p = new_block->entries; i < entries; i++, p++) {
        p->mon = PR_NewMonitor();
        if (!p->mon)
            break;
    }
    added = i;
    if (added != entries) {
        MonitorCacheEntryBlock *realloc_block;

        if (added == 0) {
            /* Totally out of system monitors. Lossage abounds */
            PR_DELETE(new_block);
            return PR_FAILURE;
        }

        /*
        ** We were able to allocate some of the system monitors. Use
        ** realloc to shrink down the new_block memory. If that fails,
        ** carry on with the too-large new_block.
        */
        realloc_block = (MonitorCacheEntryBlock*)
            PR_REALLOC(new_block, sizeof(MonitorCacheEntryBlock)
            + (added - 1) * sizeof(MonitorCacheEntry));
        if (realloc_block)
            new_block = realloc_block;
    }

    /*
    ** Now that we have allocated all of the system monitors, build up
    ** the new free list. We can just update the free_list because we own
    ** the mcache-lock and we aren't calling anyone who might want to use
    ** it.
    */
    for (i = 0, p = new_block->entries; i < added - 1; i++, p++)
        p->next = p + 1;
    p->next = free_entries;
    free_entries = new_block->entries;
    num_free_entries += added;
    new_block->next = mcache_blocks;
    mcache_blocks = new_block;

    /* Try to expand the hash table */
    new_hash_buckets = (MonitorCacheEntry**)
        PR_CALLOC(entries * sizeof(MonitorCacheEntry*));
    if (NULL == new_hash_buckets) {
        /*
        ** Partial lossage. In this situation we don't get any more hash
        ** buckets, which just means that the table lookups will take
        ** longer. This is bad, but not fatal
        */
        PR_LOG(_pr_cmon_lm, PR_LOG_WARNING,
               ("unable to grow monitor cache hash buckets"));
        return PR_SUCCESS;
    }

    /*
    ** Compute new hash mask value. This value is used to mask an address
    ** until it's bits are in the right spot for indexing into the hash
    ** table.
    */
    hash_mask = entries - 1;

    /*
    ** Expand the hash table. We have to rehash everything in the old
    ** table into the new table.
    */
    old_hash_buckets = hash_buckets;
    old_num_hash_buckets = num_hash_buckets;
    for (i = 0; i < old_num_hash_buckets; i++) {
        p = old_hash_buckets[i];
        while (p) {
            MonitorCacheEntry *next = p->next;

            /* Hash based on new table size, and then put p in the new table */
            PRUintn hash = HASH(p->address);
            p->next = new_hash_buckets[hash];
            new_hash_buckets[hash] = p;

            p = next;
        }
    }

    /*
    ** Switch over to new hash table and THEN call free of the old
    ** table. Since free might re-enter _pr_mcache_lock, things would
    ** break terribly if it used the old hash table.
    */
    hash_buckets = new_hash_buckets;
    num_hash_buckets = entries;
    num_hash_buckets_log2 = new_size_log2;
    PR_DELETE(old_hash_buckets);

    PR_LOG(_pr_cmon_lm, PR_LOG_NOTICE,
           ("expanded monitor cache to %d (buckets %d)",
            num_free_entries, entries));

    return PR_SUCCESS;
}  /* ExpandMonitorCache */

/*
** Lookup a monitor cache entry by address. Return a pointer to the
** pointer to the monitor cache entry on success, null on failure.
*/
static MonitorCacheEntry **LookupMonitorCacheEntry(void *address)
{
    PRUintn hash;
    MonitorCacheEntry **pp, *p;

    hash = HASH(address);
    pp = hash_buckets + hash;
    while ((p = *pp) != 0) {
        if (p->address == address) {
            if (p->cacheEntryCount > 0)
                return pp;
            return NULL;
        }
        pp = &p->next;
    }
    return NULL;
}

/*
** Try to create a new cached monitor. If it's already in the cache,
** great - return it. Otherwise get a new free cache entry and set it
** up. If the cache free space is getting low, expand the cache.
*/
static PRMonitor *CreateMonitor(void *address)
{
    PRUintn hash;
    MonitorCacheEntry **pp, *p;

    hash = HASH(address);
    pp = hash_buckets + hash;
    while ((p = *pp) != 0) {
        if (p->address == address) goto gotit;

        pp = &p->next;
    }

    /* Expand the monitor cache if we have run out of free slots in the table */
    if (num_free_entries < FREE_THRESHOLD) {
        /* Expand monitor cache */

        /*
        ** This function is called with the lock held. So what's the 'expanding'
        ** boolean all about? Seems a bit redundant.
        */
        if (!expanding) {
            PRStatus rv;

            expanding = PR_TRUE;
            rv = ExpandMonitorCache(num_hash_buckets_log2 + 1);
            expanding = PR_FALSE;
            if (PR_FAILURE == rv)  return NULL;

            /* redo the hash because it'll be different now */
            hash = HASH(address);
        } else {
            /*
            ** We are in process of expanding and we need a cache
            ** monitor.  Make sure we have enough!
            */
            PR_ASSERT(num_free_entries > 0);
        }
    }

    /* Make a new monitor */
    p = free_entries;
    free_entries = p->next;
    num_free_entries--;
    if (OnMonitorRecycle && p->address)
        OnMonitorRecycle(p->address);
    p->address = address;
    p->next = hash_buckets[hash];
    hash_buckets[hash] = p;
    PR_ASSERT(p->cacheEntryCount == 0);

  gotit:
    p->cacheEntryCount++;
    return p->mon;
}

/*
** Initialize the monitor cache
*/
void _PR_InitCMon(void)
{
    _PR_NEW_LOCK_MCACHE();
    ExpandMonitorCache(3);
}

/*
** Destroy the monitor cache
*/
void _PR_CleanupCMon(void)
{
    _PR_DESTROY_LOCK_MCACHE();

    while (free_entries) {
        PR_DestroyMonitor(free_entries->mon);
        free_entries = free_entries->next;
    }
    num_free_entries = 0;

    while (mcache_blocks) {
        MonitorCacheEntryBlock *block;

        block = mcache_blocks;
        mcache_blocks = block->next;
        PR_DELETE(block);
    }

    PR_DELETE(hash_buckets);
    hash_mask = 0;
    num_hash_buckets = 0;
    num_hash_buckets_log2 = 0;

    expanding = PR_FALSE;
    OnMonitorRecycle = NULL;
}

/*
** Create monitor for address. Don't enter the monitor while we have the
** mcache locked because we might block!
*/
PR_IMPLEMENT(PRMonitor*) PR_CEnterMonitor(void *address)
{
    PRMonitor *mon;

    if (!_pr_initialized) _PR_ImplicitInitialization();

    _PR_LOCK_MCACHE();
    mon = CreateMonitor(address);
    _PR_UNLOCK_MCACHE();

    if (!mon) return NULL;

    PR_EnterMonitor(mon);
    return mon;
}

PR_IMPLEMENT(PRStatus) PR_CExitMonitor(void *address)
{
    MonitorCacheEntry **pp, *p;
    PRStatus status = PR_SUCCESS;

    _PR_LOCK_MCACHE();
    pp = LookupMonitorCacheEntry(address);
    if (pp != NULL) {
        p = *pp;
        if (--p->cacheEntryCount == 0) {
            /*
            ** Nobody is using the system monitor. Put it on the cached free
            ** list. We are safe from somebody trying to use it because we
            ** have the mcache locked.
            */
            p->address = 0;             /* defensive move */
            *pp = p->next;              /* unlink from hash_buckets */
            p->next = free_entries;     /* link into free list */
            free_entries = p;
            num_free_entries++;         /* count it as free */
        }
        status = PR_ExitMonitor(p->mon);
    } else {
        status = PR_FAILURE;
    }
    _PR_UNLOCK_MCACHE();

    return status;
}

PR_IMPLEMENT(PRStatus) PR_CWait(void *address, PRIntervalTime ticks)
{
    MonitorCacheEntry **pp;
    PRMonitor *mon;

    _PR_LOCK_MCACHE();
    pp = LookupMonitorCacheEntry(address);
    mon = pp ? ((*pp)->mon) : NULL;
    _PR_UNLOCK_MCACHE();

    if (mon == NULL)
        return PR_FAILURE;
    return PR_Wait(mon, ticks);
}

PR_IMPLEMENT(PRStatus) PR_CNotify(void *address)
{
    MonitorCacheEntry **pp;
    PRMonitor *mon;

    _PR_LOCK_MCACHE();
    pp = LookupMonitorCacheEntry(address);
    mon = pp ? ((*pp)->mon) : NULL;
    _PR_UNLOCK_MCACHE();

    if (mon == NULL)
        return PR_FAILURE;
    return PR_Notify(mon);
}

PR_IMPLEMENT(PRStatus) PR_CNotifyAll(void *address)
{
    MonitorCacheEntry **pp;
    PRMonitor *mon;

    _PR_LOCK_MCACHE();
    pp = LookupMonitorCacheEntry(address);
    mon = pp ? ((*pp)->mon) : NULL;
    _PR_UNLOCK_MCACHE();

    if (mon == NULL)
        return PR_FAILURE;
    return PR_NotifyAll(mon);
}

PR_IMPLEMENT(void)
PR_CSetOnMonitorRecycle(void (*callback)(void *address))
{
    OnMonitorRecycle = callback;
}
