PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
aio_callback.c File Reference
#include "postgres.h"
#include "miscadmin.h"
#include "storage/aio.h"
#include "storage/aio_internal.h"
Include dependency graph for aio_callback.c:

Go to the source code of this file.

Data Structures

struct  PgAioHandleCallbacksEntry
 

Macros

#define CALLBACK_ENTRY(id, callback)   [id] = {.cb = &callback, .name = #callback}
 

Typedefs

typedef struct PgAioHandleCallbacksEntry PgAioHandleCallbacksEntry
 

Functions

void pgaio_io_register_callbacks (PgAioHandle *ioh, PgAioHandleCallbackID cb_id, uint8 cb_data)
 
void pgaio_io_set_handle_data_64 (PgAioHandle *ioh, uint64 *data, uint8 len)
 
void pgaio_io_set_handle_data_32 (PgAioHandle *ioh, uint32 *data, uint8 len)
 
uint64pgaio_io_get_handle_data (PgAioHandle *ioh, uint8 *len)
 
void pgaio_result_report (PgAioResult result, const PgAioTargetData *target_data, int elevel)
 
void pgaio_io_call_stage (PgAioHandle *ioh)
 
void pgaio_io_call_complete_shared (PgAioHandle *ioh)
 
void pgaio_io_call_complete_local (PgAioHandle *ioh)
 

Variables

static const PgAioHandleCallbacks aio_invalid_cb = {0}
 
static const PgAioHandleCallbacksEntry aio_handle_cbs []
 

Macro Definition Documentation

◆ CALLBACK_ENTRY

#define CALLBACK_ENTRY (   id,
  callback 
)    [id] = {.cb = &callback, .name = #callback}

Typedef Documentation

◆ PgAioHandleCallbacksEntry

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_get_handle_data()

uint64 * pgaio_io_get_handle_data ( PgAioHandle ioh,
uint8 len 
)

Definition at line 145 of file aio_callback.c.

146{
147 Assert(ioh->handle_data_len > 0);
148
149 *len = ioh->handle_data_len;
150
151 return &pgaio_ctl->handle_data[ioh->iovec_off];
152}
PgAioCtl * pgaio_ctl
Definition: aio.c:76
const void size_t len
uint64 * handle_data
Definition: aio_internal.h:238
uint8 handle_data_len
Definition: aio_internal.h:117
uint32 iovec_off
Definition: aio_internal.h:159

References Assert(), PgAioCtl::handle_data, PgAioHandle::handle_data_len, PgAioHandle::iovec_off, len, and pgaio_ctl.

◆ pgaio_io_register_callbacks()

void pgaio_io_register_callbacks ( PgAioHandle ioh,
PgAioHandleCallbackID  cb_id,
uint8  cb_data 
)

Definition at line 78 of file aio_callback.c.

80{
81 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
82
83 if (cb_id >= lengthof(aio_handle_cbs))
84 elog(ERROR, "callback %d is out of range", cb_id);
85 if (aio_handle_cbs[cb_id].cb->complete_shared == NULL &&
86 aio_handle_cbs[cb_id].cb->complete_local == NULL)
87 elog(ERROR, "callback %d does not have a completion callback", cb_id);
89 elog(PANIC, "too many callbacks, the max is %d",
91 ioh->callbacks[ioh->num_callbacks] = cb_id;
92 ioh->callbacks_data[ioh->num_callbacks] = cb_data;
93
95 "adding cb #%d, id %d/%s",
96 ioh->num_callbacks + 1,
97 cb_id, ce->name);
98
99 ioh->num_callbacks++;
100}
#define PGAIO_HANDLE_MAX_CALLBACKS
Definition: aio.h:248
#define lengthof(array)
Definition: c.h:759
#define PANIC
Definition: elog.h:42
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225

References aio_handle_cbs, PgAioHandle::callbacks, PgAioHandle::callbacks_data, PgAioHandleCallbacksEntry::cb, PgAioHandleCallbacks::complete_local, DEBUG3, elog, ERROR, lengthof, PgAioHandleCallbacksEntry::name, PgAioHandle::num_callbacks, PANIC, pgaio_debug_io, and PGAIO_HANDLE_MAX_CALLBACKS.

◆ pgaio_io_set_handle_data_32()

void pgaio_io_set_handle_data_32 ( PgAioHandle ioh,
uint32 data,
uint8  len 
)

Definition at line 130 of file aio_callback.c.

131{
133 Assert(ioh->handle_data_len == 0);
135
136 for (int i = 0; i < len; i++)
138 ioh->handle_data_len = len;
139}
@ PGAIO_HS_HANDED_OUT
Definition: aio_internal.h:48
const void * data
#define PG_IOV_MAX
Definition: pg_iovec.h:41
PgAioHandleState state
Definition: aio_internal.h:94

References Assert(), data, PgAioCtl::handle_data, PgAioHandle::handle_data_len, i, PgAioHandle::iovec_off, len, PG_IOV_MAX, pgaio_ctl, PGAIO_HS_HANDED_OUT, and PgAioHandle::state.

◆ pgaio_io_set_handle_data_64()

void pgaio_io_set_handle_data_64 ( PgAioHandle ioh,
uint64 data,
uint8  len 
)

Definition at line 113 of file aio_callback.c.

114{
116 Assert(ioh->handle_data_len == 0);
118
119 for (int i = 0; i < len; i++)
121 ioh->handle_data_len = len;
122}

References Assert(), data, PgAioCtl::handle_data, PgAioHandle::handle_data_len, i, PgAioHandle::iovec_off, len, PG_IOV_MAX, pgaio_ctl, PGAIO_HS_HANDED_OUT, and PgAioHandle::state.

◆ pgaio_result_report()

void pgaio_result_report ( PgAioResult  result,
const PgAioTargetData target_data,
int  elevel 
)

Definition at line 162 of file aio_callback.c.

163{
164 PgAioHandleCallbackID cb_id = result.id;
165 const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
166
167 Assert(result.status != PGAIO_RS_UNKNOWN);
168 Assert(result.status != PGAIO_RS_OK);
169
170 if (ce->cb->report == NULL)
171 elog(ERROR, "callback %d/%s does not have report callback",
172 result.id, ce->name);
173
174 ce->cb->report(result, target_data, elevel);
175}
@ PGAIO_RS_UNKNOWN
Definition: aio_types.h:76
PgAioHandleCallbackReport report
Definition: aio.h:239

References aio_handle_cbs, Assert(), PgAioHandleCallbacksEntry::cb, elog, ERROR, PgAioResult::id, PgAioHandleCallbacksEntry::name, PGAIO_RS_OK, PGAIO_RS_UNKNOWN, PgAioHandleCallbacks::report, and PgAioResult::status.

Variable Documentation

◆ aio_handle_cbs

const PgAioHandleCallbacksEntry aio_handle_cbs[]
static
Initial value:
= {
#define CALLBACK_ENTRY(id, callback)
}
static const PgAioHandleCallbacks aio_invalid_cb
Definition: aio_callback.c:24
#define CALLBACK_ENTRY(id, callback)

Definition at line 37 of file aio_callback.c.

Referenced by pgaio_io_call_complete_local(), pgaio_io_call_complete_shared(), pgaio_io_call_stage(), pgaio_io_register_callbacks(), and pgaio_result_report().

◆ aio_invalid_cb

const PgAioHandleCallbacks aio_invalid_cb = {0}
static

Definition at line 24 of file aio_callback.c.