summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/id_space.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/id_space.c')
-rw-r--r--usr/src/uts/common/os/id_space.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/usr/src/uts/common/os/id_space.c b/usr/src/uts/common/os/id_space.c
index 07b1a630ea..2dad0cb940 100644
--- a/usr/src/uts/common/os/id_space.c
+++ b/usr/src/uts/common/os/id_space.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -47,7 +46,7 @@
* As an ID space is designed for representing a range of id_t's, there
* is a preexisting maximal range: [0, MAXUID]. ID space requests outside
* that range will fail on a DEBUG kernel. The id_allocff*() functions
- * return the first available id, and should be used when there is benifit
+ * return the first available id, and should be used when there is benefit
* to having a compact allocated range.
*
* (Presently, the id_space_t abstraction supports only direct allocations; ID
@@ -56,6 +55,9 @@
* arrives.)
*/
+#define ID_TO_ADDR(id) ((void *)(uintptr_t)(id + 1))
+#define ADDR_TO_ID(addr) ((id_t)((uintptr_t)addr - 1))
+
/*
* Create an arena to represent the range [low, high).
* Caller must be in a context in which VM_SLEEP is legal.
@@ -66,7 +68,7 @@ id_space_create(const char *name, id_t low, id_t high)
ASSERT(low >= 0);
ASSERT(low < high);
- return (vmem_create(name, (void *)(uintptr_t)(low + 1), high - low, 1,
+ return (vmem_create(name, ID_TO_ADDR(low), high - low, 1,
NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER));
}
@@ -83,8 +85,7 @@ id_space_destroy(id_space_t *isp)
void
id_space_extend(id_space_t *isp, id_t low, id_t high)
{
- (void) vmem_add(isp,
- (void *)(uintptr_t)(low + 1), high - low, VM_SLEEP);
+ (void) vmem_add(isp, ID_TO_ADDR(low), high - low, VM_SLEEP);
}
/*
@@ -94,8 +95,7 @@ id_space_extend(id_space_t *isp, id_t low, id_t high)
id_t
id_alloc(id_space_t *isp)
{
- return ((id_t)(uintptr_t)
- vmem_alloc(isp, 1, VM_SLEEP | VM_NEXTFIT) - 1);
+ return (ADDR_TO_ID(vmem_alloc(isp, 1, VM_SLEEP | VM_NEXTFIT)));
}
/*
@@ -106,8 +106,7 @@ id_alloc(id_space_t *isp)
id_t
id_alloc_nosleep(id_space_t *isp)
{
- return ((id_t)(uintptr_t)
- vmem_alloc(isp, 1, VM_NOSLEEP | VM_NEXTFIT) - 1);
+ return (ADDR_TO_ID(vmem_alloc(isp, 1, VM_NOSLEEP | VM_NEXTFIT)));
}
/*
@@ -117,8 +116,7 @@ id_alloc_nosleep(id_space_t *isp)
id_t
id_allocff(id_space_t *isp)
{
- return ((id_t)(uintptr_t)
- vmem_alloc(isp, 1, VM_SLEEP | VM_FIRSTFIT) - 1);
+ return (ADDR_TO_ID(vmem_alloc(isp, 1, VM_SLEEP | VM_FIRSTFIT)));
}
/*
@@ -129,8 +127,25 @@ id_allocff(id_space_t *isp)
id_t
id_allocff_nosleep(id_space_t *isp)
{
- return ((id_t)(uintptr_t)
- vmem_alloc(isp, 1, VM_NOSLEEP | VM_FIRSTFIT) - 1);
+ return (ADDR_TO_ID(vmem_alloc(isp, 1, VM_NOSLEEP | VM_FIRSTFIT)));
+}
+
+/*
+ * Allocate a specific identifier if possible, returning the id if
+ * successful, or -1 on failure.
+ */
+id_t
+id_alloc_specific_nosleep(id_space_t *isp, id_t id)
+{
+ void *minaddr = ID_TO_ADDR(id);
+ void *maxaddr = ID_TO_ADDR(id + 1);
+
+ /*
+ * Note that even though we're vmem_free()ing this later, it
+ * should be OK, since there's no quantum cache.
+ */
+ return (ADDR_TO_ID(vmem_xalloc(isp, 1, 1, 0, 0,
+ minaddr, maxaddr, VM_NOSLEEP)));
}
/*
@@ -140,5 +155,5 @@ id_allocff_nosleep(id_space_t *isp)
void
id_free(id_space_t *isp, id_t id)
{
- vmem_free(isp, (void *)(uintptr_t)(id + 1), 1);
+ vmem_free(isp, ID_TO_ADDR(id), 1);
}