~ubuntu-branches/ubuntu/utopic/numactl/utopic

« back to all changes in this revision

Viewing changes to distance.c

  • Committer: Bazaar Package Importer
  • Author(s): Ian Wienand
  • Date: 2010-08-11 22:32:39 UTC
  • mfrom: (1.3.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100811223239-xa5wikung8pwt3p8
Tags: 2.0.5-1
* New upstream
* Update standards to 3.9.1
* Update debhelper compat to 7
* Remove libnuma1.shlibs; should be covered by -V to
  dh_makeshlibs (Closes: #570201)

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
   Lesser General Public License for more details.
13
13
 
14
14
   You should find a copy of v2.1 of the GNU Lesser General Public License
15
 
   somewhere on your Linux system; if not, write to the Free Software 
16
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 
15
   somewhere on your Linux system; if not, write to the Free Software
 
16
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
18
   All calls are undefined when numa_available returns an error. */
19
19
#define _GNU_SOURCE 1
24
24
#include "numaint.h"
25
25
 
26
26
static int distance_numnodes;
27
 
static int *distance_table; 
 
27
static int *distance_table;
28
28
 
29
29
static void parse_numbers(char *s, int *iptr, int n)
30
30
{
31
31
        int i, d, j;
32
32
        char *end;
33
 
        for (i = 0, j = 0; i < n; i++, j++) { 
 
33
        for (i = 0, j = 0; i < n; i++, j++) {
34
34
                d = strtoul(s, &end, 0);
35
35
                /* Skip unavailable nodes */
36
36
                while (j<n &&  !numa_bitmask_isbitset(numa_all_nodes_ptr, j))
38
38
                *(iptr+j) = d;
39
39
                if (s == end)
40
40
                        break;
41
 
                s = end; 
42
 
        } 
 
41
                s = end;
 
42
        }
43
43
}
44
44
 
45
 
static int read_distance_table(void) 
46
 
47
 
        int nd, len; 
 
45
static int read_distance_table(void)
 
46
{
 
47
        int nd, len;
48
48
        char *line = NULL;
49
 
        size_t linelen = 0; 
50
 
        int numnodes = 0; 
51
 
        int *table = NULL; 
 
49
        size_t linelen = 0;
 
50
        int numnodes = 0;
 
51
        int *table = NULL;
52
52
        int err = -1;
53
53
        
54
 
        for (nd = 0;; nd++) { 
55
 
                char fn[100]; 
 
54
        for (nd = 0;; nd++) {
 
55
                char fn[100];
56
56
                FILE *dfh;
57
57
                sprintf(fn, "/sys/devices/system/node/node%d/distance", nd);
58
 
                dfh = fopen(fn, "r"); 
59
 
                if (!dfh) { 
 
58
                dfh = fopen(fn, "r");
 
59
                if (!dfh) {
60
60
                        if (errno == ENOENT && nd > 0)
61
61
                                err = 0;
62
62
                        if (!err && nd<numa_num_configured_nodes())
69
69
                if (len <= 0)
70
70
                        break;
71
71
 
72
 
                if (!table) { 
 
72
                if (!table) {
73
73
                        numnodes = numa_num_configured_nodes();
74
 
                        table = calloc(numnodes * numnodes, sizeof(int)); 
 
74
                        table = calloc(numnodes * numnodes, sizeof(int));
75
75
                        if (!table) {
76
 
                                errno = ENOMEM; 
 
76
                                errno = ENOMEM;
77
77
                                break;
78
78
                        }
79
 
                } 
 
79
                }
80
80
 
81
81
                parse_numbers(line, table + nd * numnodes, numnodes);
82
82
        }
83
 
        free(line); 
84
 
        if (err)  { 
 
83
        free(line);
 
84
        if (err)  {
85
85
                numa_warn(W_distance,
86
86
                          "Cannot parse distance information in sysfs: %s",
87
87
                          strerror(errno));
88
 
                free(table); 
 
88
                free(table);
89
89
                return err;
90
90
        }
91
91
        /* Update the global table pointer.  Race window here with
92
92
           other threads, but in the worst case we leak one distance
93
93
           array one time, which is tolerable. This avoids a
94
94
           dependency on pthreads. */
95
 
        if (distance_table) { 
 
95
        if (distance_table) {
96
96
                free(table);
97
97
                return 0;
98
98
        }
99
99
        distance_numnodes = numnodes;
100
100
        distance_table = table;
101
101
        return 0;               
102
 
}  
 
102
}
103
103
 
104
 
int numa_distance(int a, int b) 
105
 
106
 
        if (!distance_table) { 
 
104
int numa_distance(int a, int b)
 
105
{
 
106
        if (!distance_table) {
107
107
                int err = read_distance_table();
108
108
                if (err < 0)
109
109
                        return 0;
110
110
        }
111
111
        return distance_table[a * distance_numnodes + b];
112
 
 
112
}