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

« back to all changes in this revision

Viewing changes to libnuma.c

  • Committer: Package Import Robot
  • Author(s): Ian Wienand
  • Date: 2012-11-15 12:20:29 UTC
  • mfrom: (1.3.9)
  • Revision ID: package-import@ubuntu.com-20121115122029-df53pmew2v1ydcsg
Tags: 2.0.8-1
New upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
/* these are now the default bitmask (pointers to) (version 2) */
48
48
struct bitmask *numa_no_nodes_ptr = NULL;
49
49
struct bitmask *numa_all_nodes_ptr = NULL;
 
50
struct bitmask *numa_possible_nodes_ptr = NULL;
50
51
struct bitmask *numa_all_cpus_ptr = NULL;
 
52
struct bitmask *numa_possible_cpus_ptr = NULL;
51
53
/* I would prefer to use symbol versioning to create v1 and v2 versions
52
54
   of numa_no_nodes and numa_all_nodes, but the loader does not correctly
53
55
   handle versioning of BSS versus small data items */
108
110
numa_fini(void)
109
111
{
110
112
        FREE_AND_ZERO(numa_all_cpus_ptr);
 
113
        FREE_AND_ZERO(numa_possible_cpus_ptr);
111
114
        FREE_AND_ZERO(numa_all_nodes_ptr);
 
115
        FREE_AND_ZERO(numa_possible_nodes_ptr);
112
116
        FREE_AND_ZERO(numa_no_nodes_ptr);
113
117
        FREE_AND_ZERO(numa_memnode_ptr);
114
118
        FREE_AND_ZERO(numa_nodes_ptr);
464
468
static void
465
469
set_task_constraints(void)
466
470
{
467
 
        int hicpu = sysconf(_SC_NPROCESSORS_CONF)-1;
 
471
        int hicpu = maxconfiguredcpu;
468
472
        int i;
469
473
        char *buffer = NULL;
470
474
        size_t buflen = 0;
471
475
        FILE *f;
472
476
 
473
477
        numa_all_cpus_ptr = numa_allocate_cpumask();
 
478
        numa_possible_cpus_ptr = numa_allocate_cpumask();
474
479
        numa_all_nodes_ptr = numa_allocate_nodemask();
 
480
        numa_possible_nodes_ptr = numa_allocate_cpumask();
475
481
        numa_no_nodes_ptr = numa_allocate_nodemask();
476
482
 
477
483
        f = fopen(mask_size_file, "r");
494
500
        fclose(f);
495
501
        free(buffer);
496
502
 
 
503
        for (i = 0; i <= hicpu; i++)
 
504
                numa_bitmask_setbit(numa_possible_cpus_ptr, i);
 
505
        for (i = 0; i <= maxconfigurednode; i++)
 
506
                numa_bitmask_setbit(numa_possible_nodes_ptr, i);
 
507
 
497
508
        /*
498
509
         * Cpus_allowed in the kernel can be defined to all f's
499
510
         * i.e. it may be a superset of the actual available processors.
557
568
static void
558
569
set_configured_cpus(void)
559
570
{
560
 
        char            *dirnamep = "/sys/devices/system/cpu";
561
 
        struct dirent   *dirent;
562
 
        DIR             *dir;
563
 
        dir = opendir(dirnamep);
564
 
 
565
 
        if (dir == NULL) {
566
 
                /* fall back to using the online cpu count */
567
 
                maxconfiguredcpu = sysconf(_SC_NPROCESSORS_CONF) - 1;
568
 
                return;
569
 
        }
570
 
        while ((dirent = readdir(dir)) != 0) {
571
 
                if (dirent->d_type == DT_DIR
572
 
                    && !strncmp("cpu", dirent->d_name, 3)) {
573
 
                        long cpu = strtol(dirent->d_name + 3, NULL, 10);
574
 
 
575
 
                        if (cpu < INT_MAX && cpu > maxconfiguredcpu)
576
 
                                maxconfiguredcpu = cpu;
577
 
                }
578
 
        }
579
 
        closedir(dir);
580
 
        if (maxconfiguredcpu < 0) {
581
 
                /* fall back to using the online cpu count */
582
 
                maxconfiguredcpu = sysconf(_SC_NPROCESSORS_CONF) - 1;
583
 
        }
 
571
        maxconfiguredcpu = sysconf(_SC_NPROCESSORS_CONF) - 1;
 
572
        if (maxconfiguredcpu == -1)
 
573
                numa_error("sysconf(NPROCESSORS_CONF) failed.\n");
584
574
}
585
575
 
586
576
/*
1330
1320
int
1331
1321
numa_node_to_cpus_v2(int node, struct bitmask *buffer)
1332
1322
{
1333
 
        int err = 0, bufferlen;
 
1323
        int err = 0;
1334
1324
        int nnodes = numa_max_node();
1335
1325
        char fn[64], *line = NULL;
1336
1326
        FILE *f; 
1340
1330
        if (!node_cpu_mask_v2)
1341
1331
                init_node_cpu_mask_v2();
1342
1332
 
1343
 
        bufferlen = numa_bitmask_nbytes(buffer);
1344
1333
        if (node > nnodes) {
1345
1334
                errno = ERANGE;
1346
1335
                return -1;
1728
1717
 * Allow a relative node / processor specification within the allowed
1729
1718
 * set if "relative" is nonzero
1730
1719
 */
