/* * Copyright (c) 1992, 1994 Sun Microsystems, Inc. */ #ident "@(#)processor_bind.c 1.3 94/12/23 SMI" #include #include #include #include #include #include #include #include #include #include #include #include #include /* * processor_bind(2) - Processor binding interfaces. */ int processor_bind(idtype_t idtype, id_t id, processorid_t cpun, processorid_t *obind) { struct bind_arg ba; int err = 0; cpu_t *cp; proc_t *pp; kthread_id_t tp; ba.bind = cpun; /* args for bind_thread */ ba.obind = PBIND_NONE; ba.err = 0; /* * Since we might be making a binding to a processor, hold the * cpu_lock so that the processor cannot be taken offline while * we do this. */ mutex_enter(&cpu_lock); /* * Check to be sure binding processor ID is valid. */ switch (cpun) { default: if ((cp = cpu_get(cpun)) == NULL || (cp->cpu_flags & (CPU_QUIESCED | CPU_OFFLINE))) err = EINVAL; else if ((cp->cpu_flags & CPU_READY) == 0) err = EIO; break; case PBIND_NONE: case PBIND_QUERY: break; } if (err) { mutex_exit(&cpu_lock); return (set_errno(err)); } switch (idtype) { case P_LWPID: pp = curproc; mutex_enter(&pp->p_lock); if (id == P_MYID) { err = cpu_bind_thread(curthread, &ba); } else { int found = 0; tp = pp->p_tlist; do { if (tp->t_tid == id) { err = cpu_bind_thread(tp, &ba); found = 1; break; } } while ((tp = tp->t_forw) != pp->p_tlist); if (!found) err = set_errno(ESRCH); } mutex_exit(&pp->p_lock); break; case P_PID: /* * Note. Cannot use dotoprocs here because it doesn't find * system class processes, which are legal to query. */ mutex_enter(&pidlock); if (id == P_MYID) { err = cpu_bind_process(curproc, &ba); } else if ((pp = prfind(id)) != NULL) { err = cpu_bind_process(pp, &ba); } else { err = set_errno(ESRCH); } mutex_exit(&pidlock); break; default: /* * Spec says this is invalid, even though dotoprocs could * handle other idtypes. */ err = set_errno(EINVAL); break; } mutex_exit(&cpu_lock); /* * If no search error occurred, see if any permissions errors did. */ if (err == 0 && ba.err != 0) { err = set_errno(ba.err); } if (err == 0 && obind != NULL) if (copyout((caddr_t)&ba.obind, (caddr_t)obind, sizeof (ba.obind)) == -1) err = set_errno(EFAULT); return (err); /* return success or failure */ }