=====================================

These changes require rebuilding all.
        =====================================
        * fhandler.h: Add mmap(), munmap() and msync() to fhandler_base
        and fhandler_disk_file.
        * mmem.cc (mmap): Eliminated device dependent implementation details.
        These are moved to the appropriate fhandler class.
        (munmap): Ditto.
        (msync): Ditto.
        (fhandler_base::mmap): New method.
        (fhandler_base::munmap): Ditto.
        (fhandler_base::msync): Ditto.
        (fhandler_disk_file::mmap): Ditto.
        (fhandler_disk_file::munmap): Ditto.
        (fhandler_disk_file::msync): Ditto.
This commit is contained in:
Corinna Vinschen 2000-10-05 13:07:02 +00:00
parent 4e6a4ea8e8
commit d12eba25a5
3 changed files with 220 additions and 64 deletions

View File

@ -1,3 +1,18 @@
Thu Oct 5 14:58:00 2000 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h: Add mmap(), munmap() and msync() to fhandler_base
and fhandler_disk_file.
* mmem.cc (mmap): Eliminated device dependent implementation details.
These are moved to the appropriate fhandler class.
(munmap): Ditto.
(msync): Ditto.
(fhandler_base::mmap): New method.
(fhandler_base::munmap): Ditto.
(fhandler_base::msync): Ditto.
(fhandler_disk_file::mmap): Ditto.
(fhandler_disk_file::munmap): Ditto.
(fhandler_disk_file::msync): Ditto.
Thu Oct 5 01:52:43 2000 Christopher Faylor <cgf@cygnus.com> Thu Oct 5 01:52:43 2000 Christopher Faylor <cgf@cygnus.com>
* net.cc: General cleanup. * net.cc: General cleanup.

View File

@ -263,6 +263,11 @@ public:
virtual void dump (); virtual void dump ();
virtual int dup (fhandler_base *child); virtual int dup (fhandler_base *child);
virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
int flags, off_t off);
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
void *operator new (size_t, void *p) {return p;} void *operator new (size_t, void *p) {return p;}
virtual void init (HANDLE, DWORD, mode_t); virtual void init (HANDLE, DWORD, mode_t);
@ -461,6 +466,11 @@ public:
int lock (int, struct flock *); int lock (int, struct flock *);
BOOL is_device () { return FALSE; } BOOL is_device () { return FALSE; }
int fstat (struct stat *buf); int fstat (struct stat *buf);
virtual HANDLE mmap (caddr_t *addr, size_t len, DWORD access,
int flags, off_t off);
virtual int munmap (HANDLE h, caddr_t addr, size_t len);
virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags);
}; };
class fhandler_serial: public fhandler_base class fhandler_serial: public fhandler_base

View File

