#include <k/core.h>
#include <k/def.h>
/* heapa.c - kmheapa() "heap alloc"
 * ~ lexi hale <lexi@hale.su>
 * kmheapa() allocates a pointer on the heap à la libc malloc()
 * see also: kmheapf() "heap free"
 */

/* we define all platform functions here,
 * whether or not they're for the correct
 * platform - only the ones actually called
 * by the generated code will be linked,
 * linker errors are our friend here! */
extern void* kmem_posix_mmap(void* addr,
		unsigned long sz, unsigned long prot, unsigned long flags,
		unsigned long fd, unsigned long off);

enum posix_prot {
	posix_prot_none  = 0,
	posix_prot_read  = 1 << 0,
	posix_prot_write = 1 << 1,
	posix_prot_exec  = 1 << 2
};

enum posix_map {
	posix_map_shared  = 1,
	posix_map_private = 2
};

enum posix_flag {
	posix_flag_fixed     = 0x10,
	posix_flag_anonymous = 0x20,

	/* platform flags */
	posix_flag_linux_hugetlb = 0x40000
};

void* kmheapa(sz len) {
	/* allocate an object on the heap and return
	 * a pointer, or NULL if the allocation failed. */
	void* val;

#	ifdef KFenv_posix
 	   /* posix APIs - we've got it easy */
		val = kmem_posix_mmap(null, len, posix_prot_read | posix_prot_write,
				posix_flag_anonymous, -1, 0);
		/* impl note: while per manpage fd is "ignored"
		 * for MAP_ANONYMOUS, "some implementations" require
		 * a value of -1 */

		if (val == (void*) -1) return null;
		/* worth retrieving errno? discuss */

#	else
 	   Knoimpl(kmheapa,KVos);
#		error missing implementation
#	endif

	return val;
}
