PostgreSQL Source Code: src/backend/storage/ipc/shmem.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

67

78

81

82

83

85

86static void *ShmemBase;

87

88static void *ShmemEnd;

89

90slock_t *ShmemLock;

91

92

93static HTAB *ShmemIndex = NULL;

94

95

97

99

100

101

102

103void

105{

109}

110

111

112

113

114

115

116void

118{

120 char *aligned;

121

122 Assert(shmhdr != NULL);

123

124

125

126

127

129

131

132

133

134

135

136

137 aligned = (char *)

139 shmhdr->freeoffset = aligned - (char *) shmhdr;

140

141

142 shmhdr->index = NULL;

144}

145

146

147

148

149

150

151

152

153void *

155{

156 void *newSpace;

157 Size allocated_size;

158

160 if (!newSpace)

162 (errcode(ERRCODE_OUT_OF_MEMORY),

163 errmsg("out of shared memory (%zu bytes requested)",

164 size)));

165 return newSpace;

166}

167

168

169

170

171

172

173void *

175{

176 Size allocated_size;

177

179}

180

181

182

183

184

185

186

187static void *

189{

190 Size newStart;

191 Size newFree;

192 void *newSpace;

193

194

195

196

197

198

199

200

201

202

203

204

206 *allocated_size = size;

207

209

211

213

214 newFree = newStart + size;

215 if (newFree <= ShmemSegHdr->totalsize)

216 {

217 newSpace = (char *) ShmemBase + newStart;

219 }

220 else

221 newSpace = NULL;

222

224

225

227

228 return newSpace;

229}

230

231

232

233

234

235

236

237

238

239static void *

241{

242 Size newStart;

243 Size newFree;

244 void *newSpace;

245

246

247

248

250

252

254

255 newFree = newStart + size;

258 (errcode(ERRCODE_OUT_OF_MEMORY),

259 errmsg("out of shared memory (%zu bytes requested)",

260 size)));

262

263 newSpace = (char *) ShmemBase + newStart;

264

266

267 return newSpace;

268}

269

270

271

272

273

274

275bool

277{

279}

280

281

282

283

284void

286{

288

289

290

291

292

293

294

295

296

299

302 &info,

304}

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

335 int64 init_size,

336 int64 max_size,

337 HASHCTL *infoP,

338 int hash_flags)

339{

340 bool found;

341 void *location;

342

343

344

345

346

347

348

349

353

354

357 &found);

358

359

360

361

362

363 if (found)

365

366

368

370}

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388void *

390{

392 void *structPtr;

393

395

397 {

399

400

401 Assert(strcmp(name, "ShmemIndex") == 0);

402

404 {

405

407 structPtr = shmemseghdr->index;

408 *foundPtr = true;

409 }

410 else

411 {

412

413

414

415

416

417

418

419

422 shmemseghdr->index = structPtr;

423 *foundPtr = false;

424 }

426 return structPtr;

427 }

428

429

432

433 if (!result)

434 {

437 (errcode(ERRCODE_OUT_OF_MEMORY),

438 errmsg("could not create ShmemIndex entry for data structure \"%s\"",

440 }

441

442 if (*foundPtr)

443 {

444

445

446

447

448

449 if (result->size != size)

450 {

453 (errmsg("ShmemIndex entry size is wrong for data structure"

454 " \"%s\": expected %zu, actual %zu",

456 }

457 structPtr = result->location;

458 }

459 else

460 {

461 Size allocated_size;

462

463

464 structPtr = ShmemAllocRaw(size, &allocated_size);

465 if (structPtr == NULL)

466 {

467

471 (errcode(ERRCODE_OUT_OF_MEMORY),

472 errmsg("not enough shared memory for data structure"

473 " \"%s\" (%zu bytes requested)",

474 name, size)));

475 }

476 result->size = size;

478 result->location = structPtr;

479 }

480

482

484

486

487 return structPtr;

488}

489

490

491

492

493

496{

498

501 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

502 errmsg("requested shared memory size overflows size_t")));

503 return result;

504}

505

506

507

508

511{

513

516 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

517 errmsg("requested shared memory size overflows size_t")));

518 return result;

519}

520

521

524{

525#define PG_GET_SHMEM_SIZES_COLS 4

529 Size named_allocated = 0;

532

534

536

538

539

540 memset(nulls, 0, sizeof(nulls));

542 {

547 named_allocated += ent->allocated_size;

548

551 }

552

553

555 nulls[1] = true;

559

560

561 nulls[0] = true;

563 nulls[1] = false;

567

569

570 return (Datum) 0;

571}

572

573

574

575

576

577

578

