Skip to content

Commit 78a12f9

Browse files
authored
[libc] implement insque and remque (#80305)
This PR implements the `insque` and `remque` entrypoint functions.
1 parent fee204f commit 78a12f9

File tree

14 files changed

+393
-2
lines changed

14 files changed

+393
-2
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ if(LLVM_LIBC_FULL_BUILD)
496496
libc.src.search.hsearch_r
497497
libc.src.search.hdestroy
498498
libc.src.search.hdestroy_r
499+
libc.src.search.insque
500+
libc.src.search.remque
499501

500502
# threads.h entrypoints
501503
libc.src.threads.call_once

libc/config/linux/riscv/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ if(LLVM_LIBC_FULL_BUILD)
522522
libc.src.search.hsearch_r
523523
libc.src.search.hdestroy
524524
libc.src.search.hdestroy_r
525+
libc.src.search.insque
526+
libc.src.search.remque
525527

526528
# threads.h entrypoints
527529
libc.src.threads.call_once

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ if(LLVM_LIBC_FULL_BUILD)
546546
libc.src.search.hsearch_r
547547
libc.src.search.hdestroy
548548
libc.src.search.hdestroy_r
549+
libc.src.search.insque
550+
libc.src.search.remque
549551

550552
# threads.h entrypoints
551553
libc.src.threads.call_once

libc/docs/libc_search.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ Function Name Available
4141
hcreate |check|
4242
hdestroy |check|
4343
hsearch |check|
44-
insque
44+
insque |check|
4545
lfind
4646
lsearch
47-
remque
47+
remque |check|
4848
tdelete
4949
tfind
5050
tsearch

libc/spec/posix.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,21 @@ def POSIX : StandardSpec<"POSIX"> {
13231323
ArgSpec<ActionType>
13241324
]
13251325
>,
1326+
FunctionSpec<
1327+
"insque",
1328+
RetValSpec<VoidType>,
1329+
[
1330+
ArgSpec<VoidPtr>,
1331+
ArgSpec<VoidPtr>
1332+
]
1333+
>,
1334+
FunctionSpec<
1335+
"remque",
1336+
RetValSpec<VoidType>,
1337+
[
1338+
ArgSpec<VoidPtr>
1339+
]
1340+
>,
13261341
]
13271342
>;
13281343

libc/src/__support/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ add_header_library(
250250
libc.src.__support.macros.config
251251
)
252252

253+
add_header_library(
254+
intrusive_list
255+
HDRS
256+
intrusive_list.h
257+
DEPENDS
258+
libc.src.__support.macros.attributes
259+
)
260+
253261
add_subdirectory(FPUtil)
254262
add_subdirectory(OSUtil)
255263
add_subdirectory(StringUtil)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===-- Intrusive queue implementation. -------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// An intrusive list that implements the insque and remque semantics.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H
14+
#define LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H
15+
16+
#include "common.h"
17+
18+
namespace LIBC_NAMESPACE {
19+
namespace internal {
20+
21+
class IntrusiveList {
22+
struct IntrusiveNodeHeader {
23+
IntrusiveNodeHeader *next;
24+
IntrusiveNodeHeader *prev;
25+
};
26+
27+
public:
28+
LIBC_INLINE static void insert(void *elem, void *prev) {
29+
auto elem_header = static_cast<IntrusiveNodeHeader *>(elem);
30+
auto prev_header = static_cast<IntrusiveNodeHeader *>(prev);
31+
32+
if (!prev_header) {
33+
// The list is linear and elem will be the only element.
34+
elem_header->next = nullptr;
35+
elem_header->prev = nullptr;
36+
return;
37+
}
38+
39+
auto next = prev_header->next;
40+
41+
elem_header->next = next;
42+
elem_header->prev = prev_header;
43+
44+
prev_header->next = elem_header;
45+
if (next)
46+
next->prev = elem_header;
47+
}
48+
49+
LIBC_INLINE static void remove(void *elem) {
50+
auto elem_header = static_cast<IntrusiveNodeHeader *>(elem);
51+
52+
auto prev = elem_header->prev;
53+
auto next = elem_header->next;
54+
55+
if (prev)
56+
prev->next = next;
57+
if (next)
58+
next->prev = prev;
59+
}
60+
};
61+
62+
} // namespace internal
63+
} // namespace LIBC_NAMESPACE
64+
65+
#endif // LLVM_LIBC_SRC___SUPPORT_INTRUSIVE_LIST_H

libc/src/search/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,25 @@ add_entrypoint_object(
7676
libc.src.__support.HashTable.table
7777
libc.include.search
7878
)
79+
80+
add_entrypoint_object(
81+
insque
82+
SRCS
83+
insque.cpp
84+
HDRS
85+
insque.h
86+
DEPENDS
87+
libc.include.search
88+
libc.src.__support.intrusive_list
89+
)
90+
91+
add_entrypoint_object(
92+
remque
93+
SRCS
94+
remque.cpp
95+
HDRS
96+
remque.h
97+
DEPENDS
98+
libc.include.search
99+
libc.src.__support.intrusive_list
100+
)

libc/src/search/insque.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation of insque --------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/search/insque.h"
10+
#include "src/__support/common.h"
11+
#include "src/__support/intrusive_list.h"
12+
13+
namespace LIBC_NAMESPACE {
14+
15+
LLVM_LIBC_FUNCTION(void, insque, (void *elem, void *prev)) {
16+
internal::IntrusiveList::insert(elem, prev);
17+
}
18+
19+
} // namespace LIBC_NAMESPACE

libc/src/search/insque.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for insque ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SEARCH_INSQUE_H
10+
#define LLVM_LIBC_SRC_SEARCH_INSQUE_H
11+
12+
#include <search.h>
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
void insque(void *elem, void *prev);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_SEARCH_INSQUE_H

0 commit comments

Comments
 (0)