Skip to content

Commit 945e022

Browse files
author
Siva Chandra Reddy
committed
[libc] Add GNU extention functions fread_unlocked and fwrite_unlocked.
POSIX locking and unlocking functions flockfile and funlockfile have also been added. The locking is not recursive yet. A future patch will make the underlying lock a recursive lock. Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D123986
1 parent 009048a commit 945e022

18 files changed

+352
-14
lines changed

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,14 @@ if(LLVM_LIBC_FULL_BUILD)
252252

253253
# stdio.h entrypoints
254254
libc.src.stdio.fclose
255+
libc.src.stdio.flockfile
255256
libc.src.stdio.fopen
256257
libc.src.stdio.fread
258+
libc.src.stdio.fread_unlocked
257259
libc.src.stdio.fseek
260+
libc.src.stdio.funlockfile
258261
libc.src.stdio.fwrite
262+
libc.src.stdio.fwrite_unlocked
259263

260264
# signal.h entrypoints
261265
# TODO: Enable signal.h entrypoints after fixing signal.h

libc/spec/gnu_ext.td

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,36 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
6565
]
6666
>;
6767

68+
HeaderSpec StdIO = HeaderSpec<
69+
"stdio.h",
70+
[], // Macros
71+
[], // Types
72+
[], // Enumerations
73+
[
74+
FunctionSpec<
75+
"fread_unlocked",
76+
RetValSpec<SizeTType>,
77+
[ArgSpec<VoidRestrictedPtr>,
78+
ArgSpec<SizeTType>,
79+
ArgSpec<SizeTType>,
80+
ArgSpec<FILERestrictedPtr>]
81+
>,
82+
FunctionSpec<
83+
"fwrite_unlocked",
84+
RetValSpec<SizeTType>,
85+
[ArgSpec<ConstVoidRestrictedPtr>,
86+
ArgSpec<SizeTType>,
87+
ArgSpec<SizeTType>,
88+
ArgSpec<FILERestrictedPtr>]
89+
>,
90+
]
91+
>;
92+
6893
let Headers = [
6994
CType,
7095
FEnv,
71-
Math,
96+
Math,
97+
StdIO,
7298
String,
7399
];
74100
}

libc/spec/posix.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,12 +502,32 @@ def POSIX : StandardSpec<"POSIX"> {
502502
]
503503
>;
504504

