mirror of
https://github.com/openbsd/src.git
synced 2026-04-21 04:34:20 +00:00
add idr_alloc_cyclic() for 6.18.21 drm
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: drm_linux.c,v 1.134 2026/03/31 08:54:14 jsg Exp $ */
|
||||
/* $OpenBSD: drm_linux.c,v 1.135 2026/04/07 09:11:15 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
|
||||
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
|
||||
@@ -810,6 +810,7 @@ void
|
||||
idr_init(struct idr *idr)
|
||||
{
|
||||
SPLAY_INIT(&idr->tree);
|
||||
idr->next = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -867,6 +868,44 @@ idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
|
||||
return id->id;
|
||||
}
|
||||
|
||||
/* [start, end) */
|
||||
int
|
||||
idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
|
||||
{
|
||||
int flags = (gfp_mask & GFP_NOWAIT) ? PR_NOWAIT : PR_WAITOK;
|
||||
struct idr_entry *id;
|
||||
|
||||
KERNEL_ASSERT_LOCKED();
|
||||
|
||||
if (idr_entry_cache) {
|
||||
id = idr_entry_cache;
|
||||
idr_entry_cache = NULL;
|
||||
} else {
|
||||
id = pool_get(&idr_pool, flags);
|
||||
if (id == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (end <= 0)
|
||||
end = INT_MAX;
|
||||
|
||||
id->id = idr->next;
|
||||
while (SPLAY_INSERT(idr_tree, &idr->tree, id)) {
|
||||
id->id++;
|
||||
if (id->id == end) {
|
||||
id->id = start;
|
||||
} else if (id->id == idr->next) {
|
||||
pool_put(&idr_pool, id);
|
||||
return -ENOSPC;
|
||||
}
|
||||
}
|
||||
id->ptr = ptr;
|
||||
idr->next = id->id + 1;
|
||||
if (idr->next == end)
|
||||
idr->next = start;
|
||||
return id->id;
|
||||
}
|
||||
|
||||
void *
|
||||
idr_replace(struct idr *idr, void *ptr, unsigned long id)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: idr.h,v 1.9 2026/04/07 09:04:16 jsg Exp $ */
|
||||
/* $OpenBSD: idr.h,v 1.10 2026/04/07 09:11:15 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Mark Kettenis
|
||||
*
|
||||
@@ -31,16 +31,19 @@ struct idr_entry {
|
||||
|
||||
struct idr {
|
||||
SPLAY_HEAD(idr_tree, idr_entry) tree;
|
||||
unsigned long next;
|
||||
};
|
||||
|
||||
#define DEFINE_IDR(name) \
|
||||
struct idr name = { \
|
||||
.tree = SPLAY_INITIALIZER(&name.idr.tree), \
|
||||
.next = 0 \
|
||||
}
|
||||
|
||||
void idr_init(struct idr *);
|
||||
void idr_preload(unsigned int);
|
||||
int idr_alloc(struct idr *, void *, int, int, gfp_t);
|
||||
int idr_alloc_cyclic(struct idr *, void *, int, int, gfp_t);
|
||||
void *idr_find(struct idr *, unsigned long);
|
||||
void *idr_replace(struct idr *, void *, unsigned long);
|
||||
void *idr_remove(struct idr *, unsigned long);
|
||||
|
||||
Reference in New Issue
Block a user