2
* ADIOS is freely available under the terms of the BSD license described
3
* in the COPYING file in the top level directory of this source distribution.
5
* Copyright (c) 2008 - 2009. UT-BATTELLE, LLC. All rights reserved.
11
#include <unistd.h> /* _SC_PAGE_SIZE, _SC_AVPHYS_PAGES */
13
#if defined(__APPLE__)
14
# include <mach/mach.h>
17
#include "core/buffer.h"
18
#include "core/adios_logger.h"
19
#include "public/adios_error.h"
21
// buffer sizing may be problematic. To get a more accurate picture, check:
22
// http://chandrashekar.info/vault/linux-system-programs.html
23
static uint64_t adios_buffer_size_requested = 0;
24
static uint64_t adios_buffer_size_max = 0;
25
static uint64_t adios_buffer_size_remaining = 0;
26
static int adios_buffer_alloc_percentage = 0; // 1 = yes, 0 = no
27
static enum ADIOS_BUFFER_ALLOC_WHEN adios_buffer_alloc_when = ADIOS_BUFFER_ALLOC_UNKNOWN;
29
void adios_buffer_size_requested_set (uint64_t v) { adios_buffer_size_requested = v; }
30
uint64_t adios_buffer_size_requested_get (void) { return adios_buffer_size_requested; }
31
void adios_buffer_size_max_set (uint64_t v) { adios_buffer_size_max = v; }
32
void adios_buffer_size_remaining_set (uint64_t v) { adios_buffer_size_remaining = v; }
33
void adios_buffer_alloc_percentage_set (int v) { adios_buffer_alloc_percentage = v; }
34
void adios_buffer_alloc_when_set (enum ADIOS_BUFFER_ALLOC_WHEN v) { adios_buffer_alloc_when = v; }
35
enum ADIOS_BUFFER_ALLOC_WHEN adios_buffer_alloc_when_get (void) { return adios_buffer_alloc_when; }
37
#if defined (__APPLE__)
38
// See e.g. http://www.opensource.apple.com/source/system_cmds/system_cmds-496/vm_stat.tproj/vm_stat.c
39
// for the code for the vm_stat command.
40
// http://www.opensource.apple.com/source/xnu/xnu-792.6.61/osfmk/man/host_statistics.html?txt
41
// describes the host_statistics function
42
// Added by Dorian Krause <dorian.krause@usi.ch>
43
static inline size_t adios_get_avphys_pages ()
45
// Since we are only interested in the number of free pages
46
// it is fine to work with the "older" host_statistics()
47
// instead of host_statistics64(). The advantage is that the
48
// first function is also provided on older (e.g., Mac OS X 10.5)
50
vm_statistics_data_t host_info;
51
mach_msg_type_number_t host_info_outCnt;
53
// See mach/host_info.h
54
host_info_outCnt = HOST_VM_INFO_COUNT;
55
if (host_statistics(mach_host_self(),
57
(host_info_t)&host_info,
58
&host_info_outCnt) != KERN_SUCCESS ) {
59
log_error("adios_get_avphys_pages (): host_statistics failed.\n");
60
return 0; // Best we can do
63
// on Mac OSX 10.4 (Tiger), there is no speculative page counting
64
// VM_PAGE_QUERY_PAGE_SPECULATIVE is defined in 10.5's mach/vm_statistics.h (included in mach.h)
65
# if defined (VM_PAGE_QUERY_PAGE_SPECULATIVE)
66
return host_info.free_count - host_info.speculative_count;
68
return host_info.free_count;
72
// See e.g. http://chandrashekar.info/vault/linux-system-programs.html
73
static inline size_t adios_get_avphys_pages ()
75
return sysconf (_SC_AVPHYS_PAGES);
79
int adios_set_buffer_size ()
81
if (!adios_buffer_size_max) // not called before
86
pagesize = sysconf (_SC_PAGE_SIZE);
87
pages = adios_get_avphys_pages ();
89
if (adios_buffer_alloc_percentage)
91
adios_buffer_size_max = (pages * pagesize / 100.0)
92
* adios_buffer_size_requested;
96
if (pagesize * pages >= adios_buffer_size_requested)
98
// sufficient memory, do nothing
99
adios_buffer_size_max = adios_buffer_size_requested;
103
adios_error (err_no_memory,
104
"adios_allocate_buffer (): insufficient memory: "
105
"%llu requested, %llu available. Using "
107
adios_buffer_size_requested,
108
(uint64_t)(((uint64_t) pagesize) * pages));
109
adios_buffer_size_max = (uint64_t)((uint64_t) pagesize) * pages;
113
adios_buffer_size_remaining = adios_buffer_size_max;
119
log_error ("adios_allocate_buffer already called. No changes made.\n");
124
uint64_t adios_method_buffer_alloc (uint64_t size)
126
if (adios_buffer_size_remaining >= size)
128
adios_buffer_size_remaining -= size;
134
uint64_t remaining = adios_buffer_size_remaining;
136
adios_buffer_size_remaining = 0;
142
int adios_method_buffer_free (uint64_t size)
144
if (size + adios_buffer_size_remaining > adios_buffer_size_max)
146
adios_error (err_invalid_buffer,
147
"ERROR: attempt to return more bytes to buffer "
148
"pool than were originally available\n");
150
adios_buffer_size_remaining = adios_buffer_size_max;
156
adios_buffer_size_remaining += size;