505+
HeaderSpec StdIO = HeaderSpec<
506+
"stdio.h",
507+
[], // Macros
508+
[], // Types
509+
[], // Enumerations
510+
[
511+
FunctionSpec<
512+
"flockfile",
513+
RetValSpec<VoidType>,
514+
[ArgSpec<FILEPtr>]
515+
>,
516+
FunctionSpec<
517+
"funlockfile",
518+
RetValSpec<VoidType>,
519+
[ArgSpec<FILEPtr>]
520+
>,
521+
]
522+
>;
523+
505524
let Headers = [
506525
CType,
507526
Errno,
508527
FCntl,
509528
PThread,
510529
Signal,
530+
StdIO,
511531
StdLib,
512532
SysMMan,
513533
SysStat,

libc/spec/spec.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ def QSortCompareT : NamedType<"__qsortcompare_t">;
103103

104104
def AtexitHandlerT : NamedType<"__atexithandler_t">;
105105

106+
def FILE : NamedType<"FILE">;
107+
def FILEPtr : PtrType<FILE>;
108+
def FILERestrictedPtr : RestrictedPtrType<FILE>;
109+
106110
//added because __assert_fail needs it.
107111
def UnsignedType : NamedType<"unsigned">;
108112

libc/spec/stdc.td

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
def StdC : StandardSpec<"stdc"> {
22

3-
NamedType FILE = NamedType<"FILE">;
4-
PtrType FILEPtr = PtrType<FILE>;
5-
RestrictedPtrType FILERestrictedPtr = RestrictedPtrType<FILE>;
63
NamedType StructTmType = NamedType<"struct tm">;
74
PtrType StructTmPtr = PtrType<StructTmType>;
85
PtrType TimeTTypePtr = PtrType<TimeTType>;

libc/src/__support/File/file.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616

1717
namespace __llvm_libc {
1818

19-
size_t File::write(const void *data, size_t len) {
20-
FileLock lock(this);
21-
19+
size_t File::write_unlocked(const void *data, size_t len) {
2220
if (!write_allowed()) {
2321
errno = EBADF;
2422
err = true;
@@ -76,9 +74,7 @@ size_t File::write(const void *data, size_t len) {
7674
return len;
7775
}
7876

79-
size_t File::read(void *data, size_t len) {
80-
FileLock lock(this);
81-
77+
size_t File::read_unlocked(void *data, size_t len) {
8278
if (!read_allowed()) {
8379
errno = EBADF;
8480
err = true;

libc/src/__support/File/file.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,27 @@ class File {
145145
f->eof = f->err = false;
146146
}
147147

148-
// Buffered write of |len| bytes from |data|.
149-
size_t write(const void *data, size_t len);
148+
// Buffered write of |len| bytes from |data| without the file lock.
149+
size_t write_unlocked(const void *data, size_t len);
150+
151+
// Buffered write of |len| bytes from |data| under the file lock.
152+
size_t write(const void *data, size_t len) {
153+
lock();
154+
size_t ret = write_unlocked(data, len);
155+
unlock();
156+
return ret;
157+
}
158+
159+
// Buffered read of |len| bytes into |data| without the file lock.
160+
size_t read_unlocked(void *data, size_t len);
150161

151-
// Buffered read of |len| bytes into |data|.
152-
size_t read(void *data, size_t len);
162+
// Buffered read of |len| bytes into |data| under the file lock.
163+
size_t read(void *data, size_t len) {
164+
lock();
165+
size_t ret = read_unlocked(data, len);
166+
unlock();
167+
return ret;
168+
}
153169

154170
int seek(long offset, int whence);
155171

libc/src/stdio/CMakeLists.txt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,42 @@ add_entrypoint_object(
2424
libc.src.__support.File.platform_file
2525
)
2626

27+
add_entrypoint_object(
28+
flockfile
29+
SRCS
30+
flockfile.cpp
31+
HDRS
32+
flockfile.h
33+
DEPENDS
34+
libc.include.stdio
35+
libc.src.__support.File.file
36+
libc.src.__support.File.platform_file
37+
)
38+
39+
add_entrypoint_object(
40+
funlockfile
41+
SRCS
42+
funlockfile.cpp
43+
HDRS
44+
funlockfile.h
45+
DEPENDS
46+
libc.include.stdio
47+
libc.src.__support.File.file
48+
libc.src.__support.File.platform_file
49+
)
50+
51+
add_entrypoint_object(
52+
fread_unlocked
53+
SRCS
54+
fread_unlocked.cpp
55+
HDRS
56+
fread_unlocked.h
57+
DEPENDS
58+
libc.include.stdio
59+
libc.src.__support.File.file
60+
libc.src.__support.File.platform_file
61+
)
62+
2763
add_entrypoint_object(
2864
fread
2965
SRCS
@@ -36,6 +72,18 @@ add_entrypoint_object(
3672
libc.src.__support.File.platform_file
3773
)
3874

75+
add_entrypoint_object(
76+
fwrite_unlocked
77+
SRCS
78+
fwrite_unlocked.cpp
79+
HDRS
80+
fwrite_unlocked.h
81+
DEPENDS
82+
libc.include.stdio
83+
libc.src.__support.File.file
84+
libc.src.__support.File.platform_file
85+
)
86+
3987
add_entrypoint_object(
4088
fwrite
4189
SRCS

libc/src/stdio/flockfile.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation of flockfile ---------------------------------------===//
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/stdio/flockfile.h"
10+
#include "src/__support/File/file.h"
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
LLVM_LIBC_FUNCTION(void, flockfile, (::FILE * stream)) {
17+
reinterpret_cast<__llvm_libc::File *>(stream)->lock();
18+
}
19+
20+
} // namespace __llvm_libc

libc/src/stdio/flockfile.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header of flockfile ----------------------*- 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_STDIO_FLOCKFILE_H
10+
#define LLVM_LIBC_SRC_STDIO_FLOCKFILE_H
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
void flockfile(::FILE *stream);
17+
18+
} // namespace __llvm_libc
19+
20+
#endif // LLVM_LIBC_SRC_STDIO_FLOCKFILE_H

0 commit comments

Comments
 (0)