File: process_collector_mem_cgo_darwin.c

package info (click to toggle)
golang-github-prometheus-client-golang 1.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 3,192 kB
  • sloc: makefile: 68; ansic: 46; sh: 21
file content (84 lines) | stat: -rw-r--r-- 3,010 bytes parent folder | download | duplicates (2)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2024 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build darwin && !ios && cgo

#include <mach/mach_init.h>
#include <mach/task.h>
#include <mach/mach_vm.h>

// The compiler warns that mach/shared_memory_server.h is deprecated, and to use
// mach/shared_region.h instead.  But that doesn't define
// SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and
// avoid a warning message when running tests.
#define GLOBAL_SHARED_TEXT_SEGMENT      0x90000000U
#define SHARED_DATA_REGION_SIZE         0x10000000
#define SHARED_TEXT_REGION_SIZE         0x10000000


int get_memory_info(unsigned long long *rss, unsigned long long *vsize)
{
    // This is lightly adapted from how ps(1) obtains its memory info.
    // https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109

    kern_return_t               error;
    task_t                      task = MACH_PORT_NULL;
    mach_task_basic_info_data_t info;
    mach_msg_type_number_t      info_count = MACH_TASK_BASIC_INFO_COUNT;

    error = task_info(
                mach_task_self(),
                MACH_TASK_BASIC_INFO,
                (task_info_t) &info,
                &info_count );

    if( error != KERN_SUCCESS )
    {
        return error;
    }

    *rss   = info.resident_size;
    *vsize = info.virtual_size;

    {
        vm_region_basic_info_data_64_t    b_info;
        mach_vm_address_t                 address = GLOBAL_SHARED_TEXT_SEGMENT;
        mach_vm_size_t                    size;
        mach_port_t                       object_name;

        /*
         * try to determine if this task has the split libraries
         * mapped in... if so, adjust its virtual size down by
         * the 2 segments that are used for split libraries
         */
        info_count = VM_REGION_BASIC_INFO_COUNT_64;

        error = mach_vm_region(
                    mach_task_self(),
                    &address,
                    &size,
                    VM_REGION_BASIC_INFO_64,
                    (vm_region_info_t) &b_info,
                    &info_count,
                    &object_name);

        if (error == KERN_SUCCESS) {
            if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&
                *vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) {
                    *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
            }
        }
    }

    return 0;
}