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)
 
void 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_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:334
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errhidestmt(bool hide_stmt)
Definition: elog.c:1411
int errhidecontext(bool hide_ctx)
Definition: elog.c:1430

Definition at line 345 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:322
const char * pgaio_io_get_op_name(PgAioHandle *ioh)
Definition: aio_io.c:169
#define pgaio_debug(elevel, msg,...)
Definition: aio_internal.h:345
const char * pgaio_io_get_target_name(PgAioHandle *ioh)
Definition: aio_target.c:48
const char * pgaio_io_get_state_name(PgAioHandle *ioh)
Definition: aio.c:822

Definition at line 358 of file aio_internal.h.

◆ pgaio_io_call_inj

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

Definition at line 376 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 334 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 38 of file aio_internal.h.

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

Function Documentation

◆ pgaio_io_call_complete_local()

void pgaio_io_call_complete_local ( PgAioHandle ioh)

Definition at line 268 of file aio_callback.c.

269{
270 PgAioResult result;
271
273
275 Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
276
277 /* start with distilled result from shared callback */
278 result = ioh->distilled_result;
279
280 for (int i = ioh->num_callbacks; i > 0; i--)
281 {
282 PgAioHandleCallbackID cb_id = ioh->callbacks[i - 1];
283 uint8 cb_data = ioh->callbacks_data[i - 1];
284 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
285
286 if (!ce->cb->complete_local)
287 continue;
288
290 "calling cb #%d, id %d/%s->complete_local(%u) with distilled result: status %s, id %u, error_data %d, result %d",
291 i, cb_id, ce->name, cb_data,
293 result.id, result.error_data, result.result);
294 result = ce->cb->complete_local(ioh, result, cb_data);
295 }
296
297 /*
298 * Note that we don't save the result in ioh->distilled_result, the local
299 * callback's result should not ever matter to other waiters.
300 */
302 "after local completion: distilled result: (status %s, id %u, error_data %d, result %d), raw_result: %d",
304 result.id, result.error_data, result.result,
305 ioh->result);
306
308}
const char * pgaio_result_status_string(PgAioResultStatus rs)
Definition: aio.c:828
PgAioHandleCallbackID
Definition: aio.h:184
#define PGAIO_TID_COUNT
Definition: aio.h:114
#define PGAIO_OP_COUNT
Definition: aio.h:99
@ PGAIO_TID_INVALID
Definition: aio.h:111
@ PGAIO_OP_INVALID
Definition: aio.h:82
static const PgAioHandleCallbacksEntry aio_handle_cbs[]
Definition: aio_callback.c:37
#define pgaio_debug_io(elevel, ioh, msg,...)
Definition: aio_internal.h:358
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:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
const PgAioHandleCallbacks *const cb
Definition: aio_callback.c:28
const char *const name
Definition: aio_callback.c:29
PgAioHandleCallbackComplete complete_local
Definition: aio.h:232
PgAioResult distilled_result
Definition: aio_internal.h:151
uint8 callbacks[PGAIO_HANDLE_MAX_CALLBACKS]
Definition: aio_internal.h:108
PgAioOp op
Definition: aio_internal.h:100
uint8 callbacks_data[PGAIO_HANDLE_MAX_CALLBACKS]
Definition: aio_internal.h:111
uint8 num_callbacks
Definition: aio_internal.h:105
PgAioTargetID target
Definition: aio_internal.h:97
uint32 status
Definition: aio_types.h:95
uint32 error_data
Definition: aio_types.h:98
int32 result
Definition: aio_types.h:100
uint32 id
Definition: aio_types.h:92

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 214 of file aio_callback.c.

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

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 188 of file aio_callback.c.

189{
191 Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
192
193 for (int i = ioh->num_callbacks; i > 0; i--)
194 {
195 PgAioHandleCallbackID cb_id = ioh->callbacks[i - 1];
196 uint8 cb_data = ioh->callbacks_data[i - 1];
197 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
198
199 if (!ce->cb->stage)
200 continue;
201
203 "calling cb #%d %d/%s->stage(%u)",
204 i, cb_id, ce->name, cb_data);
205 ce->cb->stage(ioh, cb_data);
206 }
207}
PgAioHandleCallbackStage stage
Definition: aio.h:200

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 97 of file aio_target.c.

98{
99 return pgaio_target_info[ioh->target]->reopen != NULL;
100}
static const PgAioTargetInfo * pgaio_target_info[]
Definition: aio_target.c:24
void(* reopen)(PgAioHandle *ioh)
Definition: aio.h:155

