We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
cpu cores estimate based on cgroups
I was reading the announcement for 2.4.0 and got interested in https://github.com/dask/distributed/pull/3039 by @jcrist 

That did lead me to this part of the code:
https://github.com/dask/distributed/blob/7d017c467590c758fa4b8cb2b1193205fe5aa7ad/distributed/system.py#L62

Just by looking at it (and although I'm not an expert I think I know what's going on), I have to observations -- half way between a question and a bugreport.

1. in my docker environment I have here (ubuntu 18.04), the filename is different:

```
~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us 
100000
~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us 
220000
```
in the code is that path:
```
~$ ls /sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us
ls: cannot access '/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us': No such file or directory
```

2. The actual calculation is `int(quota / period)`. I think this should round up, not down. The point is, if you have a fraction like "2.5 cores", it will report 2 cores and keep half a core unused. It would be better if it reports 3 cores and then cgroups limits to the actual 2.5.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `distributed/system.py`
Content:
```
1 import os
2 import sys
3 
4 import psutil
5 
6 __all__ = ("memory_limit", "cpu_count", "MEMORY_LIMIT", "CPU_COUNT")
7 
8 
9 def memory_limit():
10     """Get the memory limit (in bytes) for this system.
11 
12     Takes the minimum value from the following locations:
13 
14     - Total system host memory
15     - Cgroups limit (if set)
16     - RSS rlimit (if set)
17     """
18     limit = psutil.virtual_memory().total
19 
20     # Check cgroups if available
21     if sys.platform == "linux":
22         try:
23             with open("/sys/fs/cgroup/memory/memory.limit_in_bytes") as f:
24                 cgroups_limit = int(f.read())
25             if cgroups_limit > 0:
26                 limit = min(limit, cgroups_limit)
27         except Exception:
28             pass
29 
30     # Check rlimit if available
31     try:
32         import resource
33 
34         hard_limit = resource.getrlimit(resource.RLIMIT_RSS)[1]
35         if hard_limit > 0:
36             limit = min(limit, hard_limit)
37     except (ImportError, OSError):
38         pass
39 
40     return limit
41 
42 
43 def cpu_count():
44     """Get the available CPU count for this system.
45 
46     Takes the minimum value from the following locations:
47 
48     - Total system cpus available on the host.
49     - CPU Affinity (if set)
50     - Cgroups limit (if set)
51     """
52     count = os.cpu_count()
53 
54     # Check CPU affinity if available
55     try:
56         affinity_count = len(psutil.Process().cpu_affinity())
57         if affinity_count > 0:
58             count = min(count, affinity_count)
59     except Exception:
60         pass
61 
62     # Check cgroups if available
63     if sys.platform == "linux":
64         try:
65             with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us") as f:
66                 quota = int(f.read())
67             with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us") as f:
68                 period = int(f.read())
69             cgroups_count = int(quota / period)
70             if cgroups_count > 0:
71                 count = min(count, cgroups_count)
72         except Exception:
73             pass
74 
75     return count
76 
77 
78 MEMORY_LIMIT = memory_limit()
79 CPU_COUNT = cpu_count()
80
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/distributed/system.py b/distributed/system.py
--- a/distributed/system.py
+++ b/distributed/system.py
@@ -1,3 +1,4 @@
+import math
 import os
 import sys
 
@@ -61,16 +62,20 @@
 
     # Check cgroups if available
     if sys.platform == "linux":
-        try:
-            with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us") as f:
-                quota = int(f.read())
-            with open("/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us") as f:
-                period = int(f.read())
-            cgroups_count = int(quota / period)
-            if cgroups_count > 0:
-                count = min(count, cgroups_count)
-        except Exception:
-            pass
+        # The directory name isn't standardized across linux distros, check both
+        for dirname in ["cpuacct,cpu", "cpu,cpuacct"]:
+            try:
+                with open("/sys/fs/cgroup/%s/cpu.cfs_quota_us" % dirname) as f:
+                    quota = int(f.read())
+                with open("/sys/fs/cgroup/%s/cpu.cfs_period_us" % dirname) as f:
+                    period = int(f.read())
+                # We round up on fractional CPUs
+                cgroups_count = math.ceil(quota / period)
+                if cgroups_count > 0:
+                    count = min(count, cgroups_count)
+                break
+            except Exception:
+                pass
 
     return count

{"golden_diff": "diff --git a/distributed/system.py b/distributed/system.py\n--- a/distributed/system.py\n+++ b/distributed/system.py\n@@ -1,3 +1,4 @@\n+import math\n import os\n import sys\n \n@@ -61,16 +62,20 @@\n \n     # Check cgroups if available\n     if sys.platform == \"linux\":\n-        try:\n-            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\") as f:\n-                quota = int(f.read())\n-            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us\") as f:\n-                period = int(f.read())\n-            cgroups_count = int(quota / period)\n-            if cgroups_count > 0:\n-                count = min(count, cgroups_count)\n-        except Exception:\n-            pass\n+        # The directory name isn't standardized across linux distros, check both\n+        for dirname in [\"cpuacct,cpu\", \"cpu,cpuacct\"]:\n+            try:\n+                with open(\"/sys/fs/cgroup/%s/cpu.cfs_quota_us\" % dirname) as f:\n+                    quota = int(f.read())\n+                with open(\"/sys/fs/cgroup/%s/cpu.cfs_period_us\" % dirname) as f:\n+                    period = int(f.read())\n+                # We round up on fractional CPUs\n+                cgroups_count = math.ceil(quota / period)\n+                if cgroups_count > 0:\n+                    count = min(count, cgroups_count)\n+                break\n+            except Exception:\n+                pass\n \n     return count\n", "issue": "cpu cores estimate based on cgroups\nI was reading the announcement for 2.4.0 and got interested in https://github.com/dask/distributed/pull/3039 by @jcrist \r\n\r\nThat did lead me to this part of the code:\r\nhttps://github.com/dask/distributed/blob/7d017c467590c758fa4b8cb2b1193205fe5aa7ad/distributed/system.py#L62\r\n\r\nJust by looking at it (and although I'm not an expert I think I know what's going on), I have to observations -- half way between a question and a bugreport.\r\n\r\n1. in my docker environment I have here (ubuntu 18.04), the filename is different:\r\n\r\n```\r\n~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us \r\n100000\r\n~$ cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us \r\n220000\r\n```\r\nin the code is that path:\r\n```\r\n~$ ls /sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\r\nls: cannot access '/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us': No such file or directory\r\n```\r\n\r\n2. The actual calculation is `int(quota / period)`. I think this should round up, not down. The point is, if you have a fraction like \"2.5 cores\", it will report 2 cores and keep half a core unused. It would be better if it reports 3 cores and then cgroups limits to the actual 2.5.\r\n\r\n\n", "before_files": [{"content": "import os\nimport sys\n\nimport psutil\n\n__all__ = (\"memory_limit\", \"cpu_count\", \"MEMORY_LIMIT\", \"CPU_COUNT\")\n\n\ndef memory_limit():\n    \"\"\"Get the memory limit (in bytes) for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system host memory\n    - Cgroups limit (if set)\n    - RSS rlimit (if set)\n    \"\"\"\n    limit = psutil.virtual_memory().total\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        try:\n            with open(\"/sys/fs/cgroup/memory/memory.limit_in_bytes\") as f:\n                cgroups_limit = int(f.read())\n            if cgroups_limit > 0:\n                limit = min(limit, cgroups_limit)\n        except Exception:\n            pass\n\n    # Check rlimit if available\n    try:\n        import resource\n\n        hard_limit = resource.getrlimit(resource.RLIMIT_RSS)[1]\n        if hard_limit > 0:\n            limit = min(limit, hard_limit)\n    except (ImportError, OSError):\n        pass\n\n    return limit\n\n\ndef cpu_count():\n    \"\"\"Get the available CPU count for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system cpus available on the host.\n    - CPU Affinity (if set)\n    - Cgroups limit (if set)\n    \"\"\"\n    count = os.cpu_count()\n\n    # Check CPU affinity if available\n    try:\n        affinity_count = len(psutil.Process().cpu_affinity())\n        if affinity_count > 0:\n            count = min(count, affinity_count)\n    except Exception:\n        pass\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        try:\n            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_quota_us\") as f:\n                quota = int(f.read())\n            with open(\"/sys/fs/cgroup/cpuacct,cpu/cpu.cfs_period_us\") as f:\n                period = int(f.read())\n            cgroups_count = int(quota / period)\n            if cgroups_count > 0:\n                count = min(count, cgroups_count)\n        except Exception:\n            pass\n\n    return count\n\n\nMEMORY_LIMIT = memory_limit()\nCPU_COUNT = cpu_count()\n", "path": "distributed/system.py"}], "after_files": [{"content": "import math\nimport os\nimport sys\n\nimport psutil\n\n__all__ = (\"memory_limit\", \"cpu_count\", \"MEMORY_LIMIT\", \"CPU_COUNT\")\n\n\ndef memory_limit():\n    \"\"\"Get the memory limit (in bytes) for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system host memory\n    - Cgroups limit (if set)\n    - RSS rlimit (if set)\n    \"\"\"\n    limit = psutil.virtual_memory().total\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        try:\n            with open(\"/sys/fs/cgroup/memory/memory.limit_in_bytes\") as f:\n                cgroups_limit = int(f.read())\n            if cgroups_limit > 0:\n                limit = min(limit, cgroups_limit)\n        except Exception:\n            pass\n\n    # Check rlimit if available\n    try:\n        import resource\n\n        hard_limit = resource.getrlimit(resource.RLIMIT_RSS)[1]\n        if hard_limit > 0:\n            limit = min(limit, hard_limit)\n    except (ImportError, OSError):\n        pass\n\n    return limit\n\n\ndef cpu_count():\n    \"\"\"Get the available CPU count for this system.\n\n    Takes the minimum value from the following locations:\n\n    - Total system cpus available on the host.\n    - CPU Affinity (if set)\n    - Cgroups limit (if set)\n    \"\"\"\n    count = os.cpu_count()\n\n    # Check CPU affinity if available\n    try:\n        affinity_count = len(psutil.Process().cpu_affinity())\n        if affinity_count > 0:\n            count = min(count, affinity_count)\n    except Exception:\n        pass\n\n    # Check cgroups if available\n    if sys.platform == \"linux\":\n        # The directory name isn't standardized across linux distros, check both\n        for dirname in [\"cpuacct,cpu\", \"cpu,cpuacct\"]:\n            try:\n                with open(\"/sys/fs/cgroup/%s/cpu.cfs_quota_us\" % dirname) as f:\n                    quota = int(f.read())\n                with open(\"/sys/fs/cgroup/%s/cpu.cfs_period_us\" % dirname) as f:\n                    period = int(f.read())\n                # We round up on fractional CPUs\n                cgroups_count = math.ceil(quota / period)\n                if cgroups_count > 0:\n                    count = min(count, cgroups_count)\n                break\n            except Exception:\n                pass\n\n    return count\n\n\nMEMORY_LIMIT = memory_limit()\nCPU_COUNT = cpu_count()\n", "path": "distributed/system.py"}]}