@ -166,15 +166,25 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
syscall_printf ("addr %x, len %d, prot %x, flags %x, fd %d, off %d", syscall_printf ("addr %x, len %d, prot %x, flags %x, fd %d, off %d",
addr, len, prot, flags, fd, off); addr, len, prot, flags, fd, off);
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
if (flags & MAP_PRIVATE)
access = FILE_MAP_COPY;
SetResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap"); SetResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
#if 0
/* Windows 95 does not have fixed addresses */ /* Windows 95 does not have fixed addresses */
/*
* CV: This assumption isn't correct. See Microsoft Platform SDK, Memory,
* description of call `MapViewOfFileEx'.
*/
if ((os_being_run != winNT) && (flags & MAP_FIXED)) if ((os_being_run != winNT) && (flags & MAP_FIXED))
{ {
set_errno (EINVAL); set_errno (EINVAL);
syscall_printf ("-1 = mmap(): win95 and MAP_FIXED"); syscall_printf ("-1 = mmap(): win95 and MAP_FIXED");
return (caddr_t) -1; return (caddr_t) -1;
} }
#endif
if (mmapped_areas == 0) if (mmapped_areas == 0)
{ {
@ -188,22 +198,16 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
} }
} }
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ; fhandler_disk_file fh_paging_file (NULL);
if (flags & MAP_PRIVATE) fhandler_base *fh;
access = FILE_MAP_COPY; caddr_t base = addr;
DWORD protect; HANDLE h;
if (access & FILE_MAP_COPY)
protect = PAGE_WRITECOPY;
else if (access & FILE_MAP_WRITE)
protect = PAGE_READWRITE;
else
protect = PAGE_READONLY;
HANDLE hFile;
if (fd == -1) if (fd == -1)
hFile = (HANDLE) 0xFFFFFFFF; {
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
}
else else
{ {
/* Ensure that fd is open */ /* Ensure that fd is open */
@ -214,69 +218,38 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap"); ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1; return (caddr_t) -1;
} }
hFile = fdtab[fd]->get_handle (); fh = fdtab[fd];
} }
HANDLE h = CreateFileMapping (hFile, &sec_none, protect, 0, len, NULL); h = fh->mmap (&base, len, access, flags, off);
if (h == 0)
if (h == INVALID_HANDLE_VALUE)
{ {
__seterrno ();
syscall_printf ("-1 = mmap(): CreateFileMapping failed with %E");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap"); ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1; return MAP_FAILED;
}
void *base;
if (flags & MAP_FIXED)
{
base = MapViewOfFileEx (h, access, 0, off, len, addr);
if (base != addr)
{
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
CloseHandle (h);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
}
else
{
base = MapViewOfFile (h, access, 0, off, len);
if (base == 0)
{
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFile failed with %E");
CloseHandle (h);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
} }
/* Now we should have a successfully mmaped area. /* Now we should have a successfully mmaped area.
Need to save it so forked children can reproduce it. Need to save it so forked children can reproduce it.
*/ */
mmap_record mmap_rec (h, access, off, len, base); mmap_record mmap_rec (h, access, off, len, base);
/* Get list of mmapped areas for this fd, create a new one if /* Get list of mmapped areas for this fd, create a new one if
one does not exist yet. one does not exist yet.
*/ */
list *l = mmapped_areas->get_list_by_fd (fd); list *l = mmapped_areas->get_list_by_fd (fd);
if (l == 0) if (l == 0)
{ {
/* Create a new one */ /* Create a new one */
l = new list; l = new list;
if (l == 0) if (l == 0)
{ {
UnmapViewOfFile (base); fh->munmap (h, base, len);
CloseHandle (h); set_errno (ENOMEM);
set_errno (ENOMEM); syscall_printf ("-1 = mmap(): ENOMEM");
syscall_printf ("-1 = mmap(): ENOMEM"); ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap"); return MAP_FAILED;
return (caddr_t) -1; }
}
l = mmapped_areas->add_list (l, fd); l = mmapped_areas->add_list (l, fd);
} }
@ -285,7 +258,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
syscall_printf ("%x = mmap() succeeded", base); syscall_printf ("%x = mmap() succeeded", base);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap"); ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) base; return base;
} }
/* munmap () removes an mmapped area. It insists that base area /* munmap () removes an mmapped area. It insists that base area
@ -322,9 +295,19 @@ munmap (caddr_t addr, size_t len)
mmap_record rec = l->recs[li]; mmap_record rec = l->recs[li];
if (rec.get_address () == addr) if (rec.get_address () == addr)
{ {
/* Unmap the area */ int fd = l->fd;
UnmapViewOfFile (addr); fhandler_disk_file fh_paging_file (NULL);
CloseHandle (rec.get_handle ()); fhandler_base *fh;
if (fd == -1 || fdtab.not_open (fd))
{
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
}
else
fh = fdtab[fd];
fh->munmap (rec.get_handle (), addr, len);
/* Delete the entry. */ /* Delete the entry. */
l->erase (li); l->erase (li);
syscall_printf ("0 = munmap(): %x", addr); syscall_printf ("0 = munmap(): %x", addr);
@ -334,8 +317,8 @@ munmap (caddr_t addr, size_t len)
} }
} }
} }
set_errno (EINVAL);
set_errno (EINVAL);
syscall_printf ("-1 = munmap(): EINVAL"); syscall_printf ("-1 = munmap(): EINVAL");
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap"); ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
@ -351,13 +334,161 @@ msync (caddr_t addr, size_t len, int flags)
syscall_printf ("addr = %x, len = %d, flags = %x", syscall_printf ("addr = %x, len = %d, flags = %x",
addr, len, flags); addr, len, flags);
/* However, check flags for validity. */
if ((flags & ~(MS_ASYNC | MS_SYNC | MS_INVALIDATE))
|| ((flags & MS_ASYNC) && (flags & MS_SYNC)))
{
syscall_printf ("-1 = msync(): Invalid flags");
set_errno (EINVAL);
return -1;
}
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
/* Check if a mmap'ed area was ever created */
if (mmapped_areas == 0)
{
syscall_printf ("-1 = msync(): mmapped_areas == 0");
set_errno (EINVAL);
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
return -1;
}
/* Iterate through the map, looking for the mmapped area.
Error if not found. */
int it;
for (it = 0; it < mmapped_areas->nlists; ++it)
{
list *l = mmapped_areas->lists[it];
if (l != 0)
{
int li;
for (li = 0; li < l->nrecs; ++li)
{
mmap_record rec = l->recs[li];
if (rec.get_address () == addr)
{
int fd = l->fd;
fhandler_disk_file fh_paging_file (NULL);
fhandler_base *fh;
if (fd == -1 || fdtab.not_open (fd))
{
fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
fh = &fh_paging_file;
}
else
fh = fdtab[fd];
int ret = fh->msync (rec.get_handle (), addr, len, flags);
if (ret)
syscall_printf ("%d = msync(): %E", ret);
else
syscall_printf ("0 = msync()");
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
return 0;
}
}
}
}
/* SUSv2: Return code if indicated memory was not mapped is ENOMEM. */
set_errno (ENOMEM);
syscall_printf ("-1 = msync(): ENOMEM");
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," msync");
return -1;
}
/*
* Base implementation:
*
* `mmap' returns ENODEV as documented in SUSv2.
* In contrast to the global function implementation, the member function
* `mmap' has to return the mapped base address in `addr' and the handle to
* the mapping object as return value. In case of failure, the fhandler
* mmap has to close that handle by itself and return INVALID_HANDLE_VALUE.
*
* `munmap' and `msync' get the handle to the mapping object as first parameter
* additionally.
*/
HANDLE
fhandler_base::mmap (caddr_t *addr, size_t len, DWORD access,
int flags, off_t off)
{
set_errno (ENODEV);
return INVALID_HANDLE_VALUE;
}
int
fhandler_base::munmap (HANDLE h, caddr_t addr, size_t len)
{
set_errno (ENODEV);
return -1;
}
int
fhandler_base::msync (HANDLE h, caddr_t addr, size_t len, int flags)
{
set_errno (ENODEV);
return -1;
}
/* Implementation for disk files. */
HANDLE
fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
int flags, off_t off)
{
DWORD protect;
if (access & FILE_MAP_COPY)
protect = PAGE_WRITECOPY;
else if (access & FILE_MAP_WRITE)
protect = PAGE_READWRITE;
else
protect = PAGE_READONLY;
HANDLE h = CreateFileMapping (get_handle(), &sec_none, protect, 0, len, NULL);
if (h == 0)
{
__seterrno ();
syscall_printf ("-1 = mmap(): CreateFileMapping failed with %E");
return INVALID_HANDLE_VALUE;
}
void *base = MapViewOfFileEx (h, access, 0, off, len,
(flags & MAP_FIXED) ? addr : NULL);
if (!base || ((flags & MAP_FIXED) && base != addr))
{
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
CloseHandle (h);
return INVALID_HANDLE_VALUE;
}
*addr = (caddr_t) base;
return h;
}
int
fhandler_disk_file::munmap (HANDLE h, caddr_t addr, size_t len)
{
UnmapViewOfFile (addr);
CloseHandle (h);
return 0;
}
int
fhandler_disk_file::msync (HANDLE h, caddr_t addr, size_t len, int flags)
{
if (FlushViewOfFile (addr, len) == 0) if (FlushViewOfFile (addr, len) == 0)
{ {
syscall_printf ("-1 = msync: %E");
__seterrno (); __seterrno ();
return -1; return -1;
} }
syscall_printf ("0 = msync");
return 0; return 0;
} }