581{

582#define PG_GET_SHMEM_NUMA_SIZES_COLS 3

588 Size os_page_size;

589 void **page_ptrs;

590 int *pages_status;

591 uint64 shm_total_page_count,

592 shm_ent_page_count,

593 max_nodes;

595

597 elog(ERROR, "libnuma initialization failed or NUMA is not supported on this platform");

598

600

603

604

605

606

607

608

609

610

611

612

614

615

616

617

618

619

620

621

622

623

624

625

627 page_ptrs = palloc0_array(void *, shm_total_page_count);

628 pages_status = palloc_array(int, shm_total_page_count);

629

631 elog(DEBUG1, "NUMA: page-faulting shared memory segments for proper NUMA readouts");

632

634

636

637

638 memset(nulls, 0, sizeof(nulls));

640 {

641 int i;

642 char *startptr,

643 *endptr;

644 Size total_len;

645

646

647

648

649

650

651

652 startptr = (char *) TYPEALIGN_DOWN(os_page_size, ent->location);

653 endptr = (char *) TYPEALIGN(os_page_size,

654 (char *) ent->location + ent->allocated_size);

655 total_len = (endptr - startptr);

656

657 shm_ent_page_count = total_len / os_page_size;

658

659

660

661

662

663 memset(pages_status, 0xff, sizeof(int) * shm_ent_page_count);

664

665

666

667

668

669

670

671

672

673 for (i = 0; i < shm_ent_page_count; i++)

674 {

675 page_ptrs[i] = startptr + (i * os_page_size);

676

679

681 }

682

683 if (pg_numa_query_pages(0, shm_ent_page_count, page_ptrs, pages_status) == -1)

684 elog(ERROR, "failed NUMA pages inquiry status: %m");

685

686

687 memset(nodes, 0, sizeof(Size) * (max_nodes + 1));

688

689 for (i = 0; i < shm_ent_page_count; i++)

690 {

691 int s = pages_status[i];

692

693

694 if (s < 0 || s > max_nodes)

695 {

696 elog(ERROR, "invalid NUMA node id outside of allowed range "

698 }

699

700 nodes[s]++;

701 }

702

703

704

705

706

707 for (i = 0; i <= max_nodes; i++)

708 {

712

715 }

716 }

717

720

721 return (Datum) 0;

722}

723

724

725

726

727

728

729

730

731

734{

735 Size os_page_size;

736#ifdef WIN32

737 SYSTEM_INFO sysinfo;

738

739 GetSystemInfo(&sysinfo);

740 os_page_size = sysinfo.dwPageSize;

741#else

742 os_page_size = sysconf(_SC_PAGESIZE);

743#endif

744

747

750

751 return os_page_size;

752}

753

756{

758}

static Datum values[MAXATTR]

#define CStringGetTextDatum(s)

#define CACHELINEALIGN(LEN)

#define TYPEALIGN(ALIGNVAL, LEN)

#define TYPEALIGN_DOWN(ALIGNVAL, LEN)

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)

Size hash_get_shared_size(HASHCTL *info, int flags)

int64 hash_select_dirsize(int64 num_entries)

void * hash_seq_search(HASH_SEQ_STATUS *status)

void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define palloc_array(type, count)

#define palloc0_array(type, count)

#define PG_RETURN_BOOL(x)

void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)

Assert(PointerIsAligned(start, uint64))

static bool pg_mul_size_overflow(size_t a, size_t b, size_t *result)

static bool pg_add_size_overflow(size_t a, size_t b, size_t *result)

if(TABLE==NULL||TABLE_index==NULL)

bool LWLockAcquire(LWLock *lock, LWLockMode mode)

void LWLockRelease(LWLock *lock)

#define CHECK_FOR_INTERRUPTS()

PGDLLIMPORT int pg_numa_get_max_node(void)

#define pg_numa_touch_mem_if_required(ptr)

PGDLLIMPORT int pg_numa_query_pages(int pid, unsigned long count, void **pages, int *status)

PGDLLIMPORT int pg_numa_init(void)

static Datum Int64GetDatum(int64 X)

static Datum Int32GetDatum(int32 X)

bool ShmemAddrIsValid(const void *addr)

Datum pg_get_shmem_allocations_numa(PG_FUNCTION_ARGS)

Datum pg_numa_available(PG_FUNCTION_ARGS)

Datum pg_get_shmem_allocations(PG_FUNCTION_ARGS)

void InitShmemIndex(void)

void InitShmemAccess(PGShmemHeader *seghdr)

Size add_size(Size s1, Size s2)

Size pg_get_shmem_pagesize(void)

#define PG_GET_SHMEM_NUMA_SIZES_COLS

void * ShmemAllocNoError(Size size)

Size mul_size(Size s1, Size s2)

void * ShmemAlloc(Size size)

HTAB * ShmemInitHash(const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)

#define PG_GET_SHMEM_SIZES_COLS

void InitShmemAllocation(void)

static PGShmemHeader * ShmemSegHdr

static void * ShmemAllocRaw(Size size, Size *allocated_size)

void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)

static void * ShmemAllocUnlocked(Size size)

static bool firstNumaTouch

#define SHMEM_INDEX_KEYSIZE

#define SpinLockInit(lock)

#define SpinLockRelease(lock)

#define SpinLockAcquire(lock)

Tuplestorestate * setResult

void GetHugePageSize(Size *hugepagesize, int *mmap_flags)

void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)