1731
 
static unsigned long get_nr(char *s, char **end, struct bitmask *bmp, int relative)
 
1720
static unsigned long get_nr(const char *s, char **end, struct bitmask *bmp, int relative)
1732
1721
{
1733
1722
        long i, nr;
1734
1723
 
1746
1735
}
1747
1736
 
1748
1737
/*
1749
 
 * numa_parse_nodestring() is called to create a node mask, given
 
1738
 * __numa_parse_nodestring() is called to create a node mask, given
1750
1739
 * an ascii string such as 25 or 12-15 or 1,3,5-7 or +6-10.
1751
 
 * (the + indicates that the numbers are cpuset-relative)
 
1740
 * (the + indicates that the numbers are nodeset-relative)
1752
1741
 *
1753
 
 * The nodes may be specified as absolute, or relative to the current cpuset.
1754
 
 * The list of available nodes is in a map pointed to by "numa_all_nodes_ptr",
1755
 
 * which may represent all nodes or the nodes in the current cpuset.
 
1742
 * The nodes may be specified as absolute, or relative to the current nodeset.
 
1743
 * The list of available nodes is in a map pointed to by "allowed_nodes_ptr",
 
1744
 * which may represent all nodes or the nodes in the current nodeset.
1756
1745
 *
1757
1746
 * The caller must free the returned bitmask.
1758
1747
 */
1759
 
struct bitmask *
1760
 
numa_parse_nodestring(char *s)
 
1748
static struct bitmask *
 
