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
87
89
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)