Exemplo n.º 1
0
/*----------------------------------------------------------------------
|   TestHashMap
+---------------------------------------------------------------------*/
static int
TestHashMap()
{
    NPT_HashMap<NPT_String,A> a_map;
    A* a = NULL;

    CHECK(a_map.GetEntryCount() == 0);
    CHECK(a_map.HasKey("hello") == false);
    CHECK(!a_map.HasValue(A(1,2)));
    CHECK(NPT_FAILED(a_map.Get("bla", a)));
    CHECK(a == NULL);

    a_map.Put("hello", A(1,2));
    CHECK(a_map.GetEntryCount() == 1);
    CHECK(NPT_SUCCEEDED(a_map.Get("hello", a)));
    CHECK(*a == A(1,2));
    CHECK(a_map.HasKey("hello"));
    CHECK(a_map.HasValue(A(1,2)));
    CHECK(a_map["hello"] == A(1,2));
    
    CHECK(a_map["bla"] == A());
    CHECK(a_map.GetEntryCount() == 2);
    a_map["bla"] = A(3,4);
    CHECK(a_map["bla"] == A(3,4));
    CHECK(a_map.GetEntryCount() == 2);

    NPT_HashMap<NPT_String,A> b_map;
    b_map["hello"] = A(1,2);
    b_map["bla"] = A(3,4);
    CHECK(a_map == b_map);

    NPT_HashMap<NPT_String,A> c_map = a_map;
    CHECK(c_map["hello"] == a_map["hello"]);
    CHECK(c_map["bla"] == a_map["bla"]);

    CHECK(NPT_SUCCEEDED(a_map.Put("bla", A(5,6))));
    CHECK(NPT_SUCCEEDED(a_map.Get("bla", a)));
    CHECK(*a == A(5,6));
    CHECK(NPT_FAILED(a_map.Get("youyou", a)));

    b_map.Clear();
    CHECK(b_map.GetEntryCount() == 0);

    a_map["youyou"] = A(6,7);
    CHECK(NPT_FAILED(a_map.Erase("coucou")));
    CHECK(NPT_SUCCEEDED(a_map.Erase("bla")));
    CHECK(!a_map.HasKey("bla"));

    CHECK(!(a_map == c_map));
    CHECK(c_map != a_map);

    c_map = a_map;
    NPT_HashMap<NPT_String,A> d_map(c_map);
    CHECK(d_map == c_map);

    NPT_HashMap<int,int> i_map;
    i_map[5] = 6;
    i_map[6] = 7;
    i_map[9] = 0;
    CHECK(i_map[0] == 0 || i_map[0] != 0); // unknown value (will cause a valgrind warning)
    CHECK(i_map.GetEntryCount() == 4);

    NPT_HashMap<NPT_String,A> a1_map;
    NPT_HashMap<NPT_String,A> a2_map;
    a1_map["hello"] = A(1,2);
    a1_map["bla"]   = A(2,3);
    a1_map["youyou"]= A(3,4);
    a2_map["bla"]   = A(2,3);
    a2_map["youyou"]= A(3,4);
    a2_map["hello"] = A(1,2);
    CHECK(a1_map == a2_map);
    a1_map["foo"] = A(0,0);
    CHECK(a1_map != a2_map);
    a2_map["foo"] = A(0,0);
    CHECK(a1_map == a2_map);
    a2_map["foo"] = A(7,8);
    CHECK(a1_map != a2_map);
    a2_map["foo"] = A(0,0);
    a1_map["bir"] = A(0,0);
    a2_map["bar"] = A(0,0);
    CHECK(a1_map.GetEntryCount() == a2_map.GetEntryCount());
    CHECK(a1_map != a2_map);
    CHECK(!(a1_map == a2_map));
    
    NPT_HashMap<NPT_String, NPT_String> smap;
    for (unsigned int i=0; i<24; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        smap[s] = "1234";
        CHECK(smap[s] == "1234");
    }
    for (unsigned int i=0; i<24; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        CHECK(smap[s] == "1234");
    }
    for (unsigned int i=0; i<24; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        CHECK(NPT_SUCCEEDED(smap.Erase(s)));
        CHECK(!smap.HasKey(s));
    }
    CHECK(smap.GetEntryCount() == 0);
    
    Hasher hasher;
    NPT_HashMap<NPT_String, int, Hasher> zmap(hasher);
    for (unsigned int i=0; i<1024; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        zmap[s] = 1234;
        CHECK(zmap[s] == 1234);
    }
    for (unsigned int i=0; i<1024; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        CHECK(zmap[s] == 1234);
    }
    for (unsigned int i=0; i<1024; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        CHECK(NPT_SUCCEEDED(zmap.Erase(s)));
        CHECK(!zmap.HasKey(s));
    }
    CHECK(zmap.GetEntryCount() == 0);
    
    NPT_HashMap<NPT_String, int> imap;
    for (int i=0; i<1024; i++) {
        NPT_String s = NPT_String::Format("blabla%d", i);
        imap[s] = i;
        CHECK(imap[s] == i);
    }
    unsigned int zz = 1024;
    for (NPT_HashMap<NPT_String, int>::Iterator it = imap.GetEntries();
                                                it;
                                                ++it) {
        CHECK(imap.HasKey((*it).GetKey()));
        CHECK(imap.HasValue((*it).GetValue()));
        --zz;
    }
    CHECK(zz==0);
    
    NPT_HashMap<NPT_String, NPT_String*> p_map;
    p_map["1"] = new NPT_String("hello");
    p_map["2"] = new NPT_String("good bye");
    p_map.Apply(NPT_MapEntryValueDeleter<NPT_HashMap<NPT_String, NPT_String*>::Entry>());

    return 0;
}
Exemplo n.º 2
0
static int
smmap_common(caddr_t *addrp, size_t len,
    int prot, int flags, struct file *fp, offset_t pos)
{
	struct vnode *vp;
	struct as *as = curproc->p_as;
	uint_t uprot, maxprot, type;
	int error;
	int in_crit = 0;

	if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | _MAP_NEW |
	    _MAP_LOW32 | MAP_NORESERVE | MAP_ANON | MAP_ALIGN |
	    MAP_TEXT | MAP_INITDATA)) != 0) {
		/* | MAP_RENAME */	/* not implemented, let user know */
		return (EINVAL);
	}

	if ((flags & MAP_TEXT) && !(prot & PROT_EXEC)) {
		return (EINVAL);
	}

	if ((flags & (MAP_TEXT | MAP_INITDATA)) == (MAP_TEXT | MAP_INITDATA)) {
		return (EINVAL);
	}

