150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * memtoy:  segment.c - manage memory segments
350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * create/destroy/map/unmap - anonymous, file and SysV shmem segments
550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * touch [read or write] - ranges of segments
650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * mbind - ranges of segments
750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * show mappings or locations of segment pages
850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
1050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  Copyright (c) 2005 Hewlett-Packard, Inc
1150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  All rights reserved.
1250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
1350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
1450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
1550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  This program is free software; you can redistribute it and/or modify
1650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  it under the terms of the GNU General Public License as published by
1750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  the Free Software Foundation; either version 2 of the License, or
1850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  (at your option) any later version.
1950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
2050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  This program is distributed in the hope that it will be useful,
2150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  but WITHOUT ANY WARRANTY; without even the implied warranty of
2250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  GNU General Public License for more details.
2450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
2550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  You should have received a copy of the GNU General Public License
2650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  along with this program; if not, write to the Free Software
2750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
2850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
29cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya
30cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya#include "config.h"
311024556003d4de4bc062f711693f091f0a10fd9dyaberauneya#if HAVE_NUMA_H && HAVE_NUMAIF_H && HAVE_LINUX_MEMPOLICY_H
3250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/types.h>
3350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/ipc.h>
3450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/mman.h>
3550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/shm.h>
3650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/stat.h>
3750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <sys/time.h>
3850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <errno.h>
3950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <fcntl.h>
4050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <libgen.h>
4150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <numa.h>
42cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya#include <numaif.h>
4350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <stdarg.h>
4450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <stdlib.h>
4550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <stdio.h>
4650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <string.h>
4750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include <unistd.h>
4850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
4950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include "memtoy.h"
5050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#include "segment.h"
5150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
5250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modakstruct segment {
53354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *seg_name;
54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	void *seg_start;
55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t seg_length;
5650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
57354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	off_t seg_offset;	/* memory mapped files */
58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *seg_path;		/*   "      "      "   */
5950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	seg_type_t seg_type;
61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int seg_slot;
62354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int seg_flags;		/* shared|private */
63354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int seg_prot;
64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int seg_fd;		/* saved file descriptor */
65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int seg_shmid;
6650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
6750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak};
6850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao#define MAX_SEGMENTS 63		/* arbitrary max */
7050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define SEG_FD_NONE (-1)
7150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define SHM_ID_NONE (-1)
7250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
7350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define SEG_ERR (0)
7450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define SEG_OK  (1)
7550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
7650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define SEG_OFFSET(SEGP, ADDR) ((char *)(ADDR) - (char *)(SEGP->seg_start))
7750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
7850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
7950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * =========================================================================
8050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid segment_init(struct global_context *gcp)
8250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
8350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
8450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * one extra slot to terminate the list
8550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	gcp->seglist = calloc(MAX_SEGMENTS + 1, sizeof(segment_t *));
8750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (!gcp->seglist)
88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		die(4, "%s: can't alloc segment table\n", gcp->program_name);
8950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	gcp->seg_avail = NULL;
9050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
9150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
9250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic segment_t *new_segment(void)
9450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segment_t *segp = (segment_t *) calloc(1, sizeof(segment_t));
9750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
9850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL)
9950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  failed to allocate segment\n",
10050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name);
10150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return segp;
10250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
10350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
10450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
10550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * get_seg_slot() -- allocate a segment table slot for a new segment
10650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic segment_t *get_seg_slot(void)
10850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
11050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp, **segpp;
11150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
11250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
11350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * consume saved slot, if any
11450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
11550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = gcp->seg_avail;
11650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp != NULL) {
11750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		gcp->seg_avail = NULL;
11850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return segp;
11950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
120bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
12150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
12250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * simple linear scan for first available slot
12350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
124cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya	for (segpp = gcp->seglist; (segp = *segpp); ++segpp) {
12550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp->seg_type == SEGT_NONE)
12650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			return segp;
12750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
12850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
12950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segpp < &gcp->seglist[MAX_SEGMENTS]) {
13050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		/*
13150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 * previously unused slot
13250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 */
13350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		*segpp = segp = new_segment();
13450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_slot = segpp - gcp->seglist;
13550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return segp;
13650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
13750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
13850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	fprintf(stderr, "%s:  segment table full\n", gcp->program_name);
139cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis	return NULL;
14050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
14150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void unmap_segment(segment_t * segp)
14350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
14450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
145df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (segp->seg_start == MAP_FAILED)
14650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return;		/* already unmapped */
14750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
14850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	switch (segp->seg_type) {
14950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_ANON:
15050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_FILE:
15150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		munmap(segp->seg_start, segp->seg_length);
15250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
15350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
15450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_SHM:
15550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		shmdt(segp->seg_start);
15650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
15750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
15850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	default:
15950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		// shouldn't happen?
16050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
16150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
16250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
16350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_start = MAP_FAILED;
16450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
16550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
16650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
16750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * free up a segment table slot, freeing any string storage
16850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * and removing shm segment, if necessary
16950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * clear out the segment, but preserve slot #
17050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void free_seg_slot(segment_t * segp)
17250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int slot = segp->seg_slot;
17550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
1764bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak	if (segp->seg_name != NULL)
17750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free(segp->seg_name);
17850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
17950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_path != NULL)
18050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free(segp->seg_path);
18150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (segp->seg_type == SEGT_FILE && segp->seg_fd != SEG_FD_NONE)
18350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		close(segp->seg_fd);
18450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (segp->seg_type == SEGT_SHM && segp->seg_shmid != SHM_ID_NONE)
18650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		shmctl(segp->seg_shmid, IPC_RMID, NULL);
18750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
18850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	(void)memset(segp, 0, sizeof(*segp));
18950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
19050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_slot = slot;
19150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (gcp->seg_avail == NULL)
19250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		gcp->seg_avail = segp;
193bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
19450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
19550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
19650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
19750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * called from memtoy "at exit" cleanup().
19850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * primarily to remove any shm segments created.
19950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaovoid segment_cleanup(struct global_context *gcp)
20150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
20250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp, **segpp;
203bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
20450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segpp = gcp->seglist;
20550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segpp == NULL)
20650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return;
20750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
208cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya	for (; (segp = *segpp); ++segpp) {
20950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp->seg_type != SEGT_SHM) {
21050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			continue;
21150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
21250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);	/* to remove shared mem */
21350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
21450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
21550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
216354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic size_t round_up_to_pagesize(size_t size)
21750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
21850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
219354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t pagemask = gcp->pagesize - 1;
22050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return ((size + pagemask) & ~pagemask);
22250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
22350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
22450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic size_t round_down_to_pagesize(size_t size)
22650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
22750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t pagemask = gcp->pagesize - 1;
22950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
23050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return (size & ~pagemask);
23150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
23250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
23350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
23450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
23550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * get_node() -- fetch numa node id of page at vaddr
23650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * [from Ray Bryant's [SGI] memory migration tests]
23750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
238354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int get_node(void *vaddr)
23950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
24050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	int rc, node;
24150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
242354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	rc = get_mempolicy(&node, NULL, 0, vaddr, MPOL_F_NODE | MPOL_F_ADDR);
24350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (rc)
24450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return -1;
24550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
24650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return node;
24750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
24850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
24950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
25050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * =========================================================================
25150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
252354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int map_anon_segment(segment_t * segp)
25350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
25450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
25550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
25650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	char *memp;
257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int flags = segp->seg_flags;
25850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
259df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (!flags)
26050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		flags = MAP_PRIVATE;	/* default */
26150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
262354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	memp = (char *)mmap(0, segp->seg_length, segp->seg_prot, flags | MAP_ANONYMOUS, 0,	/* fd -- ignored */
263354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    0);	/* offset -- ignored */
26450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
26550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (memp == MAP_FAILED) {
26650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
26750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  anonymous mmap failed - %s\n",
26850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			__FUNCTION__, strerror(err));
26950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
27050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
27150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
27250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	vprint("%s:  mmap()ed anon seg %s at 0x%lx-0x%lx\n",
273354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       gcp->program_name, segp->seg_name,
274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       memp, memp + segp->seg_length - 1);
27550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
27650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_start = memp;
27750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
27850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
27950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
28050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
28150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
28250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * open_file() -- open and validate file when registering a file segment.
28350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * remember fd in segment struct.
28450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
285354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int open_file(segment_t * segp)
28650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
28750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
28850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
28950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	struct stat stbuf;
29050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	int fd, flags;
29150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
292df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (stat(segp->seg_path, &stbuf) < 0) {
29350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
29450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  can't stat %s - %s\n",
295354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			gcp->program_name, segp->seg_path, strerror(err));
29650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);
29750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
29850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
29950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
30050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
30150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * TODO:  for now, just regular files.  later?
30250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
303df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (!S_ISREG(stbuf.st_mode)) {
30450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  %s - is not a regular file\n",
30550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, segp->seg_path);
30650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);
30750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
30850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
30950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
31050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
31150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * Open file with maximal privileges;  adjust segment mapping
31250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * protections if permissions don't allow full R/W access.
31350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (!access(segp->seg_path, R_OK | W_OK))
31550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		flags = O_RDWR;
31650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	else if (!access(segp->seg_path, R_OK)) {
31750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		flags = O_RDONLY;
31850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_prot &= ~PROT_WRITE;
31950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	} else if (!access(segp->seg_path, W_OK)) {
32050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		flags = O_WRONLY;
32150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_prot &= ~PROT_READ;
32250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	} else {
32350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  can't access %s\n",
32450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, segp->seg_path);
32550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);
32650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
32750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
32850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
32950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	fd = open(segp->seg_path, flags);
33050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (fd < 0) {
33150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
33250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  can't open %s - %s\n",
333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			gcp->program_name, segp->seg_path, strerror(err));
33450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);
33550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
33650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
33750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
33850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_fd = fd;
33950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
34050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
34150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
34250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
34350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * re-fetch file size at map time -- just in case it's changed
34450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic size_t file_size(int fd)
34650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
34750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	struct stat stbuf;
34850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
34950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (fstat(fd, &stbuf) != 0) {
35050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return BOGUS_SIZE;
35150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
35250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
35350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return stbuf.st_size;
35450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
35550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
35650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
35750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * map_file_segment() -- map a [range of a] registered file segment.
35850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int map_file_segment(segment_t * segp)
36050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
36150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
36250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
36350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	char *memp;
36450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	size_t size;
36550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	int fd;
366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int flags = segp->seg_flags;
36750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
368df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (!flags)
36950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		flags = MAP_PRIVATE;	/* default */
37050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
37150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if ((fd = segp->seg_fd) == SEG_FD_NONE) {
37250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  file %s not open\n",
37350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, segp->seg_path);
37450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
37550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
37650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
37750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	size = file_size(fd);
37850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
37950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
38050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * page align offset/length;  verify fit in file
38150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
38250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_offset = round_down_to_pagesize(segp->seg_offset);
38350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_offset > size) {
38450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s: offset 0x%lx beyond end of file %s\n",
385354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			gcp->program_name, segp->seg_offset, segp->seg_path);
38650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
38750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
38850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
38950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_length == 0)
39050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_length = round_up_to_pagesize(size) -
391354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    segp->seg_offset;
39250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	else
39350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_length = round_up_to_pagesize(segp->seg_length);
39450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
39550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	memp = (char *)mmap(0, segp->seg_length,
396354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			    segp->seg_prot, flags, fd, segp->seg_offset);
39750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
39850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (memp == MAP_FAILED) {
39950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
40050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  mmap of %s failed - %s\n",
40150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			__FUNCTION__, segp->seg_path, strerror(err));
40250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
40350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
40450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
40550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	vprint("%s:  mmap()ed file seg %s at 0x%lx-0x%lx\n",
406354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       gcp->program_name, segp->seg_name,
407354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       memp, memp + segp->seg_length - 1);
40850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
40950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_start = memp;
41050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
41150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
41250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
41350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
41450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
41550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * get_shm_segment() -- create [shmget] a new shared memory segment
41650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
417354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int get_shm_segment(segment_t * segp)
41850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
41950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
42050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
42150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	int shmid;
42250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
423354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	shmid = shmget(IPC_PRIVATE, segp->seg_length, SHM_R | SHM_W);
42450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (shmid == -1) {
42550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
42650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  failed to get shm segment %s - %s\n",
427354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			gcp->program_name, segp->seg_name, strerror(err));
42850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free_seg_slot(segp);
42950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
43050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
43150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
43250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_shmid = shmid;
43350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	vprint("%s:  shm seg %s id:  %d\n",
434354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       gcp->program_name, segp->seg_name, segp->seg_shmid);
43550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
43650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
43750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
43850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
43950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * map_shm_segment() -- attach [shmat] a shared memory segment
44050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
441354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int map_shm_segment(segment_t * segp)
44250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
44350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	glctx_t *gcp = &glctx;
44450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
44550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_start = shmat(segp->seg_shmid, NULL, 0);
44650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start == MAP_FAILED) {
44750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
448cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		fprintf(stderr, "%s:  failed to attach shm segment %s: %s\n",
449354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			gcp->program_name, segp->seg_name, strerror(err));
45050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
45150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
45250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
45350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	vprint("%s:  mmap()ed shm seg %s at 0x%lx-0x%lx\n",
454354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       gcp->program_name, segp->seg_name,
455354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       segp->seg_start, segp->seg_start + segp->seg_length - 1);
45650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
45750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
45850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
45950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
46050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
46150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * =========================================================================
46250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment API
46350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
46450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
46550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_get(name) - lookup named segment
46650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modakTODO:  move to segment private functions?
46750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
468354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaosegment_t *segment_get(char *name)
46950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
470354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
47150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp, **segpp;
472bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
473cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya	for (segpp = gcp->seglist; (segp = *segpp); ++segpp) {
47450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp->seg_type == SEGT_NONE) {
47550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			if (gcp->seg_avail == NULL)
47650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak				gcp->seg_avail = *segpp;
47750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			continue;
47850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
47950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (!strcmp(name, segp->seg_name))
48050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			return segp;
48150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
48250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
483354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	if (gcp->seg_avail == NULL && segpp < &gcp->seglist[MAX_SEGMENTS]) {
48450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		/*
48550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 * prealloc an available segment
48650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 */
48750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		*segpp = segp = new_segment();
48850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp != NULL) {
48950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			segp->seg_slot = segpp - gcp->seglist;
49050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->seg_avail = segp;
49150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
49250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
49350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
494cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis	return NULL;
49550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
49650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
49750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
49850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_register:  register an anon, file or shm segment based on args.
49950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *	for anon and shm, 'name' = segment name.
50050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *	for file, 'name' = path name; segment name = basename(path)
50150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
50250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * returns: !0 on success; 0 on failure
50350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
504354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_register(seg_type_t type, char *name, range_t * range, int flags)
50550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
506354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
50750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp;
508354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *path;
50950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
51050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(basename(name));	/* ensure unique name */
51150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp != NULL) {
51250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  segment %s already exists\n",
51350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, segp->seg_name);
51450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
51550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
51650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
51750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = get_seg_slot();
51850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL)
51950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
52050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
52150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	path = strdup(name);	/* save a copy */
522354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_name = strdup(basename(name));
523354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_start = MAP_FAILED;
52450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_length = round_up_to_pagesize(range->length);
52550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_offset = round_down_to_pagesize(range->offset);
526354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_type = type;
527354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_flags = flags;	/* possibly 0 */
528354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_prot = PROT_READ | PROT_WRITE;	/* default */
529354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_fd = SEG_FD_NONE;
530354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segp->seg_shmid = SHM_ID_NONE;
53150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
53250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	switch (type) {
53350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_ANON:
53450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free(path);
53550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
53650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
53750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_FILE:
53850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_path = path;
53950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return open_file(segp);
54050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
54150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
54250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_SHM:
54350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free(path);
54450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return get_shm_segment(segp);
54550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
54650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
54750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	default:
54850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		free(path);
54950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
55050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
55150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
55250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
55350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modakstatic char *segment_header =
554354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    "  _____address______ ____length____ ____offset____ prot  share  name\n";
55550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
55650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modakstatic char seg_type[] = { '.', 'a', 'f', 's' };
55750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
558354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int show_one_segment(segment_t * segp, bool header)
55950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
56050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	char *protection, *share, *name;
56150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
562354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	switch (segp->seg_prot & (PROT_READ | PROT_WRITE)) {
563354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case PROT_READ | PROT_WRITE:
56450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		protection = "rw";
56550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
56650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
56750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case PROT_READ:
56850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		protection = "r-";
56950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
57050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
57150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case PROT_WRITE:
57250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		protection = "-w";
57350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
57450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
57550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	default:
57650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		protection = "--";
57750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
57850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
57950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
58050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_flags)
58150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		share = (segp->seg_flags & MAP_SHARED) ? "shared " : "private";
58250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	else
58350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		share = "default";
58450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
58550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	name = (segp->seg_type == SEGT_FILE) ? segp->seg_path : segp->seg_name;
58650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
58750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (header)
588cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		puts(segment_header);
58950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
59050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start != MAP_FAILED) {
591cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		printf("%c 0x%p 0x%012lx 0x%012lx  %s  %s %s\n",
592354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       seg_type[segp->seg_type],
593354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       segp->seg_start,
594354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       segp->seg_length,
595354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       segp->seg_offset, protection, share, name);
59650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	} else {
59750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		printf("%c *** not-mapped *** 0x%012lx 0x%012lx  %s  %s %s\n",
598354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       seg_type[segp->seg_type],
599354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       segp->seg_length,
600354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       segp->seg_offset, protection, share, name);
60150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
602bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
60350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
60450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
60550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
60650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
60750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_show() -- show specifed segment, or all, if none specified.
60850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
609354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_show(char *name)
61050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
611354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
61250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp, **segpp;
613354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	bool header;
61450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
615df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (name != NULL) {
61650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp = segment_get(name);
61750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp == NULL) {
61850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			fprintf(stderr, "%s:  no such segment:  %s\n",
61950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak				gcp->program_name, name);
62050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			return SEG_ERR;
62150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
62250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		show_one_segment(segp, false);
62350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_OK;
62450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
62550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
62650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
62750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * show all
62850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
62950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	header = true;
630df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	for (segpp = gcp->seglist; (segp = *segpp); ++segpp) {
63150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (segp->seg_type != SEGT_NONE) {
63250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			show_one_segment(segp, header);
633354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			header = false;	/* first time only */
63450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
63550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
63650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
63750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
63850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
63950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
64050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
64150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
64250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_remove() - remove the specified segment, if exists.
64350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
644354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_remove(char *name)
64550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
646354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
64750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp;
64850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
64950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
65050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
65150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
65250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
65350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
65450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
65550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
65650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	unmap_segment(segp);
65750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
65850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	free_seg_slot(segp);
65950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
66050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
66150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
66250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
66350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
6644bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * segment_touch() - "touch" [read or write] each page of specified range
66550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *                   -- from offset to offset+length -- to fault in or to
66650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *                   test protection.
66750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * NOTE:  offset is relative to start of mapping, not start of file!
66850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
669354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_touch(char *name, range_t * range, int rw)
67050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
671354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
672354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segment_t *segp;
673354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	off_t offset;
674354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t length, maxlength;
67550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	unsigned long *memp;
67650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	struct timeval t_start, t_end;
67750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
67850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
67950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
68050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
68150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
68250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
68350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
68450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
685354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	offset = round_down_to_pagesize(range->offset);
68650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (offset >= segp->seg_length) {
68750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  offset %ld is past end of segment %s\n",
68850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, offset, name);
68950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
69050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
69150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
692354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	memp = (unsigned long *)(segp->seg_start + offset);
69350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	maxlength = segp->seg_length - offset;
69450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
69550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	length = range->length;
69650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (length)
69750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = round_up_to_pagesize(length);
69850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
69950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
70050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * note:  we silently truncate to max length [end of segment]
70150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
702df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (length == 0 || length > maxlength)
70350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = maxlength;
70450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
70550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	gettimeofday(&t_start, NULL);
70650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	touch_memory(rw, memp, length);
70750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	gettimeofday(&t_end, NULL);
70850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	printf("%s:  touched %d pages in %6.3f secs\n",
709354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       gcp->program_name, length / gcp->pagesize,
710354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       (float)(tv_diff_usec(&t_start, &t_end)) / 1000000.0);
711bdbaec51a423e715c2b03ed9e497e9a1fba6103esubrata_modak
71250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
71350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
71450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
71550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
71650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_unmap() -  unmap the specified segment, if any, from seg_start
7174bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak *                    to seg_start+seg_lenth.  Leave the segment in the
71850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *                    table;
71950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
720354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_unmap(char *name)
72150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
722354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
72350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segment_t *segp;
72450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
72550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
72650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
72750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
72850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
72950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
73050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
73150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
73250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start == MAP_FAILED)
73350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_OK;	/* silent success */
73450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
73550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	switch (segp->seg_type) {
73650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_ANON:
73750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_FILE:
738354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		munmap(segp->seg_start, segp->seg_length);
73950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
74050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
74150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_SHM:
742354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		//TODO:  shmdt()...
74350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
744354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* Handle default to get rid of -Wswitch-enum */
745cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya	default:
746cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		break;
74750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
74850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
74950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp->seg_start = MAP_FAILED;
75050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
75150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
75250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
75350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
75450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
75550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_map() -- [re] map() a previously unmapped segment
75650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *                  no-op if already mapped.
75750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *                  range only applies to mapped file.
75850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
759354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_map(char *name, range_t * range, int flags)
76050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
761354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
762354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segment_t *segp;
76350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
76450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
76550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
76650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
76750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
76850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
76950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
77050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
77150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start != MAP_FAILED) {
77250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  segment %s already mapped\n",
77350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
77450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_OK;	/* treat as success */
77550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
77650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
77750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (flags != 0)
77850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		segp->seg_flags = flags;
77950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
78050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	switch (segp->seg_type) {
78150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_ANON:
78250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return map_anon_segment(segp);
78350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
78450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
78550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_FILE:
78650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (range != NULL) {
78750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			segp->seg_offset = range->offset;
78850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			segp->seg_length = range->length;
78950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
79050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return map_file_segment(segp);
79150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
79250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
79350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	case SEGT_SHM:
79450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return map_shm_segment(segp);
79550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		break;
796354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		/* Handle default to get rid of -Wswitch-enum */
797cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya	default:
798cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		break;
79950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
80050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
801354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	return SEG_ERR;		/* unrecognized segment type -- shouldn't happen */
80250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
80350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
80450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
80550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
80650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_mbind() - set memory policy for a range of specified segment
80750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
80850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * NOTE:  offset is relative to start of mapping, not start of file
80950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
81050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modakint
811354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaosegment_mbind(char *name, range_t * range, int policy,
812354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	      nodemask_t * nodemask, int flags)
81350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
814354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
815354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segment_t *segp;
816354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *start;
817354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	off_t offset;
818354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t length, maxlength;
819354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int ret;
82050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
82150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
82250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
82350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
82450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
82550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
82650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
82750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
82850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start == MAP_FAILED) {
82950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  segment %s not mapped\n",
83050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
83150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
83250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
83350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
834354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	offset = round_down_to_pagesize(range->offset);
83550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (offset >= segp->seg_length) {
83650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  offset %ld is past end of segment %s\n",
83750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, offset, name);
83850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
83950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
84050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
841354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	start = segp->seg_start + offset;
84250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	maxlength = segp->seg_length - offset;
84350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
84450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	length = range->length;
84550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (length)
84650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = round_up_to_pagesize(length);
84750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
84850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
84950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * note:  we silently truncate to max length [end of segment]
85050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
851df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (length == 0 || length > maxlength)
85250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = maxlength;
85350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
854354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	ret = mbind(segp->seg_start + offset, length, policy, nodemask->n,
855354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		    NUMA_NUM_NODES, flags);
85650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
85750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (ret == -1) {
85850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int err = errno;
85950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  mbind() of segment %s failed - %s\n",
86050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name, strerror(err));
86150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
86250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
86350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
86450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
86550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
86650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
86750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak/*
86850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * segment_location() - report node location of specified range of segment
86950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak *
87050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak * NOTE:  offset is relative to start of mapping, not start of file
87150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak */
87250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define PG_PER_LINE 8
87350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak#define PPL_MASK (PG_PER_LINE - 1)
874354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint segment_location(char *name, range_t * range)
87550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak{
876354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	glctx_t *gcp = &glctx;
877354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	segment_t *segp;
878354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	char *apage, *end;
879354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	off_t offset;
880354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	size_t length, maxlength;
881354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int pgid, i;
882354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	bool need_nl;
88350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
88450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	segp = segment_get(name);
88550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp == NULL) {
88650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  no such segment:  %s\n",
88750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
88850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
88950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
89050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
89150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (segp->seg_start == MAP_FAILED) {
89250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  segment %s not mapped\n",
89350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, name);
89450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
89550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
89650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
897354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	offset = round_down_to_pagesize(range->offset);
89850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (offset >= segp->seg_length) {
89950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		fprintf(stderr, "%s:  offset %ld is past end of segment %s\n",
90050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			gcp->program_name, offset, name);
90150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		return SEG_ERR;
90250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
90350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
904354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	apage = segp->seg_start + offset;
90550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	maxlength = segp->seg_length - offset;
90650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
90750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	length = range->length;
90850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (length)
90950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = round_up_to_pagesize(length);
91050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
91150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	/*
91250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 * note:  we silently truncate to max length [end of segment]
91350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	 */
914df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	if (length == 0 || length > maxlength)
91550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		length = maxlength;
91650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
917354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	end = apage + length;
918354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	pgid = offset / gcp->pagesize;
91950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
92050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	show_one_segment(segp, false);	/* show mapping, no header */
92150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
92250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	printf("page offset   ");
923354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	for (i = 0; i < PG_PER_LINE; ++i)
92450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		printf(" +%02d", i);
92550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	printf("\n");
92650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	if (pgid & PPL_MASK) {
92750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		/*
92850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 * start partial line
92950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		 */
93050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int pgid2 = pgid & ~PPL_MASK;
931cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya		printf("%12x: ", pgid2);
93250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		while (pgid2 < pgid) {
93350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			printf("    ");
93450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			++pgid2;
93550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
93650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		need_nl = true;
93750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	} else
93850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		need_nl = false;
93950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
940df3eb16e38c6a163b0a7367c885679eed6140964Garrett Cooper	for (; apage < end; apage += gcp->pagesize, ++pgid) {
94150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		int node;
94250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
94350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		node = get_node(apage);
94450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (node < 0) {
94550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			fprintf(stderr, "\n%s:  "
946354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				"failed to get node for segment %s, offset 0x%lx\n",
947354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				gcp->program_name, name, SEG_OFFSET(segp,
948354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao								    apage));
94950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			return SEG_ERR;
95050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
95150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
95250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if ((pgid & PPL_MASK) == 0) {
95350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			if (need_nl)
95450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak				printf("\n");
955cb805c4aa6692dcb501f4220132ad8238170bc41yaberauneya			printf("%12x: ", pgid);	/* start a new line */
95650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			need_nl = true;
95750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
95850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		printf(" %3d", node);
95950512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
96050512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		if (signalled(gcp)) {
96150512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			reset_signal();
96250512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak			break;
96350512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak		}
96450512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	}
96550512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	printf("\n");
96650512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak
96750512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak	return SEG_OK;
96850512d9c147b0e8a05d4d814af3ba83852a79304subrata_modak}
969ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman#endif
970