References pgaio_target_info, PgAioTargetInfo::reopen, and PgAioHandle::target.

Referenced by pgaio_worker_needs_synchronous_execution().

◆ pgaio_io_get_op_name()

const char * pgaio_io_get_op_name ( PgAioHandle ioh)

Definition at line 169 of file aio_io.c.

170{
171 Assert(ioh->op >= 0 && ioh->op < PGAIO_OP_COUNT);
172
173 switch (ioh->op)
174 {
175 case PGAIO_OP_INVALID:
176 return "invalid";
177 case PGAIO_OP_READV:
178 return "read";
179 case PGAIO_OP_WRITEV:
180 return "write";
181 }
182
183 return NULL; /* silence compiler */
184}
@ PGAIO_OP_WRITEV
Definition: aio.h:85
@ PGAIO_OP_READV
Definition: aio.h:84

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

◆ pgaio_io_get_state_name()

const char * pgaio_io_get_state_name ( PgAioHandle ioh)

Definition at line 822 of file aio.c.

823{
824 return pgaio_io_state_get_name(ioh->state);
825}
static const char * pgaio_io_state_get_name(PgAioHandleState s)
Definition: aio.c:802
PgAioHandleState state
Definition: aio_internal.h:94

References pgaio_io_state_get_name(), and PgAioHandle::state.

◆ pgaio_io_get_target_name()

const char * pgaio_io_get_target_name ( PgAioHandle ioh)

Definition at line 48 of file aio_target.c.

49{
50 Assert(ioh->target >= 0 && ioh->target < PGAIO_TID_COUNT);
51
52 return pgaio_target_info[ioh->target]->name;
53}
const char * name
Definition: aio.h:161

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

◆ pgaio_io_needs_synchronous_execution()

bool pgaio_io_needs_synchronous_execution ( PgAioHandle ioh)

Definition at line 447 of file aio.c.

448{
449 /*
450 * If the caller said to execute the IO synchronously, do so.
451 *
452 * XXX: We could optimize the logic when to execute synchronously by first
453 * checking if there are other IOs in flight and only synchronously
454 * executing if not. Unclear whether that'll be sufficiently common to be
455 * worth worrying about.
456 */
457 if (ioh->flags & PGAIO_HF_SYNCHRONOUS)
458 return true;
459
460 /* Check if the IO method requires synchronous execution of IO */
463
464 return false;
465}
const IoMethodOps * pgaio_method_ops
Definition: aio.c:88
@ PGAIO_HF_SYNCHRONOUS
Definition: aio.h:62
bool(* needs_synchronous_execution)(PgAioHandle *ioh)
Definition: aio_internal.h:274

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:492
PgAioCtl * pgaio_ctl
Definition: aio.c:76
#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
struct iovec * iovecs
Definition: aio_internal.h:229
PgAioOpData op_data
Definition: aio_internal.h:169
uint32 iovec_off
Definition: aio_internal.h:159
uint64 offset
Definition: aio.h:131
int fd
Definition: aio.h:129
uint16 iov_length
Definition: aio.h:130
struct PgAioOpData::@123 write
struct PgAioOpData::@122 read
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101

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

475{
477
479}
PgAioBackend * pgaio_my_backend
Definition: aio.c:79
static void pgaio_io_update_state(PgAioHandle *ioh, PgAioHandleState new_state)
Definition: aio.c:366
static void dclist_push_tail(dclist_head *head, dlist_node *node)
Definition: ilist.h:709
dclist_head in_flight_ios
Definition: aio_internal.h:214
dlist_node node
Definition: aio_internal.h:135

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

493{
495
497
498 ioh->result = result;
499
501
502 pgaio_io_call_inj(ioh, "AIO_PROCESS_COMPLETION_BEFORE_SHARED");
503
505
507
508 /* condition variable broadcast ensures state is visible before wakeup */
510
511 /* contains call to pgaio_io_call_complete_local() */
512 if (ioh->owner_procno == MyProcNumber)
513 pgaio_io_reclaim(ioh);
514}
static void pgaio_io_reclaim(PgAioHandle *ioh)
Definition: aio.c:621
void pgaio_io_call_complete_shared(PgAioHandle *ioh)
Definition: aio_callback.c:214
#define pgaio_io_call_inj(ioh, injection_point)
Definition: aio_internal.h:376
void ConditionVariableBroadcast(ConditionVariable *cv)
ProcNumber MyProcNumber
Definition: globals.c:89
volatile uint32 CritSectionCount
Definition: globals.c:44
int32 owner_procno
Definition: aio_internal.h:120
ConditionVariable cv
Definition: aio_internal.h:148

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)

