os_region.c 2.79 KB
Newer Older
unknown's avatar
unknown committed
1 2 3
/*-
 * See the file LICENSE for redistribution information.
 *
unknown's avatar
unknown committed
4
 * Copyright (c) 1996-2002
unknown's avatar
unknown committed
5 6 7 8 9 10
 *	Sleepycat Software.  All rights reserved.
 */

#include "db_config.h"

#ifndef lint
unknown's avatar
unknown committed
11
static const char revid[] = "$Id: os_region.c,v 11.15 2002/07/12 18:56:51 bostic Exp $";
unknown's avatar
unknown committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#endif /* not lint */

#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>

#endif

#include "db_int.h"

/*
 * __os_r_attach --
 *	Attach to a shared memory region.
 *
 * PUBLIC: int __os_r_attach __P((DB_ENV *, REGINFO *, REGION *));
 */
int
__os_r_attach(dbenv, infop, rp)
	DB_ENV *dbenv;
	REGINFO *infop;
	REGION *rp;
{
	int ret;
	/* Round off the requested size for the underlying VM. */
	OS_VMROUNDOFF(rp->size);

#ifdef DB_REGIONSIZE_MAX
	/* Some architectures have hard limits on the maximum region size. */
	if (rp->size > DB_REGIONSIZE_MAX) {
		__db_err(dbenv, "region size %lu is too large; maximum is %lu",
		    (u_long)rp->size, (u_long)DB_REGIONSIZE_MAX);
		return (EINVAL);
	}
#endif

	/*
	 * If a region is private, malloc the memory.
	 *
	 * !!!
	 * If this fails because the region is too large to malloc, mmap(2)
	 * using the MAP_ANON or MAP_ANONYMOUS flags would be an alternative.
	 * I don't know of any architectures (yet!) where malloc is a problem.
	 */
	if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
#if defined(MUTEX_NO_MALLOC_LOCKS)
		/*
		 * !!!
		 * There exist spinlocks that don't work in malloc memory, e.g.,
		 * the HP/UX msemaphore interface.  If we don't have locks that
		 * will work in malloc memory, we better not be private or not
		 * be threaded.
		 */
		if (F_ISSET(dbenv, DB_ENV_THREAD)) {
			__db_err(dbenv, "%s",
    "architecture does not support locks inside process-local (malloc) memory");
			__db_err(dbenv, "%s",
    "application may not specify both DB_PRIVATE and DB_THREAD");
			return (EINVAL);
		}
#endif
		if ((ret =
unknown's avatar
unknown committed
72
		    __os_malloc(dbenv, rp->size, &infop->addr)) != 0)
unknown's avatar
unknown committed
73 74 75 76 77 78 79 80
			return (ret);
#if defined(UMRW) && !defined(DIAGNOSTIC)
		memset(infop->addr, CLEAR_BYTE, rp->size);
#endif
		return (0);
	}

	/* If the user replaced the map call, call through their interface. */
unknown's avatar
unknown committed
81 82
	if (DB_GLOBAL(j_map) != NULL)
		return (DB_GLOBAL(j_map)(infop->name,
unknown's avatar
unknown committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
		    rp->size, 1, 0, &infop->addr));

	return (__os_r_sysattach(dbenv, infop, rp));
}

/*
 * __os_r_detach --
 *	Detach from a shared memory region.
 *
 * PUBLIC: int __os_r_detach __P((DB_ENV *, REGINFO *, int));
 */
int
__os_r_detach(dbenv, infop, destroy)
	DB_ENV *dbenv;
	REGINFO *infop;
	int destroy;
{
	REGION *rp;

	rp = infop->rp;

	/* If a region is private, free the memory. */
	if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
unknown's avatar
unknown committed
106
		__os_free(dbenv, infop->addr);
unknown's avatar
unknown committed
107 108 109 110
		return (0);
	}

	/* If the user replaced the map call, call through their interface. */
unknown's avatar
unknown committed
111 112
	if (DB_GLOBAL(j_unmap) != NULL)
		return (DB_GLOBAL(j_unmap)(infop->addr, rp->size));
unknown's avatar
unknown committed
113 114 115

	return (__os_r_sysdetach(dbenv, infop, destroy));
}