6f0621c708c612fd5e1c56f65318e90abcfc0cc1
[platform/upstream/intel-gpu-tools.git] / lib / intel_os.c
1 /*
2  * Copyright © 2008 Intel Corporation
3  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Eric Anholt <eric@anholt.net>
26  *
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <errno.h>
38 #include <err.h>
39 #include <assert.h>
40 #include <sys/ioctl.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #include <sys/mman.h>
44 #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM
45 #include <sys/sysinfo.h>
46 #elif defined(HAVE_SWAPCTL) /* Solaris */
47 #include <sys/swap.h>
48 #endif
49
50 #include "intel_io.h"
51 #include "drmtest.h"
52 #include "igt_aux.h"
53
54 /**
55  * intel_get_total_ram_mb:
56  *
57  * Returns:
58  * The total amount of system RAM available in MB.
59  */
60 uint64_t
61 intel_get_total_ram_mb(void)
62 {
63         uint64_t retval;
64
65 #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM /* Linux */
66         struct sysinfo sysinf;
67         int ret;
68
69         ret = sysinfo(&sysinf);
70         assert(ret == 0);
71
72         retval = sysinf.totalram;
73         retval *= sysinf.mem_unit;
74 #elif defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES) /* Solaris */
75         long pagesize, npages;
76
77         pagesize = sysconf(_SC_PAGESIZE);
78         npages = sysconf(_SC_PHYS_PAGES);
79
80         retval = (uint64_t) pagesize * npages;
81 #else
82 #error "Unknown how to get RAM size for this OS"
83 #endif
84
85         return retval / (1024*1024);
86 }
87
88 /**
89  * intel_get_avail_ram_mb:
90  *
91  * Returns:
92  * The amount of unused system RAM available in MB.
93  */
94 uint64_t
95 intel_get_avail_ram_mb(void)
96 {
97         uint64_t retval;
98
99 #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM /* Linux */
100         struct sysinfo sysinf;
101         int ret;
102
103         ret = sysinfo(&sysinf);
104         assert(ret == 0);
105
106         retval = sysinf.freeram;
107         retval *= sysinf.mem_unit;
108 #elif defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES) /* Solaris */
109         long pagesize, npages;
110
111         pagesize = sysconf(_SC_PAGESIZE);
112         npages = sysconf(_SC_AVPHYS_PAGES);
113
114         retval = (uint64_t) pagesize * npages;
115 #else
116 #error "Unknown how to get available RAM for this OS"
117 #endif
118
119         return retval / (1024*1024);
120 }
121
122 /**
123  * intel_get_total_swap_mb:
124  *
125  * Returns:
126  * The total amount of swap space available in MB.
127  */
128 uint64_t
129 intel_get_total_swap_mb(void)
130 {
131         uint64_t retval;
132
133 #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM /* Linux */
134         struct sysinfo sysinf;
135         int ret;
136
137         ret = sysinfo(&sysinf);
138         assert(ret == 0);
139
140         retval = sysinf.freeswap;
141         retval *= sysinf.mem_unit;
142 #elif defined(HAVE_SWAPCTL) /* Solaris */
143         long pagesize = sysconf(_SC_PAGESIZE);
144         uint64_t totalpages = 0;
145         swaptbl_t *swt;
146         char *buf;
147         int n, i;
148
149         if ((n = swapctl(SC_GETNSWP, NULL)) == -1) {
150             perror("swapctl: GETNSWP");
151             return 0;
152         }
153         if (n == 0) {
154             /* no error, but no swap devices either */
155             return 0;
156         }
157
158         swt = malloc(sizeof(struct swaptable) + (n * sizeof(swapent_t)));
159         buf = malloc(n * MAXPATHLEN);
160         if (!swt || !buf) {
161             perror("malloc");
162         } else {
163             swt->swt_n = n;
164             for (i = 0 ; i < n; i++) {
165                 swt->swt_ent[i].ste_path = buf + (i * MAXPATHLEN);
166             }
167
168             if ((n = swapctl(SC_LIST, swt)) == -1) {
169                 perror("swapctl: LIST");
170             } else {
171                 for (i = 0; i < swt->swt_n; i++) {
172                     totalpages += swt->swt_ent[i].ste_pages;
173                 }
174             }
175         }
176         free(swt);
177         free(buf);
178
179         retval = (uint64_t) pagesize * totalpages;
180 #else
181 #warning "Unknown how to get swap size for this OS"
182         return 0;
183 #endif
184
185         return retval / (1024*1024);
186 }
187
188
189 /*
190  * When testing a port to a new platform, create a standalone test binary
191  * by running:
192  * cc -o porttest intel_drm.c -I.. -DSTANDALONE_TEST `pkg-config --cflags libdrm`
193  * and then running the resulting porttest program.
194  */
195 #ifdef STANDALONE_TEST
196 void *mmio;
197
198 int main(int argc, char **argv)
199 {
200     printf("Total RAM:  %" PRIu64 " Mb\n", intel_get_total_ram_mb());
201     printf("Total Swap: %" PRIu64 " Mb\n", intel_get_total_swap_mb());
202
203     return 0;
204 }
205 #endif /* STANDALONE_TEST */