1749
__numa_parse_nodestring(const char *s, struct bitmask *allowed_nodes_ptr)
1761
1750
{
1762
1751
        int invert = 0, relative = 0;
1763
1752
        int conf_nodes = numa_num_configured_nodes();
1784
1773
                if (isalpha(*s)) {
1785
1774
                        int n;
1786
1775
                        if (!strcmp(s,"all")) {
1787
 
                                copy_bitmask_to_bitmask(numa_all_nodes_ptr,
 
1776
                                copy_bitmask_to_bitmask(allowed_nodes_ptr,
1788
1777
                                                        mask);
1789
1778
                                s+=4;
1790
1779
                                break;
1797
1786
                                break;
1798
1787
                        }
1799
1788
                }
1800
 
                arg = get_nr(s, &end, numa_all_nodes_ptr, relative);
 
1789
                arg = get_nr(s, &end, allowed_nodes_ptr, relative);
1801
1790
                if (end == s) {
1802
1791
                        numa_warn(W_nodeparse, "unparseable node description `%s'\n", s);
1803
1792
                        goto err;
1804
1793
                }
1805
 
                if (!numa_bitmask_isbitset(numa_all_nodes_ptr, arg)) {
 
1794
                if (!numa_bitmask_isbitset(allowed_nodes_ptr, arg)) {
1806
1795
                        numa_warn(W_nodeparse, "node argument %d is out of range\n", arg);
1807
1796
                        goto err;
1808
1797
                }
1812
1801
                if (*s == '-') {
1813
1802
                        char *end2;
1814
1803
                        unsigned long arg2;
1815
 
                        arg2 = get_nr(++s, &end2, numa_all_nodes_ptr, relative);
 
1804
                        arg2 = get_nr(++s, &end2, allowed_nodes_ptr, relative);
1816
1805
                        if (end2 == s) {
1817
1806
                                numa_warn(W_nodeparse, "missing node argument %s\n", s);
1818
1807
                                goto err;
1819
1808
                        }
1820
 
                        if (!numa_bitmask_isbitset(numa_all_nodes_ptr, arg2)) {
 
1809
                        if (!numa_bitmask_isbitset(allowed_nodes_ptr, arg2)) {
1821
1810
                                numa_warn(W_nodeparse, "node argument %d out of range\n", arg2);
1822
1811
                                goto err;
1823
1812
                        }
1824
1813
                        while (arg <= arg2) {
1825
1814
                                i = arg;
1826
 
                                if (numa_bitmask_isbitset(numa_all_nodes_ptr,i))
 
1815
                                if (numa_bitmask_isbitset(allowed_nodes_ptr,i))
1827
1816
                                        numa_bitmask_setbit(mask, i);
1828
1817
                                arg++;
1829
1818
                        }
1849
1838
}
1850
1839
 
1851
1840
/*
1852
 
 * numa_parse_cpustring() is called to create a bitmask, given
 
1841
 * numa_parse_nodestring() is called to create a bitmask from nodes available
 
1842
 * for this task.
 
1843
 */
 
1844
 
 
1845
struct bitmask * numa_parse_nodestring(const char *s)
 
1846
{
 
1847
        return __numa_parse_nodestring(s, numa_all_nodes_ptr);
 
1848
}
 
1849
 
 
1850
/*
 
1851
 * numa_parse_nodestring_all() is called to create a bitmask from all nodes
 
1852
 * available.
 
1853
 */
 
1854
 
 
1855
struct bitmask * numa_parse_nodestring_all(const char *s)
 
1856
{
 
1857
        return __numa_parse_nodestring(s, numa_possible_nodes_ptr);
 
1858
}
 
1859
 
 
1860
/*
 
1861
 * __numa_parse_cpustring() is called to create a bitmask, given
1853
1862
 * an ascii string such as 25 or 12-15 or 1,3,5-7 or +6-10.
1854
1863
 * (the + indicates that the numbers are cpuset-relative)
1855
1864
 *
1856
1865
 * The cpus may be specified as absolute, or relative to the current cpuset.
1857
1866
 * The list of available cpus for this task is in the map pointed to by
1858
 
 * "numa_all_cpus_ptr", which may represent all cpus or the cpus in the
 
1867
 * "allowed_cpus_ptr", which may represent all cpus or the cpus in the
1859
1868
 * current cpuset.
1860
1869
 *
1861
1870
 * The caller must free the returned bitmask.
1862
1871
 */
1863
 
struct bitmask *
1864
 
numa_parse_cpustring(char *s)
 
1872
static struct bitmask *
 
1873
__numa_parse_cpustring(const char *s, struct bitmask *allowed_cpus_ptr)
1865
1874
{
1866
1875
        int invert = 0, relative=0;
1867
1876
        int conf_cpus = numa_num_configured_cpus();
1885
1894
                int i;
1886
1895
 
1887
1896
                if (!strcmp(s,"all")) {
1888
 
                        copy_bitmask_to_bitmask(numa_all_cpus_ptr, mask);
 
1897
                        copy_bitmask_to_bitmask(allowed_cpus_ptr, mask);
1889
1898
                        s+=4;
1890
1899
                        break;
1891
1900
                }
1892
 
                arg = get_nr(s, &end, numa_all_cpus_ptr, relative);
 
1901
                arg = get_nr(s, &end, allowed_cpus_ptr, relative);
1893
1902
                if (end == s) {
1894
1903
                        numa_warn(W_cpuparse, "unparseable cpu description `%s'\n", s);
1895
1904
                        goto err;
1896
1905
                }
1897
 
                if (!numa_bitmask_isbitset(numa_all_cpus_ptr, arg)) {
 
1906
                if (!numa_bitmask_isbitset(allowed_cpus_ptr, arg)) {
1898
1907
                        numa_warn(W_cpuparse, "cpu argument %s is out of range\n", s);
1899
1908
                        goto err;
1900
1909
                }
1905
1914
                        char *end2;
1906
1915
                        unsigned long arg2;
1907
1916
                        int i;
1908
 
                        arg2 = get_nr(++s, &end2, numa_all_cpus_ptr, relative);
 
1917
                        arg2 = get_nr(++s, &end2, allowed_cpus_ptr, relative);
1909
1918
                        if (end2 == s) {
1910
1919
                                numa_warn(W_cpuparse, "missing cpu argument %s\n", s);
1911
1920
                                goto err;
1912
1921
                        }
1913
 
                        if (!numa_bitmask_isbitset(numa_all_cpus_ptr, arg2)) {
 
1922
                        if (!numa_bitmask_isbitset(allowed_cpus_ptr, arg2)) {
1914
1923
                                numa_warn(W_cpuparse, "cpu argument %s out of range\n", s);
1915
1924
                                goto err;
1916
1925
                        }
1917
1926
                        while (arg <= arg2) {
1918
1927
                                i = arg;
1919
 
                                if (numa_bitmask_isbitset(numa_all_cpus_ptr, i))
 
1928
                                if (numa_bitmask_isbitset(allowed_cpus_ptr, i))
1920
1929
                                        numa_bitmask_setbit(mask, i);
1921
1930
                                arg++;
1922
1931
                        }
1940
1949
        numa_bitmask_free(mask);
1941
1950
        return NULL;
1942
1951
}
 
1952
 
 
1953
/*
 
1954
 * numa_parse_cpustring() is called to create a bitmask from cpus available
 
1955
 * for this task.
 
1956
 */
 
1957
 
 
1958
struct bitmask * numa_parse_cpustring(const char *s)
 
1959
{
 
1960
        return __numa_parse_cpustring(s, numa_all_cpus_ptr);
 
1961
}
 
1962
 
 
1963
/*
 
1964
 * numa_parse_cpustring_all() is called to create a bitmask from all cpus
 
1965
 * available.
 
1966
 */
 
1967
 
 
1968
struct bitmask * numa_parse_cpustring_all(const char *s)
 
1969
{
 
1970
        return __numa_parse_cpustring(s, numa_possible_cpus_ptr);
 
1971
}