From a8744157214a302d84c8959b1ae99abe3ae2d7d2 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sat, 17 Jul 2010 16:24:39 +0200 Subject: Remove `serverboot'; fix "make dist" in `mach-defpager'. * serverboot/default_pager.c, serverboot/kalloc.c, serverboot/queue.h, serverboot/wiring.c, serverboot/wiring.h: Move to `mach-defpager/'. * serverboot/Makefile, serverboot/assert.h, serverboot/bootstrap.c, serverboot/bunzip2.c, serverboot/def_pager_setup.c, serverboot/defs.h, serverboot/dir.h, serverboot/disk_inode.h, serverboot/disk_inode_ffs.h, serverboot/elf-load.c, serverboot/exec.c, serverboot/ext2_file_io.c, serverboot/ffs_compat.c, serverboot/ffs_compat.h, serverboot/ffs_file_io.c, serverboot/file_io.c, serverboot/file_io.h, serverboot/fs.h, serverboot/gets.c, serverboot/gunzip.c, serverboot/load.c, serverboot/mach-exec.h, serverboot/minix_ffs_compat.c, serverboot/minix_ffs_compat.h, serverboot/minix_file_io.c, serverboot/minix_fs.h, serverboot/minix_super.h, serverboot/panic.c, serverboot/strfcns.c: Remove. * mach-defpager/Makefile (LCLHDRS): New variable. (vpath): Remove. (CPPFLAGS): Remove `-I$(srcdir)/../serverboot'. * mach-defpager/setup.c (page_aligned): Make public. --- mach-defpager/kalloc.c | 291 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 mach-defpager/kalloc.c (limited to 'mach-defpager/kalloc.c') diff --git a/mach-defpager/kalloc.c b/mach-defpager/kalloc.c new file mode 100644 index 00000000..28c0b55e --- /dev/null +++ b/mach-defpager/kalloc.c @@ -0,0 +1,291 @@ +/* + * Mach Operating System + * Copyright (c) 1993-1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * File: kern/kalloc.c + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * General kernel memory allocator. This allocator is designed + * to be used by the kernel to manage dynamic memory fast. + */ + +#include +#include /* for spin locks */ +#include /* for malloc_hook/free_hook */ + +static void init_hook (void); +static void *malloc_hook (size_t size, const void *caller); +static void free_hook (void *ptr, const void *caller); + +void (*__malloc_initialize_hook) (void) = init_hook; + + +#define DEBUG + +/* + * All allocations of size less than kalloc_max are rounded to the + * next highest power of 2. + */ +vm_size_t kalloc_max; /* max before we use vm_allocate */ +#define MINSIZE 4 /* minimum allocation size */ + +struct free_list { + spin_lock_t lock; + vm_offset_t head; /* head of free list */ +#ifdef DEBUG + int count; +#endif /*DEBUG*/ +}; + +#define KLIST_MAX 13 + /* sizes: 4, 8, 16, 32, 64, + 128, 256, 512, 1024, + 2048, 4096, 8192, 16384 */ +struct free_list kfree_list[KLIST_MAX]; + +spin_lock_t kget_space_lock; +vm_offset_t kalloc_next_space = 0; +vm_offset_t kalloc_end_of_space = 0; + +vm_size_t kalloc_wasted_space = 0; + +boolean_t kalloc_initialized = FALSE; + +/* + * Initialize the memory allocator. This should be called only + * once on a system wide basis (i.e. first processor to get here + * does the initialization). + * + * This initializes all of the zones. + */ + +void kalloc_init(void) +{ + vm_offset_t min, max; + vm_size_t size; + register int i; + + /* + * Support free lists for items up to vm_page_size or + * 16Kbytes, whichever is less. + */ + + if (vm_page_size > 16*1024) + kalloc_max = 16*1024; + else + kalloc_max = vm_page_size; + + for (i = 0; i < KLIST_MAX; i++) { + spin_lock_init(&kfree_list[i].lock); + kfree_list[i].head = 0; + } + spin_lock_init(&kget_space_lock); + + /* + * Do not allocate memory at address 0. + */ + kalloc_next_space = vm_page_size; + kalloc_end_of_space = vm_page_size; +} + +/* + * Contiguous space allocator for items of less than a page size. + */ +vm_offset_t kget_space(vm_offset_t size) +{ + vm_size_t space_to_add; + vm_offset_t new_space = 0; + vm_offset_t addr; + + spin_lock(&kget_space_lock); + while (kalloc_next_space + size > kalloc_end_of_space) { + /* + * Add at least one page to allocation area. + */ + space_to_add = round_page(size); + + if (new_space == 0) { + /* + * Unlock and allocate memory. + * Try to make it contiguous with the last + * allocation area. + */ + spin_unlock(&kget_space_lock); + + new_space = kalloc_end_of_space; + if (vm_map(mach_task_self(), + &new_space, space_to_add, (vm_offset_t) 0, TRUE, + MEMORY_OBJECT_NULL, (vm_offset_t) 0, FALSE, + VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT) + != KERN_SUCCESS) + return 0; + wire_memory(new_space, space_to_add, + VM_PROT_READ|VM_PROT_WRITE); + spin_lock(&kget_space_lock); + continue; + } + + /* + * Memory was allocated in a previous iteration. + * Check whether the new region is contiguous with the + * old one. + */ + if (new_space != kalloc_end_of_space) { + /* + * Throw away the remainder of the old space, + * and start a new one. + */ + kalloc_wasted_space += + kalloc_end_of_space - kalloc_next_space; + kalloc_next_space = new_space; + } + kalloc_end_of_space = new_space + space_to_add; + + new_space = 0; + } + + addr = kalloc_next_space; + kalloc_next_space += size; + spin_unlock(&kget_space_lock); + + if (new_space != 0) + (void) vm_deallocate(mach_task_self(), new_space, space_to_add); + + return addr; +} + +void *kalloc(vm_size_t size) +{ + register vm_size_t allocsize; + vm_offset_t addr; + register struct free_list *fl; + + if (!kalloc_initialized) { + kalloc_init(); + kalloc_initialized = TRUE; + } + + /* compute the size of the block that we will actually allocate */ + + allocsize = size; + if (size < kalloc_max) { + allocsize = MINSIZE; + fl = kfree_list; + while (allocsize < size) { + allocsize <<= 1; + fl++; + } + } + + /* + * If our size is still small enough, check the queue for that size + * and allocate. + */ + + if (allocsize < kalloc_max) { + spin_lock(&fl->lock); + if ((addr = fl->head) != 0) { + fl->head = *(vm_offset_t *)addr; +#ifdef DEBUG + fl->count--; +#endif + spin_unlock(&fl->lock); + } + else { + spin_unlock(&fl->lock); + addr = kget_space(allocsize); + } + } + else { + if (vm_allocate(mach_task_self(), &addr, allocsize, TRUE) + != KERN_SUCCESS) + addr = 0; + } + return (void *) addr; +} + +void +kfree( void *data, + vm_size_t size) +{ + register vm_size_t freesize; + register struct free_list *fl; + + freesize = size; + if (size < kalloc_max) { + freesize = MINSIZE; + fl = kfree_list; + while (freesize < size) { + freesize <<= 1; + fl++; + } + } + + if (freesize < kalloc_max) { + spin_lock(&fl->lock); + *(vm_offset_t *)data = fl->head; + fl->head = (vm_offset_t) data; +#ifdef DEBUG + fl->count++; +#endif + spin_unlock(&fl->lock); + } + else { + (void) vm_deallocate(mach_task_self(), (vm_offset_t)data, freesize); + } +} + +static void +init_hook (void) +{ + __malloc_hook = malloc_hook; + __free_hook = free_hook; +} + +static void * +malloc_hook (size_t size, const void *caller) +{ + return (void *) kalloc ((vm_size_t) size); +} + +static void +free_hook (void *ptr, const void *caller) +{ + /* Just ignore harmless attempts at cleanliness. */ + /* panic("free not implemented"); */ +} + +void malloc_fork_prepare() +{ +} + +void malloc_fork_parent() +{ +} + +void malloc_fork_child() +{ +} -- cgit v1.2.3 From 66b99a27c644f2bbfbc2feda679415ce80c77a62 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sat, 5 Nov 2011 21:46:15 +0100 Subject: mach-defpager: Declare `__malloc_initialize_hook' as volatile. * mach-defpager/kalloc.c (__MALLOC_HOOK_VOLATILE): New macro. --- mach-defpager/kalloc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'mach-defpager/kalloc.c') diff --git a/mach-defpager/kalloc.c b/mach-defpager/kalloc.c index 28c0b55e..5d91aceb 100644 --- a/mach-defpager/kalloc.c +++ b/mach-defpager/kalloc.c @@ -40,7 +40,13 @@ static void init_hook (void); static void *malloc_hook (size_t size, const void *caller); static void free_hook (void *ptr, const void *caller); -void (*__malloc_initialize_hook) (void) = init_hook; +/* GNU libc 2.14 defines this macro to declare hook variables as volatile. + Define it as empty for older libc versions. */ +#ifndef __MALLOC_HOOK_VOLATILE +# define __MALLOC_HOOK_VOLATILE +#endif + +void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = init_hook; #define DEBUG -- cgit v1.2.3 From d4b231dd9f874076c62f35590a9f6b93ca6481d7 Mon Sep 17 00:00:00 2001 From: Maksym Planeta Date: Sun, 8 Jan 2012 14:51:42 +0200 Subject: Remove warnings during compilation. * mach-defpager/kalloc.c: Added missing prototypes, headers, types. * mach-defpager/wiring.c: Likewise. * mach-defpager/default_pager.c: Likewise. * mach-defpager/main.c: Likewise. * mach-defpager/setup.c: Likewise. (S_default_pager_paging_storage): Fix wrong calling of kfree. * mach-defpager/kalloc.h: New file with prototypes from kalloc.c. * mach-defpager/default_pager.h: New file with prototypes from default_pager.c. * mach-defpager/Makefile (LCLHDRS): Add new header files. --- mach-defpager/Makefile | 2 +- mach-defpager/default_pager.c | 22 ++++++++++++++-------- mach-defpager/default_pager.h | 43 +++++++++++++++++++++++++++++++++++++++++++ mach-defpager/kalloc.c | 2 ++ mach-defpager/kalloc.h | 30 ++++++++++++++++++++++++++++++ mach-defpager/main.c | 2 ++ mach-defpager/setup.c | 12 +++++++----- mach-defpager/wiring.c | 1 + 8 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 mach-defpager/default_pager.h create mode 100644 mach-defpager/kalloc.h (limited to 'mach-defpager/kalloc.c') diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile index 51476552..9a4b7edf 100644 --- a/mach-defpager/Makefile +++ b/mach-defpager/Makefile @@ -27,7 +27,7 @@ OBJS := $(SRCS:.c=.o) \ $(addsuffix Server.o,\ memory_object default_pager memory_object_default exc) \ default_pager_replyUser.o -LCLHDRS := file_io.h queue.h wiring.h +LCLHDRS := file_io.h queue.h wiring.h kalloc.h default_pager.h HURDLIBS:= threads LDFLAGS += -static diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c index 07274553..4b5aff89 100644 --- a/mach-defpager/default_pager.c +++ b/mach-defpager/default_pager.c @@ -44,9 +44,12 @@ #include #include +#include +#include #include #include +#include #include @@ -54,8 +57,6 @@ #define debug 0 -extern void *kalloc(); - static char my_name[] = "(default pager):"; static struct mutex printf_lock = MUTEX_INITIALIZER; @@ -144,9 +145,10 @@ void set_partition_of(x, p) * Saves space, filenames can be long. */ unsigned int -part_id(const unsigned char *name) +part_id(const char *name) { - register unsigned int len, id, xorid; + register unsigned int id, xorid; + size_t len; len = strlen(name); id = xorid = 0; @@ -157,6 +159,7 @@ part_id(const unsigned char *name) return (id << 8) | xorid; } +void partition_init() { mutex_init(&all_partitions.lock); @@ -513,6 +516,7 @@ ddprintf ("choose_partition(%x,%d,%d)\n",size,cur_part,i); vm_offset_t pager_alloc_page(pindex, lock_it) p_index_t pindex; + boolean_t lock_it; { register int bm_e; register int bit; @@ -577,6 +581,7 @@ void pager_dealloc_page(pindex, page, lock_it) p_index_t pindex; register vm_offset_t page; + boolean_t lock_it; { register partition_t part; register int bit, bm_e; @@ -1185,7 +1190,7 @@ pager_read_offset(pager, offset) /* * Release a single disk block. */ -pager_release_offset(pager, offset) +void pager_release_offset(pager, offset) register dpager_t pager; vm_offset_t offset; { @@ -3792,6 +3797,7 @@ dprintf("bmd %x md %x\n", bootstrap_master_device_port, mdport); return kr; } +kern_return_t default_pager_register_fileserver(pager, fileserver) mach_port_t pager; mach_port_t fileserver; @@ -3808,7 +3814,7 @@ default_pager_register_fileserver(pager, fileserver) /* * When things do not quite workout... */ -no_paging_space(out_of_memory) +void no_paging_space(out_of_memory) boolean_t out_of_memory; { static char here[] = "%s *** NOT ENOUGH PAGING SPACE ***"; @@ -3818,7 +3824,7 @@ no_paging_space(out_of_memory) panic(here, my_name); } -overcommitted(got_more_space, space) +void overcommitted(got_more_space, space) boolean_t got_more_space; vm_size_t space; /* in pages */ { @@ -3859,7 +3865,7 @@ overcommitted(got_more_space, space) #endif } -paging_space_info(totp, freep) +void paging_space_info(totp, freep) vm_size_t *totp, *freep; { register vm_size_t total, free; diff --git a/mach-defpager/default_pager.h b/mach-defpager/default_pager.h new file mode 100644 index 00000000..f4cdda64 --- /dev/null +++ b/mach-defpager/default_pager.h @@ -0,0 +1,43 @@ +/* Backing store access callbacks for Hurd version of Mach default pager. + Copyright (C) 2012 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Prototypes for working with paging partitions and files */ + +#ifndef _DEFAULT_PAGER_H_ +#define _DEFAULT_PAGER_H_ + +#include + +void partition_init(); + +void create_paging_partition(const char *name, struct file_direct *fdp, + int isa_file, int linux_signature); +kern_return_t destroy_paging_partition(char *name, void **pp_private); + +kern_return_t add_paging_file(mach_port_t master_device_port, + char *file_name, int linux_signature); +kern_return_t remove_paging_file (char *file_name); + +void paging_space_info(vm_size_t *totp, vm_size_t *freep); +void no_paging_space(boolean_t out_of_memory); +void overcommitted(boolean_t got_more_space, vm_size_t space); + +void panic (const char *fmt, ...); + +#endif /* _DEFAULT_PAGER_H_ */ diff --git a/mach-defpager/kalloc.c b/mach-defpager/kalloc.c index 5d91aceb..d9b18c02 100644 --- a/mach-defpager/kalloc.c +++ b/mach-defpager/kalloc.c @@ -36,6 +36,8 @@ #include /* for spin locks */ #include /* for malloc_hook/free_hook */ +#include "wiring.h" + static void init_hook (void); static void *malloc_hook (size_t size, const void *caller); static void free_hook (void *ptr, const void *caller); diff --git a/mach-defpager/kalloc.h b/mach-defpager/kalloc.h new file mode 100644 index 00000000..8f52f1a5 --- /dev/null +++ b/mach-defpager/kalloc.h @@ -0,0 +1,30 @@ +/* Backing store access callbacks for Hurd version of Mach default pager. + Copyright (C) 2012 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * General kernel memory allocator. + */ + +#ifndef _KALLOC_H_ +#define _KALLOC_H_ + +void *kalloc (vm_size_t size); +void kfree (void *data, vm_size_t size); + +#endif /* _KALLOC_H_ */ diff --git a/mach-defpager/main.c b/mach-defpager/main.c index 0be9dee1..c44c86cb 100644 --- a/mach-defpager/main.c +++ b/mach-defpager/main.c @@ -31,6 +31,7 @@ #include #include #include +#include /* XXX */ #include @@ -42,6 +43,7 @@ #include /* XXX */ +#include extern vm_size_t cthread_wait_stack_size; diff --git a/mach-defpager/setup.c b/mach-defpager/setup.c index 05c19f33..080b0fa6 100644 --- a/mach-defpager/setup.c +++ b/mach-defpager/setup.c @@ -22,6 +22,11 @@ #include #include #include +#include +#include + +#include +#include #include "file_io.h" #include "default_pager_S.h" @@ -32,9 +37,6 @@ int page_aligned (vm_offset_t num) return trunc_page (num) == num; } -/* From serverboot/kalloc.c. */ -extern void *kalloc (vm_size_t); - extern mach_port_t default_pager_default_port; /* default_pager.c */ kern_return_t @@ -87,7 +89,7 @@ S_default_pager_paging_storage (mach_port_t pager, fdp->runs[i].length = runs[i + 1]; if (fdp->runs[i].start + fdp->runs[i].length > devsize) { - kfree (fdp); + kfree (fdp, offsetof (struct file_direct, runs[nrun])); return EINVAL; } fdp->fd_size += fdp->runs[i].length; @@ -295,7 +297,7 @@ remove_paging_file (char *file_name) struct file_direct *fdp = 0; kern_return_t kr; - kr = destroy_paging_partition(file_name, &fdp); + kr = destroy_paging_partition(file_name, (void **)&fdp); if (kr == KERN_SUCCESS && fdp != 0) { mach_port_deallocate (mach_task_self (), fdp->device); diff --git a/mach-defpager/wiring.c b/mach-defpager/wiring.c index 585a3075..8bf49934 100644 --- a/mach-defpager/wiring.c +++ b/mach-defpager/wiring.c @@ -29,6 +29,7 @@ #include #include #include +#include "default_pager.h" mach_port_t this_task; /* our task */ mach_port_t priv_host_port = MACH_PORT_NULL; -- cgit v1.2.3