PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
aio_internal.h File Reference
#include "lib/ilist.h"
#include "port/pg_iovec.h"
#include "storage/aio.h"
#include "storage/condition_variable.h"
Include dependency graph for aio_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PgAioHandle
 
struct  PgAioBackend
 
struct  PgAioCtl
 
struct  IoMethodOps
 

Macros

#define PGAIO_SUBMIT_BATCH_SIZE   32
 
#define PGAIO_VERBOSE   1
 
#define pgaio_debug(elevel, msg, ...)
 
#define pgaio_debug_io(elevel, ioh, msg, ...)
 
#define pgaio_io_call_inj(ioh, injection_point)   (void) 0
 

Typedefs

typedef enum PgAioHandleState PgAioHandleState
 
typedef struct PgAioBackend PgAioBackend
 
typedef struct PgAioCtl PgAioCtl
 
typedef struct IoMethodOps IoMethodOps
 

Enumerations

enum  PgAioHandleState {
  PGAIO_HS_IDLE = 0 , PGAIO_HS_HANDED_OUT , PGAIO_HS_DEFINED , PGAIO_HS_STAGED ,
  PGAIO_HS_SUBMITTED , PGAIO_HS_COMPLETED_IO , PGAIO_HS_COMPLETED_SHARED , PGAIO_HS_COMPLETED_LOCAL
}
 

Functions

bool pgaio_io_was_recycled (PgAioHandle *ioh, uint64 ref_generation, PgAioHandleState *state)
 
void pgaio_io_stage (PgAioHandle *ioh, PgAioOp op)
 
void pgaio_io_process_completion (PgAioHandle *ioh, int result)
 
void pgaio_io_prepare_submit (PgAioHandle *ioh)
 
bool pgaio_io_needs_synchronous_execution (PgAioHandle *ioh)
 
const char * pgaio_io_get_state_name (PgAioHandle *ioh)
 
const char * pgaio_result_status_string (PgAioResultStatus rs)
 
void pgaio_shutdown (int code, Datum arg)
 
void pgaio_io_call_stage (PgAioHandle *ioh)
 
void pgaio_io_call_complete_shared (PgAioHandle *ioh)
 
PgAioResult pgaio_io_call_complete_local (PgAioHandle *ioh)
 
void pgaio_io_perform_synchronously (PgAioHandle *ioh)
 
const char * pgaio_io_get_op_name (PgAioHandle *ioh)
 
bool pgaio_io_uses_fd (PgAioHandle *ioh, int fd)
 
int pgaio_io_get_iovec_length (PgAioHandle *ioh, struct iovec **iov)
 
bool pgaio_io_can_reopen (PgAioHandle *ioh)
 
void pgaio_io_reopen (PgAioHandle *ioh)
 
const char * pgaio_io_get_target_name (PgAioHandle *ioh)
 

Variables

PGDLLIMPORT const IoMethodOps pgaio_sync_ops
 
PGDLLIMPORT const IoMethodOps pgaio_worker_ops
 
PGDLLIMPORT const IoMethodOpspgaio_method_ops
 
PGDLLIMPORT PgAioCtlpgaio_ctl
 
PGDLLIMPORT PgAioBackendpgaio_my_backend
 

Macro Definition Documentation

◆ pgaio_debug

#define pgaio_debug (   elevel,
  msg,
  ... 
)
Value:
do { \
ereport(elevel, \
errhidestmt(true), errhidecontext(true), \
__VA_ARGS__)); \
} while(0)
#define PGAIO_VERBOSE
Definition: aio_internal.h:365
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
int errhidestmt(bool hide_stmt)
Definition: elog.c:1433
int errhidecontext(bool hide_ctx)
Definition: elog.c:1452

Definition at line 376 of file aio_internal.h.

◆ pgaio_debug_io

#define pgaio_debug_io (   elevel,
  ioh,
  msg,
  ... 
)
Value:
pgaio_debug(elevel, "io %-10d|op %-5s|target %-4s|state %-16s: " msg, \
__VA_ARGS__)
int pgaio_io_get_id(PgAioHandle *ioh)
Definition: aio.c:330
const char * pgaio_io_get_op_name(PgAioHandle *ioh)
Definition: aio_io.c:175
#define pgaio_debug(elevel, msg,...)
Definition: aio_internal.h:376
const char * pgaio_io_get_target_name(PgAioHandle *ioh)
Definition: aio_target.c:50
const char * pgaio_io_get_state_name(PgAioHandle *ioh)
Definition: aio.c:846

