PostgreSQL Source Code: src/backend/utils/mmgr/dsa.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

52

61

62

63

64

65

66

67

68

69#define DSA_NUM_SEGMENTS_AT_EACH_SIZE 2

70

71

72

73

74

75#define DSA_MAX_SEGMENTS \

76 Min(1024, (1 << ((SIZEOF_DSA_POINTER * 8) - DSA_OFFSET_WIDTH)))

77

78

79#define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1)

80

81

82#define DSA_PAGES_PER_SUPERBLOCK 16

83

84

85

86

87

88

89#define DSA_SEGMENT_HEADER_MAGIC 0x0ce26608

90

91

92#define DSA_MAKE_POINTER(segment_number, offset) \

93 (((dsa_pointer) (segment_number) << DSA_OFFSET_WIDTH) | (offset))

94

95

96#define DSA_EXTRACT_SEGMENT_NUMBER(dp) ((dp) >> DSA_OFFSET_WIDTH)

97

98

99#define DSA_EXTRACT_OFFSET(dp) ((dp) & DSA_OFFSET_BITMASK)

100

101

103

104

105#define DSA_SEGMENT_INDEX_NONE (~(dsa_segment_index)0)

106

107

108

109

110

111#define DSA_NUM_SEGMENT_BINS 16

112

113

114

115

116

117

118static inline size_t

120{

121 size_t bin;

122

123 if (n == 0)

124 bin = 0;

125 else

127

129}

130

131

132#define DSA_AREA_LOCK(area) (&area->control->lock)

133#define DSA_SCLASS_LOCK(area, sclass) (&area->control->pools[sclass].lock)

134

135

136

137

138

139

140typedef struct

141{

142

144

146

148

149

150

151

152

154

155

156

157

158

160

162

163

164

165

166

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183typedef struct

184{

189 size_t npages;

194 uint16 nmax;

197

198

199

200

201

202#define NextFreeObjectIndex(object) (* (uint16 *) (object))

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

226 sizeof(dsa_area_span), 0,

227 8, 16, 24, 32, 40, 48, 56, 64,

228 80, 96, 112, 128,

229 160, 192, 224, 256,

230 320, 384, 448, 512,

231 640, 768, 896, 1024,

232 1280, 1560, 1816, 2048,

233 2616, 3120, 3640, 4096,

234 5456, 6552, 7280, 8192

235};

236#define DSA_NUM_SIZE_CLASSES lengthof(dsa_size_classes)

237

238

239#define DSA_SCLASS_BLOCK_OF_SPANS 0

240#define DSA_SCLASS_SPAN_LARGE 1

241

242

243

244

245

246

247

249 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13,

250 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17,

251 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,

252 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21,

253 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,

254 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,

255 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,

256 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25

257};

258#define DSA_SIZE_CLASS_MAP_QUANTUM 8

259

260

261

262

263

264

265

266#define DSA_FULLNESS_CLASSES 4

267

268

269

270

271

272

273

274typedef struct

275{

276

278

280

282

283

284

285

286

287typedef struct

288{

289

291

293

295

297

299

301

303

305

307

309

311

313

315

317

320

321

322#define DsaAreaPoolToDsaPointer(area, p) \

323 DSA_MAKE_POINTER(0, (char *) p - (char *) area->control)

324

325

326

327

328

329

330

331

332typedef struct

333{

340

341

342

343

344

345

346

348{

349

351

352

353

354

355

356

357

359

360

361

362

363

364

365

367

368

370

371

373};

374

375#define DSA_SPAN_NOTHING_FREE ((uint16) -1)

376#define DSA_SUPERBLOCK_SIZE (DSA_PAGES_PER_SUPERBLOCK * FPM_PAGE_SIZE)

377

378

379#define get_segment_index(area, segment_map_ptr) \

380 (segment_map_ptr - &area->segment_maps[0])

381

386 int fromclass, int toclass);

389 int size_class);

400 int tranche_id,

403 size_t init_segment_size,

404 size_t max_segment_size);

410

411

412

413

414

415

416

417

418

419

421dsa_create_ext(int tranche_id, size_t init_segment_size, size_t max_segment_size)

422{

425

426

427

428

429

430 segment = dsm_create(init_segment_size, 0);

431

432

433

434

435

436

437

439

440

442 init_segment_size,

443 tranche_id,

445 init_segment_size, max_segment_size);

446

447

450

451 return area;

452}

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

473 size_t init_segment_size, size_t max_segment_size)

