* Find the nth "close" core to the specified core * "close" is defined as the deepest level that shares * at least an L2 cache. With threads, this will be * threads on the same core. If the shared cache is L3 * or higher, simply returns the same core. */
| 5977 | * or higher, simply returns the same core. |
| 5978 | */ |
| 5979 | static int |
| 5980 | find_close_core(int cpu, int core_offset) |
| 5981 | { |
| 5982 | struct cpu_group *grp; |
| 5983 | int i; |
| 5984 | int fcpu; |
| 5985 | cpuset_t cs; |
| 5986 | |
| 5987 | grp = cpu_top; |
| 5988 | if (grp == NULL) |
| 5989 | return cpu; |
| 5990 | i = 0; |
| 5991 | while ((i = find_child_with_core(cpu, grp)) != -1) { |
| 5992 | /* If the child only has one cpu, don't descend */ |
| 5993 | if (grp->cg_child[i].cg_count <= 1) |
| 5994 | break; |
| 5995 | grp = &grp->cg_child[i]; |
| 5996 | } |
| 5997 | |
| 5998 | /* If they don't share at least an L2 cache, use the same CPU */ |
| 5999 | if (grp->cg_level > CG_SHARE_L2 || grp->cg_level == CG_SHARE_NONE) |
| 6000 | return cpu; |
| 6001 | |
| 6002 | /* Now pick one */ |
| 6003 | CPU_COPY(&grp->cg_mask, &cs); |
| 6004 | |
| 6005 | /* Add the selected CPU offset to core offset. */ |
| 6006 | for (i = 0; (fcpu = CPU_FFS(&cs)) != 0; i++) { |
| 6007 | if (fcpu - 1 == cpu) |
| 6008 | break; |
| 6009 | CPU_CLR(fcpu - 1, &cs); |
| 6010 | } |
| 6011 | MPASS(fcpu); |
| 6012 | |
| 6013 | core_offset += i; |
| 6014 | |
| 6015 | CPU_COPY(&grp->cg_mask, &cs); |
| 6016 | for (i = core_offset % grp->cg_count; i > 0; i--) { |
| 6017 | MPASS(CPU_FFS(&cs)); |
| 6018 | CPU_CLR(CPU_FFS(&cs) - 1, &cs); |
| 6019 | } |
| 6020 | MPASS(CPU_FFS(&cs)); |
| 6021 | return CPU_FFS(&cs) - 1; |
| 6022 | } |
| 6023 | #else |
| 6024 | static int |
| 6025 | find_close_core(int cpu, int core_offset __unused) |
no test coverage detected