Definition at line 389 of file aio_internal.h.

◆ pgaio_io_call_inj

#define pgaio_io_call_inj (   ioh,
  injection_point 
)    (void) 0

Definition at line 407 of file aio_internal.h.

◆ PGAIO_SUBMIT_BATCH_SIZE

#define PGAIO_SUBMIT_BATCH_SIZE   32

Definition at line 28 of file aio_internal.h.

◆ PGAIO_VERBOSE

#define PGAIO_VERBOSE   1

Definition at line 365 of file aio_internal.h.

Typedef Documentation

◆ IoMethodOps

typedef struct IoMethodOps IoMethodOps

◆ PgAioBackend

typedef struct PgAioBackend PgAioBackend

◆ PgAioCtl

typedef struct PgAioCtl PgAioCtl

◆ PgAioHandleState

Enumeration Type Documentation

◆ PgAioHandleState

Enumerator
PGAIO_HS_IDLE 
PGAIO_HS_HANDED_OUT 
PGAIO_HS_DEFINED 
PGAIO_HS_STAGED 
PGAIO_HS_SUBMITTED 
PGAIO_HS_COMPLETED_IO 
PGAIO_HS_COMPLETED_SHARED 
PGAIO_HS_COMPLETED_LOCAL 

Definition at line 43 of file aio_internal.h.