474{

476

479 init_segment_size, max_segment_size);

480

481

482

483

484

485 if (segment != NULL)

488

489 return area;

490}

491

492

493

494

495

496

499{

502}

503

504

505

506

507

508

511{

514

515

516

517

518

520 if (segment == NULL)

522 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

523 errmsg("could not attach to dynamic shared area")));

524

526

527

530

531 return area;

532}

533

534

535

536

537

538

539

540

541

542

543

546{

548

550

551

552

553

554

555 if (segment != NULL)

558

559 return area;

560}

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575void

577{

579}

580

581

582

583

584

585

586

587

588

589void

591{

593}

594

595

596

597

598

599

600

601

602

603

604void

606{

608 int i;

609

614 if (--control->refcnt == 0)

615 {

617 {

619

623 }

624 }

626}

627

628

629

630

631

632

633

634void

636{

637 int i;

638

640 {

642

646 }

647}

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

672{

677

679

680

683 elog(ERROR, "invalid DSA memory alloc request size %zu", size);

684

685

686

687

688

689

690

691

693 {

695 size_t first_page;

698

699

702 {

703

706 (errcode(ERRCODE_OUT_OF_MEMORY),

707 errmsg("out of memory"),

708 errdetail("Failed on DSA request of size %zu.",

709 size)));

711 }

712

714

715

717 if (segment_map == NULL)

719 if (segment_map == NULL)

720 {

721

723 dsa_free(area, span_pointer);

724

725

728 (errcode(ERRCODE_OUT_OF_MEMORY),

729 errmsg("out of memory"),

730 errdetail("Failed on DSA request of size %zu.",

731 size)));

733 }

734

735

736

737

738

739

740

741

744 "dsa_allocate could not find %zu free pages", npages);

746

749

750

753 init_span(area, span_pointer, pool, start_pointer, npages,

755 segment_map->pagemap[first_page] = span_pointer;

757

758

761

762 return start_pointer;

763 }

764

765

767 {

768 int mapidx;

769

770

774 }

775 else

776 {

779

780

783

784 while (min < max)

785 {

786 uint16 mid = (min + max) / 2;

788

789 if (class_size < size)

790 min = mid + 1;

791 else

792 max = mid;

793 }

794

795 size_class = min;

796 }

799

800

802

803

805 {

806

809 (errcode(ERRCODE_OUT_OF_MEMORY),

810 errmsg("out of memory"),

811 errdetail("Failed on DSA request of size %zu.", size)));

813 }

814

815

818

819 return result;

820}

821

822

823

824

825void

827{

829 int pageno;

832 char *superblock;

833 char *object;

834 size_t size;

835 int size_class;

836

837

839

840

843 span_pointer = segment_map->pagemap[pageno];

849

850

851

852

853

855 {

856

857#ifdef CLOBBER_FREED_MEMORY

859#endif

860

861

866

867

870

871

876

877 dsa_free(area, span_pointer);

878 return;

879 }

880

881#ifdef CLOBBER_FREED_MEMORY

882 memset(object, 0x7f, size);

883#endif

884

886

887

888 Assert(object >= superblock);

890 Assert((object - superblock) % size == 0);

892 span->firstfree = (object - superblock) / size;

894

895

896

897

898

900 {

901

902

903

904

905

909

910

911

912

913

914

915

916

917 }

920 {

921

922

923

924

925

926

927

928

930 }

931

933}

934

935

936

937

938

939

940

941void *

943{

945 size_t offset;

946

947

949 return NULL;

950

951

953

954

958

959

961 {

962

964 }

965

967}

968

969

970

971

972

973

974void

976{

979 {

981 elog(ERROR, "dsa_area already pinned");

982 }

986}

987

988

989

990

991

992

993void

995{

999 {

1001 elog(ERROR, "dsa_area not pinned");

1002 }

1006}

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017void

1019{

1023}

1024

1025

1026size_t

1028{

1029 size_t size;

1030

1034

1035 return size;

1036}

1037

1038

1039

1040

1041

1042void

1044{

1045 int size_class;

1046

1047

1048

1049

1050

1052 {

1055

1057 {

1058

1059 continue;

1060 }

1061

1062

1063

1064

1065

1066

1068 span_pointer = pool->spans[1];

1070 {

1073

1076

1077 span_pointer = next;

1078 }

1080 }

1081}

1082

1083

1084

1085

1086

1087void

1089{

1090 size_t i,

1091 j;

1092

1093

1094

1095

1096

1097

1101 fprintf(stderr, " max_total_segment_size: %zu\n",

1103 fprintf(stderr, " total_segment_size: %zu\n",

1107 fprintf(stderr, " segment bins:\n");

1109 {

1111 {

1113

1114 if (i == 0)

1116 " segment bin %zu (no contiguous free pages):\n", i);

1117 else

1119 " segment bin %zu (at least %d contiguous pages free):\n",

1120 i, 1 << (i - 1));

1123 {

1125

1126 segment_map =

1128

1130 " segment index %zu, usable_pages = %zu, "

1131 "contiguous_pages = %zu, mapped at %p\n",

1132 segment_index,

1136 segment_index = segment_map->header->next;

1137 }

1138 }

1139 }

1141

1142 fprintf(stderr, " pools:\n");

1144 {

1145 bool found = false;

1146

1150 found = true;

1151 if (found)

1152 {

1154 fprintf(stderr, " pool for blocks of span objects:\n");

1156 fprintf(stderr, " pool for large object spans:\n");

1157 else

1159 " pool for size class %zu (object size %hu bytes):\n",

1162 {

1164 fprintf(stderr, " fullness class %zu is empty\n", j);

1165 else

1166 {

1168

1169 fprintf(stderr, " fullness class %zu:\n", j);

1171 {

1173

1176 " span descriptor at "

1179 ", pages = %zu, objects free = %hu/%hu\n",

1180 span_pointer, span->start, span->npages,

1182 span_pointer = span->nextspan;

1183 }

1184 }

1185 }

1186 }

1188 }

1189}

1190

1191

1192

1193

1194

1195size_t

1197{

1198 size_t size;

1199 int pages = 0;

1200

1203

1204

1206 {

1207 ++pages;

1209 }

1210

1212}

1213

1214

1215

1216

1219 int tranche_id,

1222 size_t init_segment_size, size_t max_segment_size)

1223{

1227 size_t usable_pages;

1228 size_t total_pages;

1229 size_t metadata_bytes;

1230 int i;

1231

1232

1234 Assert(max_segment_size >= init_segment_size);

1236

1237

1239 elog(ERROR, "dsa_area space must be at least %zu, but %zu provided",

1241

1242

1244 metadata_bytes =

1248

1251 Assert(metadata_bytes <= size);

1252 usable_pages = (size - metadata_bytes) / FPM_PAGE_SIZE;

1253

1254

1255

1256

1257

1259 memset(place, 0, sizeof(*control));

1267 control->handle = control_handle;

1275 control->refcnt = 1;

1277

1278

1279

1280

1281

1282

1284 area->control = control;

1293

1294

1296 segment_map->segment = control_segment;

1306

1307

1309

1310

1311 if (usable_pages > 0)

1313 usable_pages);

1314

1315

1318

1319 return area;

1320}

1321

1322

1323

1324

1327{

1331

1337

1338

1340 area->control = control;

1345

1346

1348 segment_map->segment = segment;

1356

1357

1359 if (control->refcnt == 0)

1360 {

1361

1363 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

1364 errmsg("could not attach to dynamic shared area")));

1365 }

1369

1370 return area;

1371}

1372

1373

1374

1375

1376static void

1381{

1384

1385

1386

1387

1388

1390

1391

1393 {

1396

1397 head->prevspan = span_pointer;

1398 }

1402 pool->spans[1] = span_pointer;

1403

1405 span->npages = npages;

1409 {

1410

1411

1412

1413

1414

1415

1416

1419 }

1425}

1426

1427

1428

1429

1430

1431static bool

1433 dsa_area_pool *pool, int fromclass, int toclass)

1434{

1438

1439

1440 span_pointer = pool->spans[fromclass];

1442 return false;

1443

1444

1448 {

1452 }

1453

1454

1456 pool->spans[toclass] = span_pointer;

1458 {

1461 nextspan->prevspan = span_pointer;

1462 }

1463 span->fclass = toclass;

1464

1465 return true;

1466}

1467

1468

1469

1470

1473{

1478 char *object;

1479 size_t size;

1480

1481

1482

1483

1484

1485

1486

1489

1490

1491

1492

1493

1496 {

1498 }

1499 else

1500 {

1501

1502

1503

1504

1505

1510 block = span->start;

1514 {

1515 result = block + span->firstfree * size;

1518 }

1519 else

1520 {

1523 }

1525

1526

1529 }

1530

1533

1534 return result;

1535}

1536

1537

1538

1539

1540

1541

1542

1543

1544

1545

1546

1547

1548

1549

1550

1551

1552

1553

1554

1555

1556

1557

1558

1559static bool

1561 int size_class)

1562{

1566 size_t nmax;

1567 int fclass;

1568 size_t npages = 1;

1569 size_t first_page;

1570 size_t i;

1572

1574

1575

1576

1577

1578

1579

1580

1583 else

1585

1586

1587

1588

1589

1590

1592 {

1593 span_pointer = pool->spans[fclass];

1594

1596 {

1597 int tfclass;

1602

1605 next_span_pointer = span->nextspan;

1606

1607

1610

1611

1615 else

1616 nextspan = NULL;

1617

1618

1619

1620

1621

1622 if (tfclass < fclass)

1623 {

1624

1625 if (pool->spans[fclass] == span_pointer)

1626 {

1627

1630 if (nextspan != NULL)

1632 }

1633 else

1634 {

1635

1640 }

1641 if (nextspan != NULL)

1643

1644

1646 pool->spans[tfclass] = span_pointer;

1649 {

1652 nextspan->prevspan = span_pointer;

1653 }

1654 span->fclass = tfclass;

1655 }

1656

1657

1658 span_pointer = next_span_pointer;

1659 }

1660

1661

1663 return true;

1664 }

1665

1666

1667

1668

1669

1670

1671

1672

1673

1677 return true;

1680 return true;

1681

1682

1683

1684

1685

1686

1687

1688

1689

1690

1692 {

1695 return false;

1697 }

1698

1699

1702 if (segment_map == NULL)

1703 {

1705 if (segment_map == NULL)

1706 {

1708 return false;

1709 }

1710 }

1711

1712

1713

1714

1715

1718 "dsa_allocate could not find %zu free pages for superblock",

1719 npages);

1721

1722

1723 start_pointer =

1726

1727

1728

1729

1730

1732 {

1733

1734

1735

1736

1737 span_pointer = start_pointer;

1738 }

1739

1740

1741 init_span(area, span_pointer, pool, start_pointer, npages, size_class);

1742 for (i = 0; i < npages; ++i)

1743 segment_map->pagemap[first_page + i] = span_pointer;

1744

1745 return true;

1746}

1747

1748

1749

1750

1751

1752

1753

1754

1755

1758{

1760 {

1765

1766

1767

1768

1769

1770

1771

1772

1773

1774

1775

1777

1778

1781 "dsa_area could not attach to a segment that has been freed");

1782

1787 if (segment == NULL)

1788 elog(ERROR, "dsa_area could not attach to segment");

1790 segment_map->segment = segment;

1792 segment_map->header =

1801

1802

1805

1808 }

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824

1826

1828}

1829

1830

1831

1832

1833

1834

1835

1836static void

1838{

1842

1843

1844

1846

1847

1848

1849

1850

1851

1854 segment_map =

1859

1861 {

1863

1864

1866 {

1867

1868

1869

1870

1881 segment_map->segment = NULL;

1882 segment_map->header = NULL;

1884 }

1885 }

1886

1887

1888 if (segment_map->header != NULL)

1890

1892

1893

1894

1895

1896

1897

1898

1899

1900

1902 dsa_free(area, span_pointer);

1903}

1904

1905static void

1907{

1909 {

1911

1913 }

1915 {

1917

1919 }

1920 else

1921 {

1923

1925 }

1926}

1927

1928static void

1931 int fclass)

1932{

1934

1936 {

1938 pool->spans[fclass]);

1939

1940 head->prevspan = span_pointer;

1941 }

1944 pool->spans[fclass] = span_pointer;

1945 span->fclass = fclass;

1946}

1947

1948

1949

1950

1951void

1953{

1954 int i;

1955

1956

1960

1961

1962

1963

1964

1965

1966

1967

1968

1969

1970

1972}

1973

1974

1975

1976

1977static void

1979{

1981 {

1983

1986 }

1987 else

1988 {

1993 }

1995 {

1997

2000 }

2001}

2002

2003

2004

2005

2006

2007

2008

2011{

2012 size_t bin;

2013

2016

2017

2018

2019

2020

2023 ++bin)

2024 {

2025

2026

2027

2028

2029 size_t threshold = (size_t) 1 << (bin - 1);

2031

2032

2035 {

2038 size_t contiguous_pages;

2039

2041 next_segment_index = segment_map->header->next;

2043

2044

2045 if (contiguous_pages >= threshold && contiguous_pages < npages)

2046 {

2047 segment_index = next_segment_index;

2048 continue;

2049 }

2050

2051

2052 if (contiguous_pages < threshold)

2053 {

2055

2056

2057

2058

2059

2060 }

2061

2062

2063 if (contiguous_pages >= npages)

2064 return segment_map;

2065

2066

2067 segment_index = next_segment_index;

2068 }

2069 }

2070

2071

2072 return NULL;

2073}

2074

2075

2076

2077

2078

2079

2082{

2084 size_t metadata_bytes;

2086 size_t total_pages;

2087 size_t usable_pages;

2091

2093

2094

2095 for (new_index = 1; new_index < DSA_MAX_SEGMENTS; ++new_index)

2096 {

2098 break;

2099 }

2101 return NULL;

2102

2103

2104

2105

2106

2109 return NULL;

2110

2111

2112

2113

2114

2115

2116

2117

2118

2119

2120

2121

2122

2123

2124

2131

2133 metadata_bytes =

2137

2138

2142 return NULL;

2145

2146

2147 if (requested_pages > usable_pages)

2148 {

2149

2150

2151

2152

2153 usable_pages = requested_pages;

2154 metadata_bytes =

2158

2159

2163

2164

2166 return NULL;

2167

2168

2171 return NULL;

2172 }

2173

2174

2179 if (segment == NULL)

2180 return NULL;

2182

2183

2186

2189

2192

2196

2197

2198 segment_map = &area->segment_maps[new_index];

2199 segment_map->segment = segment;

2209

2210

2213 usable_pages);

2214

2215

2227 {

2230

2232 next->header->prev = new_index;

2233 }

2234

2235 return segment_map;

2236}

2237

2238

2239

2240

2241

2242

2243

2244

2245

2246

2247

2248

2249

2250

2251static void

2253{

2254 size_t freed_segment_counter;

2255

2256

2257

2258

2259

2260

2261

2262

2263

2264

2265

2266

2267

2268

2272 {

2273

2277 }

2278}

2279

2280

2281

2282

2283

2284

2285

2286

2287static void

2289{

2290 size_t freed_segment_counter;

2291 int i;

2292

2296 {

2298 {

2301 {

2306 }

2307 }

2309 }

2310}

2311

2312

2313

2314

2315static void

2317{

2318 size_t new_bin;

2320

2322 if (segment_map->header->bin == new_bin)

2323 return;

2324

2325

2327

2328

2332 segment_map->header->bin = new_bin;

2335 {

2337

2339 Assert(next->header->bin == new_bin);

2340 next->header->prev = segment_index;

2341 }

2342}

#define pg_read_barrier()

#define fprintf(file, fmt, msg)

static void unlink_segment(dsa_area *area, dsa_segment_map *segment_map)

static void check_for_freed_segments(dsa_area *area)

static const uint16 dsa_size_classes[]

#define DSA_EXTRACT_SEGMENT_NUMBER(dp)

#define DSA_AREA_LOCK(area)

#define DSA_NUM_SEGMENTS_AT_EACH_SIZE

static void add_span_to_fullness_class(dsa_area *area, dsa_area_span *span, dsa_pointer span_pointer, int fclass)

static bool ensure_active_superblock(dsa_area *area, dsa_area_pool *pool, int size_class)

#define DSA_SEGMENT_INDEX_NONE

static dsa_area * create_internal(void *place, size_t size, int tranche_id, dsm_handle control_handle, dsm_segment *control_segment, size_t init_segment_size, size_t max_segment_size)

dsa_area * dsa_attach(dsa_handle handle)

#define DSA_SEGMENT_HEADER_MAGIC

void dsa_trim(dsa_area *area)

#define DSA_SPAN_NOTHING_FREE

#define DSA_MAKE_POINTER(segment_number, offset)

dsa_area * dsa_create_in_place_ext(void *place, size_t size, int tranche_id, dsm_segment *segment, size_t init_segment_size, size_t max_segment_size)

#define get_segment_index(area, segment_map_ptr)

dsa_area * dsa_attach_in_place(void *place, dsm_segment *segment)

void * dsa_get_address(dsa_area *area, dsa_pointer dp)

void dsa_on_shmem_exit_release_in_place(int code, Datum place)

void dsa_on_dsm_detach_release_in_place(dsm_segment *segment, Datum place)

static dsa_pointer alloc_object(dsa_area *area, int size_class)

#define DSA_PAGES_PER_SUPERBLOCK

#define DSA_SIZE_CLASS_MAP_QUANTUM

static size_t contiguous_pages_to_segment_bin(size_t n)

static const uint8 dsa_size_class_map[]

dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags)

static dsa_segment_map * make_new_segment(dsa_area *area, size_t requested_pages)

size_t dsa_get_total_size(dsa_area *area)

#define DSA_SUPERBLOCK_SIZE

#define DsaAreaPoolToDsaPointer(area, p)

static void check_for_freed_segments_locked(dsa_area *area)

#define DSA_EXTRACT_OFFSET(dp)

dsa_area * dsa_create_ext(int tranche_id, size_t init_segment_size, size_t max_segment_size)

static void destroy_superblock(dsa_area *area, dsa_pointer span_pointer)

static void rebin_segment(dsa_area *area, dsa_segment_map *segment_map)

#define DSA_SCLASS_LOCK(area, sclass)

void dsa_release_in_place(void *place)

static dsa_segment_map * get_segment_by_index(dsa_area *area, dsa_segment_index index)

void dsa_set_size_limit(dsa_area *area, size_t limit)

#define DSA_SCLASS_BLOCK_OF_SPANS

static bool transfer_first_span(dsa_area *area, dsa_area_pool *pool, int fromclass, int toclass)

static void unlink_span(dsa_area *area, dsa_area_span *span)

#define DSA_SCLASS_SPAN_LARGE

#define DSA_NUM_SIZE_CLASSES

void dsa_unpin(dsa_area *area)

void dsa_pin_mapping(dsa_area *area)

static dsa_area * attach_internal(void *place, dsm_segment *segment, dsa_handle handle)

#define NextFreeObjectIndex(object)

void dsa_dump(dsa_area *area)

dsa_handle dsa_get_handle(dsa_area *area)

static void init_span(dsa_area *area, dsa_pointer span_pointer, dsa_area_pool *pool, dsa_pointer start, size_t npages, uint16 size_class)

void dsa_detach(dsa_area *area)

static dsa_segment_map * get_best_segment(dsa_area *area, size_t npages)

#define DSA_FULLNESS_CLASSES

void dsa_free(dsa_area *area, dsa_pointer dp)

#define DSA_NUM_SEGMENT_BINS

size_t dsa_minimum_size(void)

void dsa_pin(dsa_area *area)

#define DSA_POINTER_FORMAT

#define DSA_MIN_SEGMENT_SIZE

#define InvalidDsaPointer

#define DSA_HANDLE_INVALID

#define DsaPointerIsValid(x)

#define DSA_MAX_SEGMENT_SIZE

dsm_handle dsm_segment_handle(dsm_segment *seg)

void dsm_detach(dsm_segment *seg)

void on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)

void dsm_pin_mapping(dsm_segment *seg)

void dsm_unpin_segment(dsm_handle handle)

void dsm_pin_segment(dsm_segment *seg)

void * dsm_segment_address(dsm_segment *seg)

dsm_segment * dsm_create(Size size, int flags)

dsm_segment * dsm_attach(dsm_handle h)

#define DSM_HANDLE_INVALID

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

bool FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page)

void FreePageManagerPut(FreePageManager *fpm, Size first_page, Size npages)

void FreePageManagerInitialize(FreePageManager *fpm, char *base)

#define fpm_size_to_pages(sz)

Assert(PointerIsAligned(start, uint64))

bool LWLockHeldByMe(LWLock *lock)

bool LWLockAcquire(LWLock *lock, LWLockMode mode)

void LWLockRelease(LWLock *lock)

void LWLockInitialize(LWLock *lock, int tranche_id)

void pfree(void *pointer)

#define AllocHugeSizeIsValid(size)

#define AllocSizeIsValid(size)

#define pg_leftmost_one_pos_size_t

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

ResourceOwner CurrentResourceOwner

dsa_segment_header segment_header

size_t total_segment_size

dsa_segment_index high_segment_index

size_t max_total_segment_size

dsa_segment_index segment_bins[DSA_NUM_SEGMENT_BINS]

dsa_area_pool pools[DSA_NUM_SIZE_CLASSES]

size_t freed_segment_counter

dsm_handle segment_handles[DSA_MAX_SEGMENTS]

dsa_pointer spans[DSA_FULLNESS_CLASSES]

dsa_segment_map segment_maps[DSA_MAX_SEGMENTS]

dsa_segment_index high_segment_index

size_t freed_segment_counter

dsa_area_control * control

dsa_segment_header * header