~ubuntu-branches/ubuntu/utopic/adios/utopic

« back to all changes in this revision

Viewing changes to src/core/buffer.c

  • Committer: Package Import Robot
  • Author(s): Alastair McKinstry
  • Date: 2013-12-09 15:21:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20131209152131-jtd4fpmdv3xnunnm
Tags: 1.5.0-1
* New upstream.
* Standards-Version: 3.9.5
* Include latest config.{sub,guess} 
* New watch file.
* Create libadios-bin for binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
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.
 
4
 *
 
5
 * Copyright (c) 2008 - 2009.  UT-BATTELLE, LLC. All rights reserved.
 
6
 */
 
7
 
 
8
#include <stdio.h>
 
9
#include <stdlib.h>
 
10
#include <stdint.h>
 
11
#include <unistd.h>   /* _SC_PAGE_SIZE, _SC_AVPHYS_PAGES */
 
12
 
 
13
#if defined(__APPLE__)
 
14
#       include <mach/mach.h>
 
15
#endif
 
16
 
 
17
#include "core/buffer.h"
 
18
#include "core/adios_logger.h"
 
19
#include "public/adios_error.h"
 
20
 
 
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;
 
28
 
 
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; }
 
36
 
 
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 ()
 
44
{
 
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)
 
49
    // systems
 
50
    vm_statistics_data_t   host_info;
 
51
    mach_msg_type_number_t host_info_outCnt;
 
52
 
 
53
    // See mach/host_info.h
 
54
    host_info_outCnt = HOST_VM_INFO_COUNT;
 
55
    if (host_statistics(mach_host_self(),
 
56
                        HOST_VM_INFO,
 
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
 
61
    }
 
62
 
 
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;
 
67
#   else
 
68
    return host_info.free_count;
 
69
#   endif
 
70
}
 
71
#else
 
72
// See e.g. http://chandrashekar.info/vault/linux-system-programs.html
 
73
static inline size_t adios_get_avphys_pages ()
 
74
{
 
75
    return sysconf (_SC_AVPHYS_PAGES);
 
76
}
 
77
#endif
 
78
 
 
79
int adios_set_buffer_size ()
 
80
{
 
81
    if (!adios_buffer_size_max) // not called before
 
82
    {
 
83
        long pagesize;
 
84
        long pages;
 
85
 
 
86
        pagesize = sysconf (_SC_PAGE_SIZE);
 
87
        pages =  adios_get_avphys_pages ();
 
88
        
 
89
        if (adios_buffer_alloc_percentage)
 
90
        {
 
91
            adios_buffer_size_max =   (pages * pagesize / 100.0)
 
92
                                    * adios_buffer_size_requested;
 
93
        }
 
94
        else
 
95
        {
 
96
            if (pagesize * pages >= adios_buffer_size_requested)
 
97
            {
 
98
                // sufficient memory, do nothing
 
99
                adios_buffer_size_max = adios_buffer_size_requested;
 
100
            }
 
101
            else
 
102
            {
 
103
                adios_error (err_no_memory,
 
104
                             "adios_allocate_buffer (): insufficient memory: "
 
105
                             "%llu requested, %llu available.  Using "
 
106
                             "available.\n",
 
107
                             adios_buffer_size_requested,
 
108
                             (uint64_t)(((uint64_t) pagesize) * pages));
 
109
                adios_buffer_size_max = (uint64_t)((uint64_t) pagesize) * pages;
 
110
           }
 
111
        }
 
112
 
 
113
        adios_buffer_size_remaining = adios_buffer_size_max;
 
114
 
 
115
        return 1;
 
116
    }
 
117
    else
 
118
    {
 
119
        log_error ("adios_allocate_buffer already called. No changes made.\n");
 
120
        return 0;
 
121
    }
 
122
}
 
123
 
 
124
uint64_t adios_method_buffer_alloc (uint64_t size)
 
125
{
 
126
    if (adios_buffer_size_remaining >= size)
 
127
    {
 
128
        adios_buffer_size_remaining -= size;
 
129
 
 
130
        return size;
 
131
    }
 
132
    else
 
133
    {
 
134
        uint64_t remaining = adios_buffer_size_remaining;
 
135
 
 
136
        adios_buffer_size_remaining = 0;
 
137
 
 
138
        return remaining;
 
139
    }
 
140
}
 
141
 
 
142
int adios_method_buffer_free (uint64_t size)
 
143
{
 
144
    if (size + adios_buffer_size_remaining > adios_buffer_size_max)
 
145
    {
 
146
        adios_error (err_invalid_buffer, 
 
147
                     "ERROR: attempt to return more bytes to buffer "
 
148
                     "pool than were originally available\n");
 
149
 
 
150
        adios_buffer_size_remaining = adios_buffer_size_max;
 
151
 
 
152
        return 0;
 
153
    }
 
154
    else
 
155
    {
 
156
        adios_buffer_size_remaining += size;
 
157
 
 
158
        return 1;
 
159
    }
 
160
}
 
161