da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(_UWIN) && defined(_BLD_ast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid _STUB_vmmopen(){}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "vmhdr.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _sys_stat
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sys/stat.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcntl.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_IRUSR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CREAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CREAT_MODE 0644
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sys/mman.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define mmap(a,b,c,d,e,f) MAP_FAILED
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define munmap(a,b) MAP_FAILED
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Create a region to allocate based on mmap()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin**
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo (kpv@research.att.com)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef MAP_FAILED
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MAP_FAILED (void*)(-1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MM_MAGIC (('V'<<24) | ('M'<<16) | ('A'<<8) | ('P'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MM_ROUND (64*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MM_START ROUND(sizeof(Mmvm_t),ALIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _user_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{ struct _user_s* next; /* link list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int key; /* identifying key */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Void_t* data; /* data to be returned */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} User_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _mmvm_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmulong_t magic; /* magic bytes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Void_t* base; /* base of the map */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t size; /* current size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t busy; /* amount in use */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t round; /* amount to round to */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin User_t* user; /* some user data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Mmvm_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct _mmvmdisc_s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmdisc_t disc; /* Vmalloc discipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd; /* file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvm_t* mm; /* mmap data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} Mmvmdisc_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int mmvminit(char* file, Void_t* addr, size_t round, Mmvm_t* mm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int mmvminit(file, addr, round, mm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* file; /* file to map data from */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* addr; /* desired starting address */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t round; /* amount to round requests */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMmvm_t* mm; /* to return some mapped info */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Void_t *base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvm_t *hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = open(file, O_RDWR, CREAT_MODE)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((size = lseek(fd, (off_t)0, 2)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(size == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto new_f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read the header */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lseek(fd, (off_t)0, 0) != (off_t)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(read(fd, mm, sizeof(Mmvm_t)) != sizeof(Mmvm_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mm->magic != MM_MAGIC || !mm->base ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (off_t)mm->size != size || mm->busy > mm->size )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = (Void_t*)mmap(mm->base, mm->size, PROT_READ|PROT_WRITE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin MAP_FIXED|MAP_SHARED, fd, (off_t)0 );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(base == (Void_t*)MAP_FAILED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((fd = open(file, O_RDWR|O_CREAT, CREAT_MODE)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin new_f: /* create an initial set of data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = round;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lseek(fd, size-1, 0) != (size-1) || write(fd, "", 1) != 1 )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = (Void_t*)mmap(addr, (size_t)size, PROT_READ|PROT_WRITE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (addr ? MAP_FIXED : 0)|MAP_SHARED, fd, (off_t)0 );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(base == (Void_t*)MAP_FAILED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* write magic number */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr = (Mmvm_t*)base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->magic = MM_MAGIC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->base = base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->size = size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->busy = MM_START;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->round = round;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hdr->user = NIL(User_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(mm, hdr, sizeof(Mmvm_t));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(fd >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* mmvmmemory(Vmalloc_t* vm, Void_t* caddr,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t csize, size_t nsize, Vmdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* mmvmmemory(vm, caddr, csize, nsize, disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* caddr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t csize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t nsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvmdisc_t *mmdc = (Mmvmdisc_t*)disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mmdc->fd < 0 || !mmdc->mm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MMADDR(b) ((Void_t*)(((Vmuchar_t*)b) + MM_START) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(caddr && caddr != MMADDR(mmdc->mm->base) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nsize < csize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nsize > mmdc->mm->size-MM_START)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* base and size of new map */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin caddr = mmdc->mm->base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin csize = MM_START + nsize +
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((nsize % disc->round) < (disc->round/2) ? disc->round/2 : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin csize = ROUND(csize, disc->round);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make room for new space */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lseek(mmdc->fd, (off_t)(csize-1), 0) != (off_t)(csize-1) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(mmdc->fd, "", 1) != 1 )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* remap the space */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)munmap(caddr, mmdc->mm->size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin caddr = (Void_t*)mmap(caddr, csize, PROT_READ|PROT_WRITE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin MAP_FIXED|MAP_SHARED, mmdc->fd, (off_t)0 );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(caddr == (Void_t*)MAP_FAILED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin caddr = NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(caddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->mm->size = csize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else /* bad problem */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { close(mmdc->fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->mm = NIL(Mmvm_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->mm->busy = nsize+MM_START;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (Void_t*)(((Vmuchar_t*)mmdc->mm->base) + MM_START);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int mmvmexcept(Vmalloc_t* vm, int type, Void_t* data, Vmdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int mmvmexcept(vm, type, data, disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvmdisc_t *mmdc = (Mmvmdisc_t*)disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmuchar_t *base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type == VM_OPEN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(mmdc->mm->busy > MM_START)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { base = ((Vmuchar_t*)mmdc->mm->base) + MM_START;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *((Void_t**)data) = (Void_t*)base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type == VM_CLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { (void)munmap(mmdc->mm->base, mmdc->mm->size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)close(mmdc->fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vmfree(Vmheap, mmdc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1; /* freeing of mapped data is already done */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vmmopen(char* file, Void_t* base, size_t round)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vmmopen(file, base, round)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* file; /* file mapping data from */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* base; /* desired starting address */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t round; /* amount to round requests */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmalloc_t *vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvmdisc_t *mmdc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvm_t mm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!file)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Vmalloc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set the amount to round up to on each memory request */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin GETPAGESIZE(_Vmpagesize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(round < MM_ROUND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin round = MM_ROUND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin round = ROUND(round, _Vmpagesize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = mmvminit(file, base, round, &mm)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Vmalloc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mmdc = (Mmvmdisc_t*)vmalloc(Vmheap, sizeof(Mmvmdisc_t))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Vmalloc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->disc.memoryf = mmvmmemory;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->disc.exceptf = mmvmexcept;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->disc.round = mm.round;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->fd = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmdc->mm = (Mmvm_t*)mm.base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(vm = vmopen(&mmdc->disc, Vmbest, VM_TRUST)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { mmvmexcept(NIL(Vmalloc_t*), VM_CLOSE, NIL(Void_t*), &mmdc->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Vmalloc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* vmmset(Vmalloc_t* vm, int key, Void_t* data, int set)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* vmmset(vm, data, key, set)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm; /* a region based on vmmmopen */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint key; /* key of data to be set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* data; /* data to be set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint set; /* 1 for setting, 0 for getting */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin User_t *u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Mmvm_t *mmvm = ((Mmvmdisc_t*)vm->disc)->mm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(u = mmvm->user; u; u = u->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(u->key == key)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!set)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return u ? u->data : NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(u)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { Void_t* old = u->data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u->data = data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(u = (User_t*)vmalloc(vm, sizeof(User_t))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { u->data = data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u->key = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u->next = mmvm->user;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmvm->user = u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif