この節では、この章で説明した API を使用するタスクのコーディング例を示します。
次のコーディング例では、addr と addr+len のアドレス範囲にあるメモリーを、その範囲に次回アクセスするスレッド付近に移動します。
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> /* * Move memory to thread */ void mem_to_thread(caddr_t addr, size_t len) { if (madvise(addr, len, MADV_ACCESS_LWP) < 0) perror("madvise"); }
このコーディング例では、meminfo() 関数を使用して、指定されたアドレスで仮想ページにバックアップする物理メモリーの lgroup を判定します。次にこの例では、現在のスレッドをそのメモリー付近に移動するために、その lgroup に強いアフィニティーを設定します。
#include <stdio.h> #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); }
次のコーディング例では、lgroup 階層を巡回し、出力します。
#include <stdio.h> #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_LWPID, 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 <stdio.h> #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_ALL); 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_cookie(lgrp, lgrp); if (latency == -1) { perror("lgrp_latency_cookie"); 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_ALL); 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)); }
このコーディング例では、指定されたスレッドのホーム lgroup にもっとも近い、空きメモリー領域を持つ lgroup を検索します。
lgrp_id_t lgrp_nearest(lgrp_cookie_t cookie) { lgrp_id_t home; longlong_t size; /* * Get home lgroup */ home = lgrp_home(); /* * See whether home lgroup has any memory available in its hierarchy */ if (lgrp_mem_size(cookie, lgrp, LGRP_MEM_SZ_FREE, LGRP_CONTENT_ALL, &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)); }