#if defined(__sparc)
	/*
	 * See if this is an "old mmap call".  If so, remember this
	 * fact and convert the flags value given to mmap to indicate
	 * the specified address in the system call must be used.
	 * _MAP_NEW is turned set by all new uses of mmap.
	 */
	if ((flags & _MAP_NEW) == 0)
		flags |= MAP_FIXED;
#endif
	flags &= ~_MAP_NEW;

	type = flags & MAP_TYPE;
	if (type != MAP_PRIVATE && type != MAP_SHARED)
		return (EINVAL);


	if (flags & MAP_ALIGN) {

		if (flags & MAP_FIXED)
			return (EINVAL);

		/* alignment needs to be a power of 2 >= page size */
		if (((uintptr_t)*addrp < PAGESIZE && (uintptr_t)*addrp != 0) ||
		    !ISP2((uintptr_t)*addrp))
			return (EINVAL);
	}
	/*
	 * Check for bad lengths and file position.
	 * We let the VOP_MAP routine check for negative lengths
	 * since on some vnode types this might be appropriate.
	 */
	if (len == 0 || (pos & (u_offset_t)PAGEOFFSET) != 0)
		return (EINVAL);

	maxprot = PROT_ALL;		/* start out allowing all accesses */
	uprot = prot | PROT_USER;

	if (fp == NULL) {
		ASSERT(flags & MAP_ANON);
		/* discard lwpchan mappings, like munmap() */
		if ((flags & MAP_FIXED) && curproc->p_lcp != NULL)
			lwpchan_delete_mapping(curproc, *addrp, *addrp + len);
		as_rangelock(as);
		error = zmap(as, addrp, len, uprot, flags, pos);
		as_rangeunlock(as);
		/*
		 * Tell machine specific code that lwp has mapped shared memory
		 */
		if (error == 0 && (flags & MAP_SHARED)) {
			/* EMPTY */
			LWP_MMODEL_SHARED_AS(*addrp, len);
		}
		return (error);
	} else if ((flags & MAP_ANON) != 0)
		return (EINVAL);

	vp = fp->f_vnode;

	/* Can't execute code from "noexec" mounted filesystem. */
	if ((vp->v_vfsp->vfs_flag & VFS_NOEXEC) != 0)
		maxprot &= ~PROT_EXEC;

	/*
	 * These checks were added as part of large files.
	 *
	 * Return ENXIO if the initial position is negative; return EOVERFLOW
	 * if (offset + len) would overflow the maximum allowed offset for the
	 * type of file descriptor being used.
	 */
	if (vp->v_type == VREG) {
		if (pos < 0)
			return (ENXIO);
		if ((offset_t)len > (OFFSET_MAX(fp) - pos))
			return (EOVERFLOW);
	}

	if (type == MAP_SHARED && (fp->f_flag & FWRITE) == 0) {
		/* no write access allowed */
		maxprot &= ~PROT_WRITE;
	}

	/*
	 * XXX - Do we also adjust maxprot based on protections
	 * of the vnode?  E.g. if no execute permission is given
	 * on the vnode for the current user, maxprot probably
	 * should disallow PROT_EXEC also?  This is different
	 * from the write access as this would be a per vnode
	 * test as opposed to a per fd test for writability.
	 */

	/*
	 * Verify that the specified protections are not greater than
	 * the maximum allowable protections.  Also test to make sure
	 * that the file descriptor does allows for read access since
	 * "write only" mappings are hard to do since normally we do
	 * the read from the file before the page can be written.
	 */
	if (((maxprot & uprot) != uprot) || (fp->f_flag & FREAD) == 0)
		return (EACCES);

	/*
	 * If the user specified an address, do some simple checks here
	 */
	if ((flags & MAP_FIXED) != 0) {
		caddr_t userlimit;

		/*
		 * Use the user address.  First verify that
		 * the address to be used is page aligned.
		 * Then make some simple bounds checks.
		 */
		if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
			return (EINVAL);

		userlimit = flags & _MAP_LOW32 ?
		    (caddr_t)USERLIMIT32 : as->a_userlimit;
		switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
		case RANGE_OKAY:
			break;
		case RANGE_BADPROT:
			return (ENOTSUP);
		case RANGE_BADADDR:
		default:
			return (ENOMEM);
		}
	}

	if ((prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
	    nbl_need_check(vp)) {
		int svmand;
		nbl_op_t nop;

		nbl_start_crit(vp, RW_READER);
		in_crit = 1;
		error = nbl_svmand(vp, fp->f_cred, &svmand);
		if (error != 0)
			goto done;
		if ((prot & PROT_WRITE) && (type == MAP_SHARED)) {
			if (prot & (PROT_READ | PROT_EXEC)) {
				nop = NBL_READWRITE;
			} else {
				nop = NBL_WRITE;
			}
		} else {
			nop = NBL_READ;
		}
		if (nbl_conflict(vp, nop, 0, LONG_MAX, svmand, NULL)) {
			error = EACCES;
			goto done;
		}
	}

	/* discard lwpchan mappings, like munmap() */
	if ((flags & MAP_FIXED) && curproc->p_lcp != NULL)
		lwpchan_delete_mapping(curproc, *addrp, *addrp + len);

	/*
	 * Ok, now let the vnode map routine do its thing to set things up.
	 */
	error = VOP_MAP(vp, pos, as,
	    addrp, len, uprot, maxprot, flags, fp->f_cred, NULL);

	if (error == 0) {
		/*
		 * Tell machine specific code that lwp has mapped shared memory
		 */
		if (flags & MAP_SHARED) {
			/* EMPTY */
			LWP_MMODEL_SHARED_AS(*addrp, len);
		}
		if (vp->v_type == VREG &&
		    (flags & (MAP_TEXT | MAP_INITDATA)) != 0) {
			/*
			 * Mark this as an executable vnode
			 */
			mutex_enter(&vp->v_lock);
			vp->v_flag |= VVMEXEC;
			mutex_exit(&vp->v_lock);
		}
	}

done:
	if (in_crit)
		nbl_end_crit(vp);
	return (error);
}