44{
45 /* not in use */
46 PGAIO_HS_IDLE = 0,
47
48 /*
49 * Returned by pgaio_io_acquire(). The next state is either DEFINED (if
50 * pgaio_io_start_*() is called), or IDLE (if pgaio_io_release() is
51 * called).
52 */
54
55 /*
56 * pgaio_io_start_*() has been called, but IO is not yet staged. At this
57 * point the handle has all the information for the IO to be executed.
58 */
60
61 /*
62 * stage() callbacks have been called, handle ready to be submitted for
63 * execution. Unless in batchmode (see c.f. pgaio_enter_batchmode()), the
64 * IO will be submitted immediately after.
65 */
67
68 /* IO has been submitted to the IO method for execution */
70
71 /* IO finished, but result has not yet been processed */
73
74 /*
75 * IO completed, shared completion has been called.
76 *
77 * If the IO completion occurs in the issuing backend, local callbacks
78 * will immediately be called. Otherwise the handle stays in
79 * COMPLETED_SHARED until the issuing backend waits for the completion of
80 * the IO.
81 */
83
84 /*
85 * IO completed, local completion has been called.
86 *
87 * After this the handle will be made reusable and go into IDLE state.
88 */
PgAioHandleState
Definition: aio_internal.h:44
@ PGAIO_HS_STAGED
Definition: aio_internal.h:66
@ PGAIO_HS_COMPLETED_SHARED
Definition: aio_internal.h:82
@ PGAIO_HS_DEFINED
Definition: aio_internal.h:59
@ PGAIO_HS_SUBMITTED
Definition: aio_internal.h:69
@ PGAIO_HS_IDLE
Definition: aio_internal.h:46
@ PGAIO_HS_HANDED_OUT
Definition: aio_internal.h:53
@ PGAIO_HS_COMPLETED_IO
Definition: aio_internal.h:72
@ PGAIO_HS_COMPLETED_LOCAL
Definition: aio_internal.h:89

Function Documentation

◆ pgaio_io_call_complete_local()

PgAioResult pgaio_io_call_complete_local ( PgAioHandle ioh)

Definition at line 282 of file aio_callback.c.

283{
284 PgAioResult result;
285
287
289 Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
290
291 /* start with distilled result from shared callback */
292 result = ioh->distilled_result;
293
294 for (int i = ioh->num_callbacks; i > 0; i--)
295 {
296 PgAioHandleCallbackID cb_id = ioh->callbacks[i - 1];
297 uint8 cb_data = ioh->callbacks_data[i - 1];
298 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
299
300 if (!ce->cb->complete_local)
301 continue;
302
304 "calling cb #%d, id %d/%s->complete_local(%u) with distilled result: status %s, id %u, error_data %d, result %d",
305 i, cb_id, ce->name, cb_data,
307 result.id, result.error_data, result.result);
308 result = ce->cb->complete_local(ioh, result, cb_data);
309 }
310
311 /*
312 * Note that we don't save the result in ioh->distilled_result, the local
313 * callback's result should not ever matter to other waiters. However, the
314 * local backend does care, so we return the result as modified by local
315 * callbacks, which then can be passed to ioh->report_return->result.
316 */
318 "after local completion: result: (status %s, id %u, error_data %d, result %d), raw_result: %d",
320 result.id, result.error_data, result.result,
321 ioh->result);
322
324
325 return result;
326}
const char * pgaio_result_status_string(PgAioResultStatus rs)
Definition: aio.c:852
PgAioHandleCallbackID
Definition: aio.h:193
#define PGAIO_TID_COUNT
Definition: aio.h:123
#define PGAIO_OP_COUNT
Definition: aio.h:107
@ PGAIO_TID_INVALID
Definition: aio.h:119
@ PGAIO_OP_INVALID
Definition: aio.h:90
static const PgAioHandleCallbacksEntry aio_handle_cbs[]
Definition: aio_callback.c:39
#define pgaio_debug_io(elevel, ioh, msg,...)
Definition: aio_internal.h:389
uint8_t uint8
Definition: c.h:500
#define DEBUG3
Definition: elog.h:28
#define DEBUG4
Definition: elog.h:27
Assert(PointerIsAligned(start, uint64))
int i
Definition: isn.c:77
#define START_CRIT_SECTION()
Definition: miscadmin.h:150
#define END_CRIT_SECTION()
Definition: miscadmin.h:152
const PgAioHandleCallbacks *const cb
Definition: aio_callback.c:30
const char *const name
Definition: aio_callback.c:31
PgAioHandleCallbackComplete complete_local
Definition: aio.h:251
PgAioResult distilled_result
Definition: aio_internal.h:156
uint8 callbacks[PGAIO_HANDLE_MAX_CALLBACKS]
Definition: aio_internal.h:113
PgAioOp op
Definition: aio_internal.h:105
uint8 callbacks_data[PGAIO_HANDLE_MAX_CALLBACKS]
Definition: aio_internal.h:116
uint8 num_callbacks
Definition: aio_internal.h:110
PgAioTargetID target
Definition: aio_internal.h:102
uint32 status
Definition: aio_types.h:108
uint32 error_data
Definition: aio_types.h:111
int32 result
Definition: aio_types.h:113
uint32 id
Definition: aio_types.h:105

References aio_handle_cbs, Assert(), PgAioHandle::callbacks, PgAioHandle::callbacks_data, PgAioHandleCallbacksEntry::cb, PgAioHandleCallbacks::complete_local, DEBUG3, DEBUG4, PgAioHandle::distilled_result, END_CRIT_SECTION, PgAioResult::error_data, i, PgAioResult::id, PgAioHandleCallbacksEntry::name, PgAioHandle::num_callbacks, PgAioHandle::op, pgaio_debug_io, PGAIO_OP_COUNT, PGAIO_OP_INVALID, pgaio_result_status_string(), PGAIO_TID_COUNT, PGAIO_TID_INVALID, PgAioHandle::result, PgAioResult::result, START_CRIT_SECTION, PgAioResult::status, and PgAioHandle::target.

Referenced by pgaio_io_reclaim().

◆ pgaio_io_call_complete_shared()

void pgaio_io_call_complete_shared ( PgAioHandle ioh)

Definition at line 225 of file aio_callback.c.

