Skip to content

Commit 6654bb9

Browse files
committed
Add prefetching support on macOS
macOS doesn't have posix_fadvise(), but fcntl() with the F_RDADVISE command does the same thing. Some related documentation has been generalized to not mention posix_advise() specifically anymore. Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/0827edec-1317-4917-a186-035eb1e3241d%40eisentraut.org
1 parent 2e6a804 commit 6654bb9

File tree

6 files changed

+54
-35
lines changed

6 files changed

+54
-35
lines changed

doc/src/sgml/config.sgml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2679,11 +2679,9 @@ include_dir 'conf.d'
26792679
</para>
26802680

26812681
<para>
2682-
Asynchronous I/O depends on an effective <function>posix_fadvise</function>
2683-
function, which some operating systems lack. If the function is not
2684-
present then setting this parameter to anything but zero will result
2685-
in an error. On some operating systems (e.g., Solaris), the function
2686-
is present but does not actually do anything.
2682+
Asynchronous I/O requires that the operating system supports issuing
2683+
read-ahead advice. If there is no operating system support then
2684+
setting this parameter to anything but zero will result in an error.
26872685
</para>
26882686

26892687
<para>
@@ -3852,10 +3850,8 @@ include_dir 'conf.d'
38523850
<literal>off</literal>, <literal>on</literal> and
38533851
<literal>try</literal> (the default). The setting
38543852
<literal>try</literal> enables
3855-
prefetching only if the operating system provides the
3856-
<function>posix_fadvise</function> function, which is currently used
3857-
to implement prefetching. Note that some operating systems provide the
3858-
function, but it doesn't do anything.
3853+
prefetching only if the operating system provides support for issuing
3854+
read-ahead advice.
38593855
</para>
38603856
<para>
38613857
Prefetching blocks that will soon be needed can reduce I/O wait times

doc/src/sgml/wal.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,8 @@
841841
The <xref linkend="guc-maintenance-io-concurrency"/> and
842842
<xref linkend="guc-wal-decode-buffer-size"/> settings limit prefetching
843843
concurrency and distance, respectively. By default, it is set to
844-
<literal>try</literal>, which enables the feature on systems where
845-
<function>posix_fadvise</function> is available.
844+
<literal>try</literal>, which enables the feature on systems that support
845+
issuing read-ahead advice.
846846
</para>
847847
</sect1>
848848

src/backend/commands/variable.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ check_effective_io_concurrency(int *newval, void **extra, GucSource source)
12121212
#ifndef USE_PREFETCH
12131213
if (*newval != 0)
12141214
{
1215-
GUC_check_errdetail("\"effective_io_concurrency\" must be set to 0 on platforms that lack posix_fadvise().");
1215+
GUC_check_errdetail("\"effective_io_concurrency\" must be set to 0 on platforms that lack support for issuing read-ahead advice.");
12161216
return false;
12171217
}
12181218
#endif /* USE_PREFETCH */
@@ -1225,7 +1225,7 @@ check_maintenance_io_concurrency(int *newval, void **extra, GucSource source)
12251225
#ifndef USE_PREFETCH
12261226
if (*newval != 0)
12271227
{
1228-
GUC_check_errdetail("\"maintenance_io_concurrency\" must be set to 0 on platforms that lack posix_fadvise().");
1228+
GUC_check_errdetail("\"maintenance_io_concurrency\" must be set to 0 on platforms that lack support for issuing read-ahead advice.");
12291229
return false;
12301230
}
12311231
#endif /* USE_PREFETCH */

src/backend/storage/file/fd.c

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,40 +2068,59 @@ FileClose(File file)
20682068
/*
20692069
* FilePrefetch - initiate asynchronous read of a given range of the file.
20702070
*
2071-
* Currently the only implementation of this function is using posix_fadvise
2072-
* which is the simplest standardized interface that accomplishes this.
2073-
* We could add an implementation using libaio in the future; but note that
2074-
* this API is inappropriate for libaio, which wants to have a buffer provided
2075-
* to read into.
2071+
* Returns 0 on success, otherwise an errno error code (like posix_fadvise()).
2072+
*
2073+
* posix_fadvise() is the simplest standardized interface that accomplishes
2074+
* this.
20762075
*/
20772076
int
20782077
FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info)
20792078
{
2080-
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2081-
int returnCode;
2082-
20832079
Assert(FileIsValid(file));
20842080

20852081
DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
20862082
file, VfdCache[file].fileName,
20872083
(int64) offset, (int64) amount));
20882084

2089-
returnCode = FileAccess(file);
2090-
if (returnCode < 0)
2091-
return returnCode;
2085+
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2086+
{
2087+
int returnCode;
2088+
2089+
returnCode = FileAccess(file);
2090+
if (returnCode < 0)
2091+
return returnCode;
20922092

20932093
retry:
2094-
pgstat_report_wait_start(wait_event_info);
2095-
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2096-
POSIX_FADV_WILLNEED);
2097-
pgstat_report_wait_end();
2094+
pgstat_report_wait_start(wait_event_info);
2095+
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2096+
POSIX_FADV_WILLNEED);
2097+
pgstat_report_wait_end();
20982098

2099-
if (returnCode == EINTR)
2100-
goto retry;
2099+
if (returnCode == EINTR)
2100+
goto retry;
21012101

2102-
return returnCode;
2102+
return returnCode;
2103+
}
2104+
#elif defined(__darwin__)
2105+
{
2106+
struct radvisory
2107+
{
2108+
off_t ra_offset; /* offset into the file */
2109+
int ra_count; /* size of the read */
2110+
} ra;
2111+
int returnCode;
2112+
2113+
ra.ra_offset = offset;
2114+
ra.ra_count = amount;
2115+
pgstat_report_wait_start(wait_event_info);
2116+
returnCode = fcntl(VfdCache[file].fd, F_RDADVISE, &ra);
2117+
pgstat_report_wait_end();
2118+
if (returnCode != -1)
2119+
return 0;
2120+
else
2121+
return errno;
2122+
}
21032123
#else
2104-
Assert(FileIsValid(file));
21052124
return 0;
21062125
#endif
21072126
}

src/include/pg_config_manual.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,8 @@
139139
/*
140140
* USE_PREFETCH code should be compiled only if we have a way to implement
141141
* prefetching. (This is decoupled from USE_POSIX_FADVISE because there
142-
* might in future be support for alternative low-level prefetch APIs.
143-
* If you change this, you probably need to adjust the error message in
144-
* check_effective_io_concurrency.)
142+
* might in future be support for alternative low-level prefetch APIs,
143+
* as well as platform-specific APIs defined elsewhere.)
145144
*/
146145
#ifdef USE_POSIX_FADVISE
147146
#define USE_PREFETCH

src/include/port/darwin.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@
66
#define HAVE_FSYNC_WRITETHROUGH
77

88
#endif
9+
10+
/*
11+
* macOS has a platform-specific implementation of prefetching.
12+
*/
13+
#define USE_PREFETCH

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy