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{
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",
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