226{
227 PgAioResult result;
228
230
232 Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
233
234 result.status = PGAIO_RS_OK; /* low level IO is always considered OK */
235 result.result = ioh->result;
236 result.id = PGAIO_HCB_INVALID;
237 result.error_data = 0;
238
239 /*
240 * Call callbacks with the last registered (innermost) callback first.
241 * Each callback can modify the result forwarded to the next callback.
242 */
243 for (int i = ioh->num_callbacks; i > 0; i--)
244 {
245 PgAioHandleCallbackID cb_id = ioh->callbacks[i - 1];
246 uint8 cb_data = ioh->callbacks_data[i - 1];
247 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
248
249 if (!ce->cb->complete_shared)
250 continue;
251
253 "calling cb #%d, id %d/%s->complete_shared(%u) with distilled result: (status %s, id %u, error_data %d, result %d)",
254 i, cb_id, ce->name,
255 cb_data,
257 result.id, result.error_data, result.result);
258 result = ce->cb->complete_shared(ioh, result, cb_data);
259 }
260
261 ioh->distilled_result = result;
262
264 "after shared completion: distilled result: (status %s, id %u, error_data: %d, result %d), raw_result: %d",
266 result.id, result.error_data, result.result,
267 ioh->result);
268
270}
@ PGAIO_HCB_INVALID
Definition: aio.h:194
@ PGAIO_RS_OK
Definition: aio_types.h:81
PgAioHandleCallbackComplete complete_shared
Definition: aio.h:239

References aio_handle_cbs, Assert(), PgAioHandle::callbacks, PgAioHandle::callbacks_data, PgAioHandleCallbacksEntry::cb, PgAioHandleCallbacks::complete_shared, DEBUG3, DEBUG4, PgAioHandle::distilled_result, END_CRIT_SECTION, PgAioResult::error_data, i, PgAioResult::id, PgAioHandleCallbacksEntry::name, PgAioHandle::num_callbacks, PgAioHandle::op, pgaio_debug_io, PGAIO_HCB_INVALID, PGAIO_OP_COUNT, PGAIO_OP_INVALID, pgaio_result_status_string(), PGAIO_RS_OK, PGAIO_TID_COUNT, PGAIO_TID_INVALID, PgAioHandle::result, PgAioResult::result, START_CRIT_SECTION, PgAioResult::status, and PgAioHandle::target.

Referenced by pgaio_io_process_completion().

◆ pgaio_io_call_stage()

void pgaio_io_call_stage ( PgAioHandle ioh)

Definition at line 199 of file aio_callback.c.

200{
202 Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
203
204 for (int i = ioh->num_callbacks; i > 0; i--)
205 {
206 PgAioHandleCallbackID cb_id = ioh->callbacks[i - 1];
207 uint8 cb_data = ioh->callbacks_data[i - 1];
208 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
209
210 if (!ce->cb->stage)
211 continue;
212
214 "calling cb #%d %d/%s->stage(%u)",
215 i, cb_id, ce->name, cb_data);
216 ce->cb->stage(ioh, cb_data);
217 }
218}
PgAioHandleCallbackStage stage
Definition: aio.h:219

References aio_handle_cbs, Assert(), PgAioHandle::callbacks, PgAioHandle::callbacks_data, PgAioHandleCallbacksEntry::cb, DEBUG3, i, PgAioHandleCallbacksEntry::name, PgAioHandle::num_callbacks, PgAioHandle::op, pgaio_debug_io, PGAIO_OP_COUNT, PGAIO_OP_INVALID, PGAIO_TID_COUNT, PGAIO_TID_INVALID, PgAioHandleCallbacks::stage, and PgAioHandle::target.

Referenced by pgaio_io_stage().

◆ pgaio_io_can_reopen()

bool pgaio_io_can_reopen ( PgAioHandle ioh)

Definition at line 103 of file aio_target.c.

104{
106
107 return pgaio_target_info[ioh->target]->reopen != NULL;
108}
static const PgAioTargetInfo * pgaio_target_info[]
Definition: aio_target.c:25
void(* reopen)(PgAioHandle *ioh)
Definition: aio.h:164

References Assert(), pgaio_target_info, PGAIO_TID_COUNT, PGAIO_TID_INVALID, PgAioTargetInfo::reopen, and PgAioHandle::target.

Referenced by pgaio_worker_needs_synchronous_execution().

◆ pgaio_io_get_iovec_length()

int pgaio_io_get_iovec_length ( PgAioHandle ioh,
struct iovec **  iov 
)

