Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  aio_init.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * aio_init.c
 *    AIO - Subsystem Initialization
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *    src/backend/storage/aio/aio_init.c
 *
 *-------------------------------------------------------------------------
 */


#include "postgres.h"

#include "miscadmin.h"
#include "storage/aio.h"
#include "storage/aio_internal.h"
#include "storage/aio_subsys.h"
#include "storage/bufmgr.h"
#include "storage/io_worker.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/shmem.h"
#include "utils/guc.h"



static Size
AioCtlShmemSize(void)
{
 /* pgaio_ctl itself */
 return sizeof(PgAioCtl);
}

static uint32
AioProcs(void)
{
 /*
  * While AIO workers don't need their own AIO context, we can't currently
  * guarantee nothing gets assigned to the a ProcNumber for an IO worker if
  * we just subtracted MAX_IO_WORKERS.
 */

 return MaxBackends + NUM_AUXILIARY_PROCS;
}

static Size
AioBackendShmemSize(void)
{
 return mul_size(AioProcs(), sizeof(PgAioBackend));
}

static Size
AioHandleShmemSize(void)
{
 Size  sz;

 /* verify AioChooseMaxConcurrency() did its thing */
 Assert(io_max_concurrency > 0);

 /* io handles */
 sz = mul_size(AioProcs(),
      mul_size(io_max_concurrency, sizeof(PgAioHandle)));

 return sz;
}

static Size
AioHandleIOVShmemSize(void)
{
 /* each IO handle can have up to io_max_combine_limit iovec objects */
 return mul_size(sizeof(struct iovec),
     mul_size(mul_size(io_max_combine_limit, AioProcs()),
        io_max_concurrency));
}

static Size
AioHandleDataShmemSize(void)
{
 /* each buffer referenced by an iovec can have associated data */
 return mul_size(sizeof(uint64),
     mul_size(mul_size(io_max_combine_limit, AioProcs()),
        io_max_concurrency));
}

/*
 * Choose a suitable value for io_max_concurrency.
 *
 * It's unlikely that we could have more IOs in flight than buffers that we
 * would be allowed to pin.
 *
 * On the upper end, apply a cap too - just because shared_buffers is large,
 * it doesn't make sense have millions of buffers undergo IO concurrently.
 */

static int
AioChooseMaxConcurrency(void)
{
 uint32  max_backends;
 int   max_proportional_pins;

 /* Similar logic to LimitAdditionalPins() */
 max_backends = MaxBackends + NUM_AUXILIARY_PROCS;
 max_proportional_pins = NBuffers / max_backends;

 max_proportional_pins = Max(max_proportional_pins, 1);

 /* apply upper limit */
 return Min(max_proportional_pins, 64);
}

Size
AioShmemSize(void)
{
 Size  sz = 0;

 /*
  * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
  * However, if the DBA explicitly set io_max_concurrency = -1 in the
  * config file, then PGC_S_DYNAMIC_DEFAULT will fail to override that and
  * we must force the matter with PGC_S_OVERRIDE.
 */

 if (io_max_concurrency == -1)
 {
  char  buf[32];

  snprintf(buf, sizeof(buf), "%d", AioChooseMaxConcurrency());
  SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
      PGC_S_DYNAMIC_DEFAULT);
  if (io_max_concurrency == -1/* failed to apply it? */
   SetConfigOption("io_max_concurrency", buf, PGC_POSTMASTER,
       PGC_S_OVERRIDE);
 }

 sz = add_size(sz, AioCtlShmemSize());
 sz = add_size(sz, AioBackendShmemSize());
 sz = add_size(sz, AioHandleShmemSize());
 sz = add_size(sz, AioHandleIOVShmemSize());
 sz = add_size(sz, AioHandleDataShmemSize());

 /* Reserve space for method specific resources. */
 if (pgaio_method_ops->shmem_size)
  sz = add_size(sz, pgaio_method_ops->shmem_size());

 return sz;
}

void
AioShmemInit(void)
{
 bool  found;
 uint32  io_handle_off = 0;
 uint32  iovec_off = 0;
 uint32  per_backend_iovecs = io_max_concurrency * io_max_combine_limit;

 pgaio_ctl = (PgAioCtl *)
  ShmemInitStruct("AioCtl", AioCtlShmemSize(), &found);

 if (found)
  goto out;

 memset(pgaio_ctl, 0, AioCtlShmemSize());

 pgaio_ctl->io_handle_count = AioProcs() * io_max_concurrency;
 pgaio_ctl->iovec_count = AioProcs() * per_backend_iovecs;

 pgaio_ctl->backend_state = (PgAioBackend *)
  ShmemInitStruct("AioBackend", AioBackendShmemSize(), &found);

 pgaio_ctl->io_handles = (PgAioHandle *)
  ShmemInitStruct("AioHandle", AioHandleShmemSize(), &found);

 pgaio_ctl->iovecs = (struct iovec *)
  ShmemInitStruct("AioHandleIOV", AioHandleIOVShmemSize(), &found);
 pgaio_ctl->handle_data = (uint64 *)
  ShmemInitStruct("AioHandleData", AioHandleDataShmemSize(), &found);

 for (int procno = 0; procno < AioProcs(); procno++)
 {
  PgAioBackend *bs = &pgaio_ctl->backend_state[procno];

  bs->io_handle_off = io_handle_off;
  io_handle_off += io_max_concurrency;

  dclist_init(&bs->idle_ios);
  memset(bs->staged_ios, 0sizeof(PgAioHandle *) * PGAIO_SUBMIT_BATCH_SIZE);
  dclist_init(&bs->in_flight_ios);

  /* initialize per-backend IOs */
  for (int i = 0; i < io_max_concurrency; i++)
  {
   PgAioHandle *ioh = &pgaio_ctl->io_handles[bs->io_handle_off + i];

   ioh->generation = 1;
   ioh->owner_procno = procno;
   ioh->iovec_off = iovec_off;
   ioh->handle_data_len = 0;
   ioh->report_return = NULL;
   ioh->resowner = NULL;
   ioh->num_callbacks = 0;
   ioh->distilled_result.status = PGAIO_RS_UNKNOWN;
   ioh->flags = 0;

   ConditionVariableInit(&ioh->cv);

   dclist_push_tail(&bs->idle_ios, &ioh->node);
   iovec_off += io_max_combine_limit;
  }
 }

out:
 /* Initialize IO method specific resources. */
 if (pgaio_method_ops->shmem_init)
  pgaio_method_ops->shmem_init(!found);
}

void
pgaio_init_backend(void)
{
 /* shouldn't be initialized twice */
 Assert(!pgaio_my_backend);

 if (MyBackendType == B_IO_WORKER)
  return;

 if (MyProc == NULL || MyProcNumber >= AioProcs())
  elog(ERROR, "aio requires a normal PGPROC");

 pgaio_my_backend = &pgaio_ctl->backend_state[MyProcNumber];

 if (pgaio_method_ops->init_backend)
  pgaio_method_ops->init_backend();

 before_shmem_exit(pgaio_shutdown, 0);
}

Messung V0.5 in Prozent
C=93 H=86 G=89

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002