am a2e5d98b: am 2a8c929a: Merge "Implement __fsetlocking."
* commit 'a2e5d98b641bef4c5611f6aba5defff74abcad93': Implement __fsetlocking.
This commit is contained in:
commit
0edffb85fa
@ -17,6 +17,7 @@
|
|||||||
#include "benchmark.h"
|
#include "benchmark.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdio_ext.h>
|
||||||
|
|
||||||
#define KB 1024
|
#define KB 1024
|
||||||
#define MB 1024*KB
|
#define MB 1024*KB
|
||||||
@ -29,6 +30,7 @@ template <typename Fn>
|
|||||||
static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
|
static void ReadWriteTest(int iters, int chunk_size, Fn f, bool buffered) {
|
||||||
StopBenchmarkTiming();
|
StopBenchmarkTiming();
|
||||||
FILE* fp = fopen("/dev/zero", "rw");
|
FILE* fp = fopen("/dev/zero", "rw");
|
||||||
|
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||||
char* buf = new char[chunk_size];
|
char* buf = new char[chunk_size];
|
||||||
StartBenchmarkTiming();
|
StartBenchmarkTiming();
|
||||||
|
|
||||||
@ -66,12 +68,22 @@ static void BM_stdio_fwrite_unbuffered(int iters, int chunk_size) {
|
|||||||
}
|
}
|
||||||
BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
|
BENCHMARK(BM_stdio_fwrite_unbuffered)->AT_COMMON_SIZES;
|
||||||
|
|
||||||
static void BM_stdio_fopen_fgets_fclose(int iters) {
|
static void FopenFgetsFclose(int iters, bool no_locking) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
for (int i = 0; i < iters; ++i) {
|
for (int i = 0; i < iters; ++i) {
|
||||||
FILE* fp = fopen("/proc/version", "re");
|
FILE* fp = fopen("/proc/version", "re");
|
||||||
|
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||||
fgets(buf, sizeof(buf), fp);
|
fgets(buf, sizeof(buf), fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_stdio_fopen_fgets_fclose);
|
|
||||||
|
static void BM_stdio_fopen_fgets_fclose_locking(int iters) {
|
||||||
|
FopenFgetsFclose(iters, false);
|
||||||
|
}
|
||||||
|
BENCHMARK(BM_stdio_fopen_fgets_fclose_locking);
|
||||||
|
|
||||||
|
static void BM_stdio_fopen_fgets_fclose_no_locking(int iters) {
|
||||||
|
FopenFgetsFclose(iters, true);
|
||||||
|
}
|
||||||
|
BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#define _FILEEXT_H_
|
#define _FILEEXT_H_
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
@ -40,9 +41,10 @@ __BEGIN_DECLS
|
|||||||
* file extension
|
* file extension
|
||||||
*/
|
*/
|
||||||
struct __sfileext {
|
struct __sfileext {
|
||||||
struct __sbuf _ub; /* ungetc buffer */
|
struct __sbuf _ub; /* ungetc buffer */
|
||||||
struct wchar_io_data _wcio; /* wide char io status */
|
struct wchar_io_data _wcio; /* wide char io status */
|
||||||
pthread_mutex_t _lock; /* file lock */
|
pthread_mutex_t _lock; /* file lock */
|
||||||
|
bool _stdio_handles_locking; /* __fsetlocking support */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define _EXT(fp) ((struct __sfileext *)((fp)->_ext._base))
|
#define _EXT(fp) ((struct __sfileext *)((fp)->_ext._base))
|
||||||
@ -54,7 +56,8 @@ do { \
|
|||||||
_UB(fp)._base = NULL; \
|
_UB(fp)._base = NULL; \
|
||||||
_UB(fp)._size = 0; \
|
_UB(fp)._size = 0; \
|
||||||
WCIO_INIT(fp); \
|
WCIO_INIT(fp); \
|
||||||
_FLOCK(fp).value = __PTHREAD_RECURSIVE_MUTEX_INIT_VALUE; \
|
_FLOCK(fp).value = __PTHREAD_RECURSIVE_MUTEX_INIT_VALUE; \
|
||||||
|
_EXT(fp)->_stdio_handles_locking = true; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define _FILEEXT_SETUP(f, fext) \
|
#define _FILEEXT_SETUP(f, fext) \
|
||||||
|
@ -111,8 +111,8 @@ extern void __atexit_register_cleanup(void (*)(void));
|
|||||||
(fp)->_lb._base = NULL; \
|
(fp)->_lb._base = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLOCKFILE(fp) flockfile(fp)
|
#define FLOCKFILE(fp) if (_EXT(fp)->_stdio_handles_locking) flockfile(fp)
|
||||||
#define FUNLOCKFILE(fp) funlockfile(fp)
|
#define FUNLOCKFILE(fp) if (_EXT(fp)->_stdio_handles_locking) funlockfile(fp)
|
||||||
|
|
||||||
#define FLOATING_POINT
|
#define FLOATING_POINT
|
||||||
#define PRINTF_WIDE_CHAR
|
#define PRINTF_WIDE_CHAR
|
||||||
|
@ -27,13 +27,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio_ext.h>
|
#include <stdio_ext.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
|
#include "private/libc_logging.h"
|
||||||
#define FSETLOCKING_QUERY 0
|
|
||||||
#define FSETLOCKING_INTERNAL 1
|
|
||||||
#define FSETLOCKING_BYCALLER 2
|
|
||||||
|
|
||||||
size_t __fbufsize(FILE* fp) {
|
size_t __fbufsize(FILE* fp) {
|
||||||
return fp->_bf._size;
|
return fp->_bf._size;
|
||||||
@ -76,11 +73,19 @@ void _flushlbf() {
|
|||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __fsetlocking(FILE*, int) {
|
int __fsetlocking(FILE* fp, int type) {
|
||||||
// We don't currently have an implementation that would obey this,
|
int old_state = _EXT(fp)->_stdio_handles_locking ? FSETLOCKING_INTERNAL : FSETLOCKING_BYCALLER;
|
||||||
// so make setting the state a no-op and always return "we handle locking for you".
|
if (type == FSETLOCKING_QUERY) {
|
||||||
// http://b/17154740 suggests ways we could fix this.
|
return old_state;
|
||||||
return FSETLOCKING_INTERNAL;
|
}
|
||||||
|
|
||||||
|
if (type != FSETLOCKING_INTERNAL && type != FSETLOCKING_BYCALLER) {
|
||||||
|
// The API doesn't let us report an error, so blow up.
|
||||||
|
__libc_fatal("Bad type (%d) passed to __fsetlocking", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
_EXT(fp)->_stdio_handles_locking = (type == FSETLOCKING_INTERNAL);
|
||||||
|
return old_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearerr_unlocked(FILE* fp) {
|
void clearerr_unlocked(FILE* fp) {
|
||||||
|
@ -133,7 +133,10 @@ TEST(stdio_ext, __freadable__fwritable) {
|
|||||||
|
|
||||||
TEST(stdio_ext, __fsetlocking) {
|
TEST(stdio_ext, __fsetlocking) {
|
||||||
FILE* fp = fopen("/proc/version", "r");
|
FILE* fp = fopen("/proc/version", "r");
|
||||||
// Android doesn't actually support the other modes.
|
ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
|
||||||
|
ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_BYCALLER));
|
||||||
|
ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_QUERY));
|
||||||
|
ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_INTERNAL));
|
||||||
ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
|
ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user