Definition at line 108 of file aio_target.c.

109{
110 Assert(ioh->target >= 0 && ioh->target < PGAIO_TID_COUNT);
111 Assert(ioh->op >= 0 && ioh->op < PGAIO_OP_COUNT);
112
113 pgaio_target_info[ioh->target]->reopen(ioh);
114}

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

Referenced by IoWorkerMain().

◆ pgaio_io_stage()

void pgaio_io_stage ( PgAioHandle ioh,
PgAioOp  op 
)

Definition at line 397 of file aio.c.

398{
399 bool needs_synchronous;
400
404
405 ioh->op = op;
406 ioh->result = 0;
407
409
410 /* allow a new IO to be staged */
412
414
416
417 /*
418 * Synchronous execution has to be executed, well, synchronously, so check
419 * that first.
420 */
421 needs_synchronous = pgaio_io_needs_synchronous_execution(ioh);
422
424 "prepared (synchronous: %d, in_batch: %d)",
425 needs_synchronous, pgaio_my_backend->in_batchmode);
426
427 if (!needs_synchronous)
428 {
431
432 /*
433 * Unless code explicitly opted into batching IOs, submit the IO
434 * immediately.
435 */
438 }
439 else
440 {
443 }
444}
bool pgaio_io_needs_synchronous_execution(PgAioHandle *ioh)
Definition: aio.c:447
void pgaio_submit_staged(void)
Definition: aio.c:1010
void pgaio_io_prepare_submit(PgAioHandle *ioh)
Definition: aio.c:474
void pgaio_io_call_stage(PgAioHandle *ioh)
Definition: aio_callback.c:188
#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:38
uint16 num_staged_ios
Definition: aio_internal.h:203
PgAioHandle * staged_ios[PGAIO_SUBMIT_BATCH_SIZE]
Definition: aio_internal.h:204
PgAioHandle * handed_out_io
Definition: aio_internal.h:195

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_prep_readv(), and pgaio_io_prep_writev().

◆ pgaio_io_was_recycled()

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

Definition at line 523 of file aio.c.

524{
525 *state = ioh->state;
527
528 return ioh->generation != ref_generation;
529}
#define pg_read_barrier()
Definition: atomics.h:156
uint64 generation
Definition: aio_internal.h:141
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 828 of file aio.c.

829{
830 switch (rs)
831 {
832 case PGAIO_RS_UNKNOWN:
833 return "UNKNOWN";
834 case PGAIO_RS_OK:
835 return "OK";
836 case PGAIO_RS_PARTIAL:
837 return "PARTIAL";
838 case PGAIO_RS_ERROR:
839 return "ERROR";
840 }
841
842 return NULL; /* silence compiler */
843}
@ PGAIO_RS_UNKNOWN
Definition: aio_types.h:76
@ PGAIO_RS_PARTIAL
Definition: aio_types.h:78
@ PGAIO_RS_ERROR
Definition: aio_types.h:79

References PGAIO_RS_ERROR, PGAIO_RS_OK, PGAIO_RS_PARTIAL, and PGAIO_RS_UNKNOWN.

Referenced by 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 1127 of file aio.c.

1128{
1131
1132 /* first clean up resources as we would at a transaction boundary */
1133 AtEOXact_Aio(code == 0);
1134
1135 /*
1136 * Before exiting, make sure that all IOs are finished. That has two main
1137 * purposes:
1138 *
1139 * - Some kernel-level AIO mechanisms don't deal well with the issuer of
1140 * an AIO exiting before IO completed
1141 *
1142 * - It'd be confusing to see partially finished IOs in stats views etc
1143 */
1145 {
1147
1148 /* see comment in pgaio_io_wait_for_free() about raciness */
1149 pgaio_io_wait(ioh, ioh->generation);
1150 }
1151
1152 pgaio_my_backend = NULL;
1153}
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1080
static void pgaio_io_wait(PgAioHandle *ioh, uint64 ref_generation)
Definition: aio.c:536
#define dclist_head_element(type, membername, lhead)
Definition: ilist.h:955
static bool dclist_is_empty(const dclist_head *head)
Definition: ilist.h:682

References Assert(), AtEOXact_Aio(), dclist_head_element, dclist_is_empty(), PgAioHandle::generation, PgAioBackend::handed_out_io, PgAioBackend::in_flight_ios, 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 82 of file method_worker.c.