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, ...)
 

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:316
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:832

Definition at line 389 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:838
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:78
@ 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 832 of file aio.c.

833{
834 return pgaio_io_state_get_name(ioh->state);
835}
static const char * pgaio_io_state_get_name(PgAioHandleState s)
Definition: aio.c:812

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 441 of file aio.c.

442{
443 /*
444 * If the caller said to execute the IO synchronously, do so.
445 *
446 * XXX: We could optimize the logic when to execute synchronously by first
447 * checking if there are other IOs in flight and only synchronously
448 * executing if not. Unclear whether that'll be sufficiently common to be
449 * worth worrying about.
450 */
451 if (ioh->flags & PGAIO_HF_SYNCHRONOUS)
452 return true;
453
454 /* Check if the IO method requires synchronous execution of IO */
457
458 return false;
459}
const IoMethodOps * pgaio_method_ops
Definition: aio.c:93
@ 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:486
#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 468 of file aio.c.

469{
471
473}
PgAioBackend * pgaio_my_backend
Definition: aio.c:81
static void pgaio_io_update_state(PgAioHandle *ioh, PgAioHandleState new_state)
Definition: aio.c:360
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 486 of file aio.c.

487{
489
491
492 ioh->result = result;
493
495
496 INJECTION_POINT("aio-process-completion-before-shared", ioh);
497
499
501
502 /* condition variable broadcast ensures state is visible before wakeup */
504
505 /* contains call to pgaio_io_call_complete_local() */
506 if (ioh->owner_procno == MyProcNumber)
507 pgaio_io_reclaim(ioh);
508}
static void pgaio_io_reclaim(PgAioHandle *ioh)
Definition: aio.c:615
void pgaio_io_call_complete_shared(PgAioHandle *ioh)
Definition: aio_callback.c:225
void ConditionVariableBroadcast(ConditionVariable *cv)
ProcNumber MyProcNumber
Definition: globals.c:91
volatile uint32 CritSectionCount
Definition: globals.c:46
#define INJECTION_POINT(name, arg)
int32 owner_procno
Definition: aio_internal.h:125
ConditionVariable cv
Definition: aio_internal.h:153

References Assert(), ConditionVariableBroadcast(), CritSectionCount, PgAioHandle::cv, INJECTION_POINT, MyProcNumber, PgAioHandle::owner_procno, PGAIO_HS_COMPLETED_IO, PGAIO_HS_COMPLETED_SHARED, PGAIO_HS_SUBMITTED, pgaio_io_call_complete_shared(), 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 391 of file aio.c.

392{
393 bool needs_synchronous;
394
398
399 ioh->op = op;
400 ioh->result = 0;
401
403
404 /* allow a new IO to be staged */
406
408
410
411 /*
412 * Synchronous execution has to be executed, well, synchronously, so check
413 * that first.
414 */
415 needs_synchronous = pgaio_io_needs_synchronous_execution(ioh);
416
418 "staged (synchronous: %d, in_batch: %d)",
419 needs_synchronous, pgaio_my_backend->in_batchmode);
420
421 if (!needs_synchronous)
422 {
425
426 /*
427 * Unless code explicitly opted into batching IOs, submit the IO
428 * immediately.
429 */
432 }
433 else
434 {
437 }
438}
bool pgaio_io_needs_synchronous_execution(PgAioHandle *ioh)
Definition: aio.c:441
void pgaio_submit_staged(void)
Definition: aio.c:1022
void pgaio_io_prepare_submit(PgAioHandle *ioh)
Definition: aio.c:468
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 517 of file aio.c.

518{
519 *state = ioh->state;
521
522 return ioh->generation != ref_generation;
523}
#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 838 of file aio.c.

839{
840 switch (rs)
841 {
842 case PGAIO_RS_UNKNOWN:
843 return "UNKNOWN";
844 case PGAIO_RS_OK:
845 return "OK";
846 case PGAIO_RS_WARNING:
847 return "WARNING";
848 case PGAIO_RS_PARTIAL:
849 return "PARTIAL";
850 case PGAIO_RS_ERROR:
851 return "ERROR";
852 }
853
854 return NULL; /* silence compiler */
855}
@ 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 1184 of file aio.c.

1185{
1188
1189 /* first clean up resources as we would at a transaction boundary */
1190 AtEOXact_Aio(code == 0);
1191
1192 /*
1193 * Before exiting, make sure that all IOs are finished. That has two main
1194 * purposes:
1195 *
1196 * - Some kernel-level AIO mechanisms don't deal well with the issuer of
1197 * an AIO exiting before IO completed
1198 *
1199 * - It'd be confusing to see partially finished IOs in stats views etc
1200 */
1202 {
1204
1206 "waiting for IO to complete during shutdown, %d in-flight IOs",
1208
1209 /* see comment in pgaio_io_wait_for_free() about raciness */
1210 pgaio_io_wait(ioh, ioh->generation);
1211 }
1212
1213 pgaio_my_backend = NULL;
1214}
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1092
static void pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation)
Definition: aio.c:530
#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 84 of file method_worker.c.