Definition at line 219 of file aio_io.c.

220{
222
223 *iov = &pgaio_ctl->iovecs[ioh->iovec_off];
224
225 switch (ioh->op)
226 {
227 case PGAIO_OP_READV:
228 return ioh->op_data.read.iov_length;
229 case PGAIO_OP_WRITEV:
230 return ioh->op_data.write.iov_length;
231 default:
233 return 0;
234 }
235}
PgAioCtl * pgaio_ctl
Definition: aio.c:81
@ PGAIO_OP_WRITEV
Definition: aio.h:93
@ PGAIO_OP_READV
Definition: aio.h:92
#define pg_unreachable()
Definition: c.h:332
struct iovec * iovecs
Definition: aio_internal.h:234
PgAioOpData op_data
Definition: aio_internal.h:174
uint32 iovec_off
Definition: aio_internal.h:164
PgAioHandleState state
Definition: aio_internal.h:99
uint16 iov_length
Definition: aio.h:139
struct PgAioOpData::@123 write
struct PgAioOpData::@122 read

References Assert(), PgAioOpData::iov_length, PgAioHandle::iovec_off, PgAioCtl::iovecs, PgAioHandle::op, PgAioHandle::op_data, pg_unreachable, pgaio_ctl, PGAIO_HS_DEFINED, PGAIO_OP_READV, PGAIO_OP_WRITEV, PgAioOpData::read, PgAioHandle::state, and PgAioOpData::write.

Referenced by IoWorkerMain().

◆ pgaio_io_get_op_name()

const char * pgaio_io_get_op_name ( PgAioHandle ioh)

Definition at line 175 of file aio_io.c.

176{
177 Assert(ioh->op >= 0 && ioh->op < PGAIO_OP_COUNT);
178
179 switch (ioh->op)
180 {
181 case PGAIO_OP_INVALID:
182 return "invalid";
183 case PGAIO_OP_READV:
184 return "read";
185 case PGAIO_OP_WRITEV:
186 return "write";
187 }
188
189 return NULL; /* silence compiler */
190}

References Assert(), PgAioHandle::op, PGAIO_OP_COUNT, PGAIO_OP_INVALID, PGAIO_OP_READV, and PGAIO_OP_WRITEV.

Referenced by pg_get_aios().

◆ pgaio_io_get_state_name()

const char * pgaio_io_get_state_name ( PgAioHandle ioh)

Definition at line 846 of file aio.c.

847{
848 return pgaio_io_state_get_name(ioh->state);
849}
static const char * pgaio_io_state_get_name(PgAioHandleState s)
Definition: aio.c:826

References pgaio_io_state_get_name(), and PgAioHandle::state.

Referenced by pg_get_aios().

◆ pgaio_io_get_target_name()

const char * pgaio_io_get_target_name ( PgAioHandle ioh)

Definition at line 50 of file aio_target.c.

51{
52 /* explicitly allow INVALID here, function used by debug messages */
54
55 return pgaio_target_info[ioh->target]->name;
56}
const char * name
Definition: aio.h:170

References Assert(), PgAioTargetInfo::name, pgaio_target_info, PGAIO_TID_COUNT, PGAIO_TID_INVALID, and PgAioHandle::target.

Referenced by pg_get_aios().

◆ pgaio_io_needs_synchronous_execution()

bool pgaio_io_needs_synchronous_execution ( PgAioHandle ioh)

Definition at line 455 of file aio.c.

456{
457 /*
458 * If the caller said to execute the IO synchronously, do so.
459 *
460 * XXX: We could optimize the logic when to execute synchronously by first
461 * checking if there are other IOs in flight and only synchronously
462 * executing if not. Unclear whether that'll be sufficiently common to be
463 * worth worrying about.
464 */
465 if (ioh->flags & PGAIO_HF_SYNCHRONOUS)
466 return true;
467
468 /* Check if the IO method requires synchronous execution of IO */
471
472 return false;
473}
const IoMethodOps * pgaio_method_ops
Definition: aio.c:96
@ PGAIO_HF_SYNCHRONOUS
Definition: aio.h:70
bool(* needs_synchronous_execution)(PgAioHandle *ioh)
Definition: aio_internal.h:288

