<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _setup_cgroups(self, my_cpus, memlimit, memory_nodes, cgroup_values):
 """ This method creates the CGroups for the following execution. @param my_cpus: None or a list of the CPU cores to use @param memlimit: None or memory limit in bytes @param memory_nodes: None or a list of memory nodes of a NUMA system to use @param cgroup_values: dict of additional values to set @return cgroups: a map of all the necessary cgroups for the following execution. Please add the process of the following execution to all those cgroups! """

        logging.debug("Setting up cgroups for run.")

        # Setup cgroups, need a single call to create_cgroup() for all subsystems
        subsystems = [BLKIO, CPUACCT, FREEZER, MEMORY] + self._cgroup_subsystems
        if my_cpus is not None or memory_nodes is not None:
            subsystems.append(CPUSET)
        subsystems = [s for s in subsystems if s in self.cgroups]

        cgroups = self.cgroups.create_fresh_child_cgroup(*subsystems)

        logging.debug("Created cgroups %s.", cgroups)

        # First, set user-specified values such that they get overridden by our settings if necessary.
        for ((subsystem, option), value) in cgroup_values.items():
            try:
                cgroups.set_value(subsystem, option, value)
            except EnvironmentError as e:
                cgroups.remove()
                sys.exit('{} for setting cgroup option {}.{} to "{}" (error code {}).'
                         .format(e.strerror, subsystem, option, value, e.errno))
            logging.debug('Cgroup value %s.%s was set to "%s", new value is now "%s".',
                          subsystem, option, value, cgroups.get_value(subsystem, option))

        # Setup cpuset cgroup if necessary to limit the CPU cores/memory nodes to be used.
        if my_cpus is not None:
            my_cpus_str = ','.join(map(str, my_cpus))
            cgroups.set_value(CPUSET, 'cpus', my_cpus_str)
            my_cpus_str = cgroups.get_value(CPUSET, 'cpus')
            logging.debug('Using cpu cores [%s].', my_cpus_str)

        if memory_nodes is not None:
            cgroups.set_value(CPUSET, 'mems', ','.join(map(str, memory_nodes)))
            memory_nodesStr = cgroups.get_value(CPUSET, 'mems')
            logging.debug('Using memory nodes [%s].', memory_nodesStr)


        # Setup memory limit
        if memlimit is not None:
            limit = 'limit_in_bytes'
            cgroups.set_value(MEMORY, limit, memlimit)

            swap_limit = 'memsw.limit_in_bytes'
            # We need swap limit because otherwise the kernel just starts swapping
            # out our process if the limit is reached.
            # Some kernels might not have this feature,
            # which is ok if there is actually no swap.
            if not cgroups.has_value(MEMORY, swap_limit):
                if systeminfo.has_swap():
                    sys.exit('Kernel misses feature for accounting swap memory, but machine has swap. Please set swapaccount=1 on your kernel command line or disable swap with "sudo swapoff -a".')
            else:
                try:
                    cgroups.set_value(MEMORY, swap_limit, memlimit)
                except IOError as e:
                    if e.errno == errno.ENOTSUP: # kernel responds with operation unsupported if this is disabled
                        sys.exit('Memory limit specified, but kernel does not allow limiting swap memory. Please set swapaccount=1 on your kernel command line or disable swap with "sudo swapoff -a".')
                    raise e

            memlimit = cgroups.get_value(MEMORY, limit)
            logging.debug('Effective memory limit is %s bytes.', memlimit)

        if MEMORY in cgroups:
            try:
                # Note that this disables swapping completely according to
                # https://www.kernel.org/doc/Documentation/cgroups/memory.txt
                # (unlike setting the global swappiness to 0).
                # Our process might get killed because of this.
                cgroups.set_value(MEMORY, 'swappiness', '0')
            except IOError as e:
                logging.warning('Could not disable swapping for benchmarked process: %s', e)

        return cgroups