This section contains code that performs example tasks by using the APIs that are described in this chapter.
The following code sample moves the memory in the range from the address specified by addr to the address specified by addr+len to the thread specified by MADV_ACCESS_LWP.
#include <sys/mman.h> #include <sys/types.h> /* * Move memory to thread */ mem_to_thread(caddr_t addr, size_t len) { if (madvise(addr, len, MADV_ACCESS_LWP) < 0) perror("madvise"); }
This sample code uses the meminfo() function to return the lgroup of a specified memory page and raises the specified thread's affinity to that lgroup with the lgrp_affinity_set function().
#include <sys/lgrp_user.h> #include <sys/mman.h> #include <sys/types.h> /* * Move a Thread to Memory */ int thread_to_memory(caddr_t va) { uint64_t addr; ulong_t count; lgrp_id_t home; uint64_t lgrp; uint_t request; uint_t valid; addr = (uint64_t)va; count = 1; request = MEMINFO_VLGRP; if (meminfo(&addr, 1, &request, 1, &lgrp, &valid) != 0) { perror("meminfo"); return (1); } if (lgrp_affinity_set(P_LWPID, P_MYID, lgrp, LGRP_AFF_STRONG) != 0) { perror("lgrp_affinity_set"); return (2); } home = lgrp_home(P_LWPID, P_MYID); if (home == -1) { perror ("lgrp_home"); return (3); } if (home != lgrp) return (-1); return (0); }
The following sample code walks through and prints out the lgroup hierarchy.
#include <stdlib.h> #include <sys/lgrp_user.h> #include <sys/types.h> /* * Walk and print lgroup hierarchy from given lgroup * through all its descendants */ int lgrp_walk(lgrp_cookie_t cookie, lgrp_id_t lgrp, lgrp_content_t content) { lgrp_affinity_t aff; lgrp_id_t *children; processorid_t *cpuids; int i; int ncpus; int nchildren; int nparents; lgrp_id_t *parents; lgrp_mem_size_t size; /* * Print given lgroup, caller's affinity for lgroup, * and desired content specified */ printf("LGROUP #%d:\n", lgrp); aff = lgrp_affinity_get(P_MYID, P_MYID, lgrp); if (aff == -1) perror ("lgrp_affinity_get"); printf("\tAFFINITY: %d\n", aff); printf("CONTENT %d:\n", content); /* * Get CPUs */ ncpus = lgrp_cpus(cookie, lgrp, NULL, 0, content); printf("\t%d CPUS: ", ncpus); if (ncpus == -1) { perror("lgrp_cpus"); return (-1); } else if (ncpus > 0) { cpuids = malloc(ncpus * sizeof (processorid_t)); ncpus = lgrp_cpus(cookie, lgrp, cpuids, ncpus, content); if (ncpus == -1) { free(cpuids); perror("lgrp_cpus"); return (-1); } for (i = 0; i < ncpus; i++) printf("%d ", cpuids[i]); free(cpuids); } printf("\n"); /* * Get memory size */ printf("\tMEMORY: "); size = lgrp_mem_size(cookie, lgrp, LGRP_MEM_SZ_INSTALLED, content); if (size == -1) { perror("lgrp_mem_size"); return (-1); } printf("installed bytes 0x%llx, ", size); size = lgrp_mem_size(cookie, lgrp, LGRP_MEM_SZ_FREE, content); if (size == -1) { perror("lgrp_mem_size"); return (-1); } printf("free bytes 0x%llx\n", size); /* * Get parents */ nparents = lgrp_parents(cookie, lgrp, NULL, 0); printf("\t%d PARENTS: ", nparents); if (nparents == -1) { perror("lgrp_parents"); return (-1); } else if (nparents > 0) { parents = malloc(nparents * sizeof (lgrp_id_t)); nparents = lgrp_parents(cookie, lgrp, parents, nparents); if (nparents == -1) { free(parents); perror("lgrp_parents"); return (-1); } for (i = 0; i < nparents; i++) printf("%d ", parents[i]); free(parents); } printf("\n"); /* * Get children */ nchildren = lgrp_children(cookie, lgrp, NULL, 0); printf("\t%d CHILDREN: ", nchildren); if (nchildren == -1) { perror("lgrp_children"); return (-1); } else if (nchildren > 0) { children = malloc(nchildren * sizeof (lgrp_id_t)); nchildren = lgrp_children(cookie, lgrp, children, nchildren); if (nchildren == -1) { free(children); perror("lgrp_children"); return (-1); } printf("Children: "); for (i = 0; i < nchildren; i++) printf("%d ", children[i]); printf("\n"); for (i = 0; i < nchildren; i++) lgrp_walk(cookie, children[i], content); free(children); } printf("\n"); return (0); }
#include <stdlib.h> #include <sys/lgrp_user.h> #include <sys/types.h> #define INT_MAX 2147483647 /* * Find next closest lgroup outside given one with available memory */ lgrp_id_t lgrp_next_nearest(lgrp_cookie_t cookie, lgrp_id_t from) { lgrp_id_t closest; int i; int latency; int lowest; int nparents; lgrp_id_t *parents; lgrp_mem_size_t size; /* * Get number of parents */ nparents = lgrp_parents(cookie, from, NULL, 0); if (nparents == -1) { perror("lgrp_parents"); return (LGRP_NONE); } /* * No parents, so current lgroup is next nearest */ if (nparents == 0) { return (from); } /* * Get parents */ parents = malloc(nparents * sizeof (lgrp_id_t)); nparents = lgrp_parents(cookie, from, parents, nparents); if (nparents == -1) { perror("lgrp_parents"); free(parents); return (LGRP_NONE); } /* * Find closest parent (ie. the one with lowest latency) */ closest = LGRP_NONE; lowest = INT_MAX; for (i = 0; i < nparents; i++) { lgrp_id_t lgrp; /* * See whether parent has any free memory */ size = lgrp_mem_size(cookie, parents[i], LGRP_MEM_SZ_FREE, LGRP_CONTENT_HIERARCHY); if (size > 0) lgrp = parents[i]; else { if (size == -1) perror("lgrp_mem_size"); /* * Find nearest ancestor if parent doesn't * have any memory */ lgrp = lgrp_next_nearest(cookie, parents[i]); if (lgrp == LGRP_NONE) continue; } /* * Get latency within parent lgroup */ latency = lgrp_latency(lgrp, lgrp); if (latency == -1) { perror("lgrp_latency"); continue; } /* * Remember lgroup with lowest latency */ if (latency < lowest) { closest = lgrp; lowest = latency; } } free(parents); return (closest); } /* * Find lgroup with memory nearest home lgroup of current thread */ lgrp_id_t lgrp_nearest(lgrp_cookie_t cookie) { lgrp_id_t home; longlong_t size; /* * Get home lgroup */ home = lgrp_home(P_LWPID, P_MYID); /* * See whether home lgroup has any memory available in its hierarchy */ size = lgrp_mem_size(cookie, home, LGRP_MEM_SZ_FREE, LGRP_CONTENT_HIERARCHY); if (size == -1) perror("lgrp_mem_size"); /* * It does, so return the home lgroup. */ if (size > 0) return (home); /* * Otherwise, find next nearest lgroup outside of the home. */ return (lgrp_next_nearest(cookie, home)); }
This example code finds the nearest lgroup with free memory to a given thread's home lgroup.
#include <stdlib.h> #include <sys/lgrp_user.h> #include <sys/types.h> #define INT_MAX 2147483647 /* * Find next closest lgroup outside given one with available memory */ lgrp_id_t lgrp_next_nearest(lgrp_cookie_t cookie, lgrp_id_t from) { lgrp_id_t closest; int i; int latency; int lowest; int nparents; lgrp_id_t *parents; lgrp_mem_size_t size; /* * Get number of parents */ nparents = lgrp_parents(cookie, from, NULL, 0); if (nparents == -1) { perror("lgrp_parents"); return (LGRP_NONE); } /* * No parents, so current lgroup is next nearest */ if (nparents == 0) { return (from); } /* * Get parents */ parents = malloc(nparents * sizeof (lgrp_id_t)); nparents = lgrp_parents(cookie, from, parents, nparents); if (nparents == -1) { perror("lgrp_parents"); free(parents); return (LGRP_NONE); } /* * Find closest parent (ie. the one with lowest latency) */ closest = LGRP_NONE; lowest = INT_MAX; for (i = 0; i < nparents; i++) { lgrp_id_t lgrp; /* * See whether parent has any free memory */ size = lgrp_mem_size(cookie, parents[i], LGRP_MEM_SZ_FREE, LGRP_CONTENT_HIERARCHY); if (size > 0) lgrp = parents[i]; else { if (size == -1) perror("lgrp_mem_size"); /* * Find nearest ancestor if parent doesn't * have any memory */ lgrp = lgrp_next_nearest(cookie, parents[i]); if (lgrp == LGRP_NONE) continue; } /* * Get latency within parent lgroup */ latency = lgrp_latency(lgrp, lgrp); if (latency == -1) { perror("lgrp_latency"); continue; } /* * Remember lgroup with lowest latency */ if (latency < lowest) { closest = lgrp; lowest = latency; } } free(parents); return (closest); } /* * Find lgroup with memory nearest home lgroup of current thread */ lgrp_id_t lgrp_nearest(lgrp_cookie_t cookie) { lgrp_id_t home; longlong_t size; /* * Get home lgroup */ home = lgrp_home(P_LWPID, P_MYID); /* * See whether home lgroup has any memory available in its hierarchy */ size = lgrp_mem_size(cookie, home, LGRP_MEM_SZ_FREE, LGRP_CONTENT_HIERARCHY); if (size == -1) perror("lgrp_mem_size"); /* * It does, so return the home lgroup. */ if (size > 0) return (home); /* * Otherwise, find next nearest lgroup outside of the home. */ return (lgrp_next_nearest(cookie, home)); }