References PgAioHandle::flags, IoMethodOps::needs_synchronous_execution, PGAIO_HF_SYNCHRONOUS, and pgaio_method_ops.

Referenced by pgaio_io_stage().

◆ pgaio_io_perform_synchronously()

void pgaio_io_perform_synchronously ( PgAioHandle ioh)

Definition at line 116 of file aio_io.c.

117{
118 ssize_t result = 0;
119 struct iovec *iov = &pgaio_ctl->iovecs[ioh->iovec_off];
120
122
123 /* Perform IO. */
124 switch (ioh->op)
125 {
126 case PGAIO_OP_READV:
127 pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_READ);
128 result = pg_preadv(ioh->op_data.read.fd, iov,
130 ioh->op_data.read.offset);
132 break;
133 case PGAIO_OP_WRITEV:
134 pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_WRITE);
135 result = pg_pwritev(ioh->op_data.write.fd, iov,
137 ioh->op_data.write.offset);
139 break;
140 case PGAIO_OP_INVALID:
141 elog(ERROR, "trying to execute invalid IO operation");
142 }
143
144 ioh->result = result < 0 ? -errno : result;
145
147
149}
void pgaio_io_process_completion(PgAioHandle *ioh, int result)
Definition: aio.c:500
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:87
static ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:48
uint64 offset
Definition: aio.h:140
int fd
Definition: aio.h:138
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:69
static void pgstat_report_wait_end(void)
Definition: wait_event.h:85

References elog, END_CRIT_SECTION, ERROR, PgAioOpData::fd, PgAioOpData::iov_length, PgAioHandle::iovec_off, PgAioCtl::iovecs, PgAioOpData::offset, PgAioHandle::op, PgAioHandle::op_data, pg_preadv(), pg_pwritev(), pgaio_ctl, pgaio_io_process_completion(), PGAIO_OP_INVALID, PGAIO_OP_READV, PGAIO_OP_WRITEV, pgstat_report_wait_end(), pgstat_report_wait_start(), PgAioOpData::read, PgAioHandle::result, START_CRIT_SECTION, and PgAioOpData::write.

Referenced by IoWorkerMain(), pgaio_io_stage(), and pgaio_worker_submit_internal().

◆ pgaio_io_prepare_submit()

void pgaio_io_prepare_submit ( PgAioHandle ioh)

Definition at line 482 of file aio.c.

483{
485
487}
PgAioBackend * pgaio_my_backend
Definition: aio.c:84
static void pgaio_io_update_state(PgAioHandle *ioh, PgAioHandleState new_state)
Definition: aio.c:374
static void dclist_push_tail(dclist_head *head, dlist_node *node)
Definition: ilist.h:709
dclist_head in_flight_ios
Definition: aio_internal.h:219
dlist_node node
Definition: aio_internal.h:140

References dclist_push_tail(), PgAioBackend::in_flight_ios, PgAioHandle::node, PGAIO_HS_SUBMITTED, pgaio_io_update_state(), and pgaio_my_backend.

Referenced by pgaio_io_stage(), and pgaio_worker_submit().

◆ pgaio_io_process_completion()

void pgaio_io_process_completion ( PgAioHandle ioh,
int  result 
)

Definition at line 500 of file aio.c.

501{
503
505
506 ioh->result = result;
507
509
510 pgaio_io_call_inj(ioh, "aio-process-completion-before-shared");
511
513
515
516 /* condition variable broadcast ensures state is visible before wakeup */
518
519 /* contains call to pgaio_io_call_complete_local() */
520 if (ioh->owner_procno == MyProcNumber)
521 pgaio_io_reclaim(ioh);
522}
static void pgaio_io_reclaim(PgAioHandle *ioh)
Definition: aio.c:629
void pgaio_io_call_complete_shared(PgAioHandle *ioh)
Definition: aio_callback.c:225
#define pgaio_io_call_inj(ioh, injection_point)
Definition: aio_internal.h:407
void ConditionVariableBroadcast(ConditionVariable *cv)
ProcNumber MyProcNumber
Definition: globals.c:91
volatile uint32 CritSectionCount
Definition: globals.c:46
int32 owner_procno
Definition: aio_internal.h:125
ConditionVariable cv
Definition: aio_internal.h:153

