编程接口指南

API 用法示例

本节包含使用本章介绍的 API 的示例任务的代码。


示例 4–7 将内存移动到线程

以下代码样例将 addraddr+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");

}


示例 4–8 将线程移动到内存

本样例代码使用 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);

}


示例 4–9 遍历 lgroup 分层结构

以下样例代码遍历并列显了 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);

}


示例 4–10 查找位于给定 lgroup 外具有可用内存的最近 lgroup

#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));

}


示例 4–11 查找具有可用内存的最近 lgroup

本示例代码查找具有可用内存且距离给定线程的主 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));

}