/* * Set the value in the map at wordPointer to bit. */ void heapMapAtWordPut(void *wordPointer, int bit) { ulong address = (ulong)wordPointer; uchar **directory, *page; if ((address & ((1<<LOGWORDSIZE)-1))) error("misaligned word"); if (!(directory = mapPages[DIRECTORYINDEX(address)])) { if (!(directory = malloc(DIRECTORYSIZE))) { perror("heapMap malloc"); exit(1); } mapPages[DIRECTORYINDEX(address)] = directory; memset(directory,0,DIRECTORYSIZE); } if (!(page = directory[PAGEINDEX(address)])) { if (!(page = malloc(PAGESIZE))) { perror("heapMap malloc"); exit(1); } directory[PAGEINDEX(address)] = page; memset(page,0,PAGESIZE); } if (bit) page[BYTEINDEX(address)] |= 1 << BITINDEX(address); else page[BYTEINDEX(address)] &= (uchar)-1 ^ (1 << BITINDEX(address)); }
/* * Answer non-zero if the heapMap is set at wordPointer, 0 otherwise */ int heapMapAtWord(void *wordPointer) { ulong address = (ulong)wordPointer; uchar *page = mapPages[PAGEINDEX(address)]; if ((address & ((1<<LOGWORDSIZE)-1))) error("misaligned word"); return page ? page[BYTEINDEX(address)] & (1 << BITINDEX(address)) : 0; }
/* * Answer non-zero if the heapMap is set at wordPointer, 0 otherwise */ int heapMapAtWord(void *wordPointer) { ulong address = (ulong)wordPointer; uchar **directory, *page; if ((address & ((1<<LOGWORDSIZE)-1))) error("misaligned word"); if (!(directory = mapPages[DIRECTORYINDEX(address)])) return 0; page = directory[PAGEINDEX(address)]; return page ? page[BYTEINDEX(address)] & (1 << BITINDEX(address)) : 0; }
/* ARGSUSED */ long lx_sched_getaffinity(uintptr_t pid, uintptr_t len, uintptr_t maskp) { int sz; ulong_t *lmask, *zmask; int i; sz = syscall(SYS_brand, B_GET_AFFINITY_MASK, pid, len, maskp); if (sz == -1) return (-errno); /* * If the target LWP hasn't ever had an affinity mask set, the kernel * will return a mask of all 0's. If that is the case we must build a * default mask that has all valid bits turned on. */ lmask = SAFE_ALLOCA(sz); zmask = SAFE_ALLOCA(sz); if (lmask == NULL || zmask == NULL) return (-ENOMEM); bzero(zmask, sz); if (uucopy((void *)maskp, lmask, sz) != 0) return (-EFAULT); if (bcmp(lmask, zmask, sz) != 0) return (sz); for (i = 0; i < sz * 8; i++) { if (p_online(i, P_STATUS) != -1) { lmask[BITINDEX(i)] |= BITSHIFT(i); } } if (uucopy(lmask, (void *)maskp, sz) != 0) return (-EFAULT); return (sz); }
/* ARGSUSED */ long lx_sched_setaffinity(uintptr_t pid, uintptr_t len, uintptr_t maskp) { int ret; int sz; int i; int found; ulong_t *lmask; pid_t s_pid; lwpid_t s_tid; processorid_t cpuid = NULL; if ((pid_t)pid < 0) return (-EINVAL); if (lx_lpid_to_spair(pid, &s_pid, &s_tid) < 0) return (-ESRCH); /* * We only support setting affinity masks for threads in * the calling process. */ if (s_pid != getpid()) return (-EPERM); /* * First, get the minimum bitmask size from the kernel. */ sz = syscall(SYS_brand, B_GET_AFFINITY_MASK, 0, 0, 0); if (sz == -1) return (-errno); lmask = SAFE_ALLOCA(sz); if (lmask == NULL) return (-ENOMEM); if (uucopy((void *)maskp, lmask, sz) != 0) return (-EFAULT); /* * Make sure the mask contains at least one processor that is * physically on the system. Reduce the user's mask to the set of * physically present CPUs. Keep track of how many valid * bits are set in the user's mask. */ for (found = 0, i = 0; i < sz * 8; i++) { if (p_online(i, P_STATUS) == -1) { /* * This CPU doesn't exist, so clear this bit from * the user's mask. */ lmask[BITINDEX(i)] &= ~BITSHIFT(i); continue; } if ((lmask[BITINDEX(i)] & BITSHIFT(i)) == BITSHIFT(i)) { found++; cpuid = i; } } if (found == 0) { lx_debug("\tlx_sched_setaffinity: mask has no present CPUs\n"); return (-EINVAL); } /* * If only one bit is set, bind the thread to that procesor; * otherwise, clear the binding. */ if (found == 1) { lx_debug("\tlx_sched_setaffinity: binding thread %d to cpu%d\n", s_tid, cpuid); if (processor_bind(P_LWPID, s_tid, cpuid, NULL) != 0) /* * It could be that the requested processor is offline, * so we'll just abandon our good-natured attempt to * bind to it. */ lx_debug("couldn't bind LWP %d to cpu %d: %s\n", s_tid, cpuid, strerror(errno)); } else { lx_debug("\tlx_sched_setaffinity: clearing thr %d binding\n", s_tid); if (processor_bind(P_LWPID, s_tid, PBIND_NONE, NULL) != 0) { lx_debug("couldn't clear CPU binding for LWP %d: %s\n", s_tid, strerror(errno)); } } /* * Finally, ask the kernel to make a note of our current (though fairly * meaningless) affinity mask. */ ret = syscall(SYS_brand, B_SET_AFFINITY_MASK, pid, sz, lmask); return ((ret == 0) ? 0 : -errno); }