References Assert(), ConditionVariableBroadcast(), CritSectionCount, PgAioHandle::cv, MyProcNumber, PgAioHandle::owner_procno, PGAIO_HS_COMPLETED_IO, PGAIO_HS_COMPLETED_SHARED, PGAIO_HS_SUBMITTED, pgaio_io_call_complete_shared(), pgaio_io_call_inj, pgaio_io_reclaim(), pgaio_io_update_state(), PgAioHandle::result, and PgAioHandle::state.

Referenced by IoWorkerMain(), and pgaio_io_perform_synchronously().

◆ pgaio_io_reopen()

void pgaio_io_reopen ( PgAioHandle ioh)

◆ pgaio_io_stage()

void pgaio_io_stage ( PgAioHandle ioh,
PgAioOp  op 
)

Definition at line 405 of file aio.c.

406{
407 bool needs_synchronous;
408
412
413 ioh->op = op;
414 ioh->result = 0;
415
417
418 /* allow a new IO to be staged */
420
422
424
425 /*
426 * Synchronous execution has to be executed, well, synchronously, so check
427 * that first.
428 */
429 needs_synchronous = pgaio_io_needs_synchronous_execution(ioh);
430
432 "staged (synchronous: %d, in_batch: %d)",
433 needs_synchronous, pgaio_my_backend->in_batchmode);
434
435 if (!needs_synchronous)
436 {
439
440 /*
441 * Unless code explicitly opted into batching IOs, submit the IO
442 * immediately.
443 */
446 }
447 else
448 {
451 }
452}
bool pgaio_io_needs_synchronous_execution(PgAioHandle *ioh)
Definition: aio.c:455
void pgaio_submit_staged(void)
Definition: aio.c:1036
void pgaio_io_prepare_submit(PgAioHandle *ioh)
Definition: aio.c:482
void pgaio_io_call_stage(PgAioHandle *ioh)
Definition: aio_callback.c:199
#define PGAIO_SUBMIT_BATCH_SIZE
Definition: aio_internal.h:28
void pgaio_io_perform_synchronously(PgAioHandle *ioh)
Definition: aio_io.c:116
bool pgaio_io_has_target(PgAioHandle *ioh)
Definition: aio_target.c:40
uint16 num_staged_ios
Definition: aio_internal.h:208
PgAioHandle * staged_ios[PGAIO_SUBMIT_BATCH_SIZE]
Definition: aio_internal.h:209
PgAioHandle * handed_out_io
Definition: aio_internal.h:200

References Assert(), DEBUG3, PgAioBackend::handed_out_io, PgAioBackend::in_batchmode, PgAioBackend::num_staged_ios, PgAioHandle::op, pgaio_debug_io, PGAIO_HS_DEFINED, PGAIO_HS_HANDED_OUT, PGAIO_HS_STAGED, pgaio_io_call_stage(), pgaio_io_has_target(), pgaio_io_needs_synchronous_execution(), pgaio_io_perform_synchronously(), pgaio_io_prepare_submit(), pgaio_io_update_state(), pgaio_my_backend, PGAIO_SUBMIT_BATCH_SIZE, pgaio_submit_staged(), PgAioHandle::result, PgAioBackend::staged_ios, and PgAioHandle::state.

Referenced by pgaio_io_start_readv(), and pgaio_io_start_writev().

◆ pgaio_io_uses_fd()

bool pgaio_io_uses_fd ( PgAioHandle ioh,
int  fd 
)

Definition at line 197 of file aio_io.c.

198{
200
201 switch (ioh->op)
202 {
203 case PGAIO_OP_READV:
204 return ioh->op_data.read.fd == fd;
205 case PGAIO_OP_WRITEV:
206 return ioh->op_data.write.fd == fd;
207 case PGAIO_OP_INVALID:
208 return false;
209 }
210
211 return false; /* silence compiler */
212}
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References Assert(), PgAioOpData::fd, fd(), PgAioHandle::op, PgAioHandle::op_data, PGAIO_HS_DEFINED, PGAIO_OP_INVALID, PGAIO_OP_READV, PGAIO_OP_WRITEV, PgAioOpData::read, PgAioHandle::state, and PgAioOpData::write.

Referenced by pgaio_closing_fd().

◆ pgaio_io_was_recycled()

bool pgaio_io_was_recycled ( PgAioHandle ioh,
uint64  ref_generation,
PgAioHandleState state 
)

Definition at line 531 of file aio.c.

532{
533 *state = ioh->state;
535
536 return ioh->generation != ref_generation;
537}
#define pg_read_barrier()
Definition: atomics.h:156
uint64 generation
Definition: aio_internal.h:146
Definition: regguts.h:323

References PgAioHandle::generation, pg_read_barrier, and PgAioHandle::state.

Referenced by pgaio_io_wait(), and pgaio_wref_check_done().

◆ pgaio_result_status_string()

const char * pgaio_result_status_string ( PgAioResultStatus  rs)

Definition at line 852 of file aio.c.

853{
854 switch (rs)
855 {
856 case PGAIO_RS_UNKNOWN:
857 return "UNKNOWN";
858 case PGAIO_RS_OK:
859 return "OK";
860 case PGAIO_RS_WARNING:
861 return "WARNING";
862 case PGAIO_RS_PARTIAL:
863 return "PARTIAL";
864 case PGAIO_RS_ERROR:
865 return "ERROR";
866 }
867
868 return NULL; /* silence compiler */
869}
@ PGAIO_RS_UNKNOWN
Definition: aio_types.h:80
@ PGAIO_RS_PARTIAL
Definition: aio_types.h:82
@ PGAIO_RS_ERROR
Definition: aio_types.h:84
@ PGAIO_RS_WARNING
Definition: aio_types.h:83

References PGAIO_RS_ERROR, PGAIO_RS_OK, PGAIO_RS_PARTIAL, PGAIO_RS_UNKNOWN, and PGAIO_RS_WARNING.

Referenced by pg_get_aios(), pgaio_io_call_complete_local(), pgaio_io_call_complete_shared(), and pgaio_io_reclaim().

◆ pgaio_shutdown()

void pgaio_shutdown ( int  code,
Datum  arg 
)

Definition at line 1198 of file aio.c.

1199{
1202
1203 /* first clean up resources as we would at a transaction boundary */
1204 AtEOXact_Aio(code == 0);
1205
1206 /*
1207 * Before exiting, make sure that all IOs are finished. That has two main
1208 * purposes:
1209 *
1210 * - Some kernel-level AIO mechanisms don't deal well with the issuer of
1211 * an AIO exiting before IO completed
1212 *
1213 * - It'd be confusing to see partially finished IOs in stats views etc
1214 */
1216 {
1218
1220 "waiting for IO to complete during shutdown, %d in-flight IOs",
1222
1223 /* see comment in pgaio_io_wait_for_free() about raciness */
1224 pgaio_io_wait(ioh, ioh->generation);
1225 }
1226
1227 pgaio_my_backend = NULL;
1228}
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1106
static void pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation)
Definition: aio.c:544
#define DEBUG2
Definition: elog.h:29
#define dclist_head_element(type, membername, lhead)
Definition: ilist.h:955
static uint32 dclist_count(const dclist_head *head)
Definition: ilist.h:932
static bool dclist_is_empty(const dclist_head *head)
Definition: ilist.h:682

References Assert(), AtEOXact_Aio(), dclist_count(), dclist_head_element, dclist_is_empty(), DEBUG2, PgAioHandle::generation, PgAioBackend::handed_out_io, PgAioBackend::in_flight_ios, pgaio_debug_io, pgaio_io_wait(), and pgaio_my_backend.

Referenced by pgaio_init_backend().

Variable Documentation

◆ pgaio_ctl

◆ pgaio_method_ops

◆ pgaio_my_backend

◆ pgaio_sync_ops

PGDLLIMPORT const IoMethodOps pgaio_sync_ops
extern

Definition at line 28 of file method_sync.c.

◆ pgaio_worker_ops

PGDLLIMPORT const IoMethodOps pgaio_worker_ops
extern

Definition at line 83 of file method_worker.c.