这是一个Linux kernel的进程CPU绑定补丁,其官方发布版本没有较新的2.4内核对应版本,下面的代码是从patch文件中摘出,经过测试和简单的分析在kernel2.4.26下可以放心的使用。
/* Tested by Grip2 in kernel-2.4.26
/**
* sys_sched_setaffinity - set the cpu affinity of a process
* @pid: pid of the process
* @len: length in bytes of the bitmask pointed to by user_mask_ptr
* @user_mask_ptr: user-space pointer to the new cpu mask
*/
asmlinkage int sys_sched_setaffinity(pid_t pid, unsigned int len,
unsigned long *user_mask_ptr)
{
unsigned long new_mask;
struct task_struct *p;
int retval, reschedule = 0;
if (len < sizeof(new_mask))
return -EINVAL;
if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
return -EFAULT;
new_mask &= cpu_online_map;
if (!new_mask)
return -EINVAL;
read_lock_irq(&tasklist_lock);
spin_lock(&runqueue_lock);
retval = -ESRCH;
p = find_process_by_pid(pid);
if (!p)
goto out_unlock;
retval = -EPERM;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
!capable(CAP_SYS_NICE))
goto out_unlock;
p->cpus_allowed = new_mask;
#ifdef CONFIG_SMP
if (!(p->cpus_runnable & p->cpus_allowed)) {
if (p == current)
reschedule = 1;
else {
p->need_resched = 1;
smp_send_reschedule(p->processor);
}
}
#endif
retval = 0;
out_unlock:
spin_unlock(&runqueue_lock);
read_unlock_irq(&tasklist_lock);
if (reschedule)
schedule();
return retval;
}
/**
* sys_sched_getaffinity - get the cpu affinity of a process
* @pid: pid of the process
* @len: length in bytes of the bitmask pointed to by user_mask_ptr
* @user_mask_ptr: user-space pointer to hold the current mask
*/
asmlinkage int sys_sched_getaffinity(pid_t pid, unsigned int len,
unsigned long *user_mask_ptr)
{
unsigned long mask;
unsigned int real_len;
struct task_struct *p;
int retval;
real_len = sizeof(mask);
if (len < real_len)
return -EINVAL;
read_lock_irq(&tasklist_lock);
spin_lock(&runqueue_lock);
retval = -ESRCH;
p = find_process_by_pid(pid);
if (!p)
goto out_unlock;
retval = 0;
mask = p->cpus_allowed & cpu_online_map;
out_unlock:
spin_unlock(&runqueue_lock);
read_unlock_irq(&tasklist_lock);
if (retval)
return retval;
if (copy_to_user(user_mask_ptr, &mask, real_len))
return -EFAULT;
return real_len;
}
没有评论:
发表评论