BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / master / memory / mmap.c

// Related

Nucleus

Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
/*
 * This file implements the mmap() routine.  It takes the parameters and sets up
 * the relevant memory regions.  If no address is passed it will find the first
 * available one and use it.
 */

#include <sys/errno.h>
#include <sys/mman.h>
#include <nucleus/memory.h>
#include <nucleus/object.h>
#include <nucleus/task.h>
#include <nucleus/vfs.h>
#include "namespace.h"

/* Map an object into memory */
void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
	VMRegion *region = NULL;

	/* Find gap big enough */
	if (!addr) {
		VMRegion *head;
		foreach (current->vm->regions, head) {
			if (region && (head->start - region->end >= len))
				break;
			region = head;
		}
		if (region && region->end + len >= 0xDFC00000)
			return (void *) -ENOMEM;
		addr = (void *) region->end;
	}

	/* Map anonymous memory */
	if (flags & MAP_ANONYMOUS) {
		region = vm_create_region(addr, len, prot, flags, 0, NULL);
		goto end;
	}

	/* Map a file */
	if (fildes < 0 || fildes >= NFILES)
		return (void *) -EBADF;
	File *file = get_file_by_fd(fildes);
	if (!file)
		return (void *) -EBADF;
	region = vm_create_region(addr, len, prot, flags, off, file);
end:
	if (!region)
		return (void *) -ENOMEM;
	void *start = (void *) region->start;
	put(region);
	return start;
}