This is an automated email from the git hooks/post-receive script. sthibault pushed a commit to branch dde in repository hurd.
commit 2d2c723fab657b556c8ffd8cffe35386c8ccf205 Author: Samuel Thibault <[email protected]> Date: Thu Jan 14 00:05:18 2016 +0000 Drop devnode and libhurd-slab, now upstream --- devnode/Makefile | 30 --- devnode/README | 25 --- devnode/devnode.c | 359 ---------------------------------- devnode/mig-mutate.h | 27 --- devnode/util.h | 40 ---- libhurd-slab/Makefile | 33 ---- libhurd-slab/slab.c | 518 -------------------------------------------------- libhurd-slab/slab.h | 338 -------------------------------- 8 files changed, 1370 deletions(-) diff --git a/devnode/Makefile b/devnode/Makefile deleted file mode 100644 index 9529fa7..0000000 --- a/devnode/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 2008 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 the GNU Hurd; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -dir := devnode -makemode := server - -SRCS = devnode.c -LCLHDRS = util.h -HURDLIBS = ports trivfs fshelp shouldbeinlibc -target = devnode -MIGSTUBS = deviceServer.o notifyServer.o -MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h -device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name" -OBJS = $(SRCS:.c=.o) $(MIGSTUBS) - -include ../Makeconf diff --git a/devnode/README b/devnode/README deleted file mode 100644 index 90ca27c..0000000 --- a/devnode/README +++ /dev/null @@ -1,25 +0,0 @@ -[Introduction] - -devnode is a translator that creates the device file for the kernel device. It provides another way for other programs to open the kernel device. -The device file should be created in /dev with the device name as its file name, so clients can find the device file easily. -Clients need to get the port to the devnode translator by calling file_name_lookup() and uses this port as a master device port to open the device by calling device_open(). The device name used in device_open() is specified by '-n' option of devnode. - - -[Usage] - -Usage: devnode [OPTION...] device -Hurd devnode translator. - - -n, --name=DEVICENAME Accept open from clients only with DEVICENAME - -M, --master_device=FILE Get a pseudo master device port - -?, --help Give this help list - --usage Give a short usage message - -V, --version Print program version - -The '-n' option specifies the device name used by clients in device_open(). It can be optional. If it's specified, clients must use the name to open the device. Otherwise, every device name used by clients in device_open() is acceptable. -The '-M' option specifies the file where devnode can get the master device port. This option can be useful to open the virtual interface created by eth-multiplexer, for example. - - -[Internal] - -devnode is very simple. It implements the server side functions in device.defs, so it can receive the request of opening a device from clients. Only ds_device_open is actually implemented, which opens the device and returns the port to the device. Normally, devnode shouldn't get other requests. diff --git a/devnode/devnode.c b/devnode/devnode.c deleted file mode 100644 index 2802471..0000000 --- a/devnode/devnode.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Zheng Da. - - 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 the GNU Hurd; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* - * This program is a translator that sits on the top of the network - * interface and helps socket servers open the interface. - */ - -#include <argp.h> -#include <argz.h> -#include <errno.h> -#include <error.h> -#include <stddef.h> -#include <fcntl.h> - -#include <hurd.h> -#include <mach.h> -#include <device/device.h> -#include <hurd/trivfs.h> -#include <hurd/ports.h> -#include <version.h> - -#include "device_S.h" -#include "notify_S.h" -#include "util.h" - -/* The name of the network interface that the translator sits on. */ -static char *device_name; -/* The device name used by the socket servers. */ -static char *user_device_name; -static char *master_file; -/* The master device port for opening the interface. */ -static mach_port_t master_device; - -const char *argp_program_version = STANDARD_HURD_VERSION (devnode); - -static const char args_doc[] = "device"; -static const char doc[] = "Hurd devnode translator."; -static const struct argp_option options[] = -{ - {"name", 'n', "DEVICENAME", 0, - "Define the device name used by clients in device_open()", 2}, - {"master-device", 'M', "FILE", 0, - "Get a pseudo master device port", 3}, - {0} -}; - -/* Port bucket we service requests on. */ -struct port_bucket *port_bucket; - -/* Trivfs hooks. */ -int trivfs_fstype = FSTYPE_MISC; -int trivfs_fsid = 0; -int trivfs_support_read = 0; -int trivfs_support_write = 0; -int trivfs_support_exec = 0; -int trivfs_allow_open = O_READ | O_WRITE; - -/* Our port classes. */ -struct port_class *trivfs_protid_class; -struct port_class *trivfs_cntl_class; - -static int -devnode_demuxer (mach_msg_header_t *inp, - mach_msg_header_t *outp) -{ - mig_routine_t routine; - if ((routine = device_server_routine (inp)) || - (routine = notify_server_routine (inp)) || - (routine = NULL, trivfs_demuxer (inp, outp))) - { - if (routine) - (*routine) (inp, outp); - return TRUE; - } - else - return FALSE; -} - -/* Implementation of notify interface */ -kern_return_t -do_mach_notify_port_deleted (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_msg_accepted (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_port_destroyed (struct port_info *pi, - mach_port_t port) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_no_senders (struct port_info *pi, - mach_port_mscount_t mscount) -{ - return ports_do_mach_notify_no_senders (pi, mscount); -} - -kern_return_t -do_mach_notify_send_once (struct port_info *pi) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_dead_name (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -/* Implementation of device interface */ -kern_return_t -ds_device_open (mach_port_t master_port, mach_port_t reply_port, - mach_msg_type_name_t reply_portPoly, - dev_mode_t mode, dev_name_t name, mach_port_t *device, - mach_msg_type_name_t *devicetype) -{ - error_t err; - - devnode_debug ("ds_device_open is called\n"); - - if ((user_device_name && strcmp (user_device_name, name)) - || device_name == NULL) - return D_NO_SUCH_DEVICE; - - if (master_file != NULL) - { - if (master_device != MACH_PORT_NULL) - mach_port_deallocate (mach_task_self (), master_device); - - master_device = file_name_lookup (master_file, 0, 0); - if (master_device == MACH_PORT_NULL) - error (1, errno, "file_name_lookup"); - } - - err = device_open (master_device, mode, device_name, device); - *devicetype = MACH_MSG_TYPE_MOVE_SEND; - return err; -} - -kern_return_t -ds_device_close (device_t device) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_write (device_t device, mach_port_t reply_port, - mach_msg_type_name_t reply_type, dev_mode_t mode, - recnum_t recnum, io_buf_ptr_t data, size_t datalen, - int *bytes_written) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_write_inband (device_t device, mach_port_t reply_port, - mach_msg_type_name_t reply_type, dev_mode_t mode, - recnum_t recnum, io_buf_ptr_inband_t data, - size_t datalen, int *bytes_written) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_read (device_t device, mach_port_t reply_port, - mach_msg_type_name_t reply_type, dev_mode_t mode, - recnum_t recnum, int bytes_wanted, - io_buf_ptr_t *data, size_t *datalen) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_read_inband (device_t device, mach_port_t reply_port, - mach_msg_type_name_t reply_type, dev_mode_t mode, - recnum_t recnum, int bytes_wanted, - io_buf_ptr_inband_t data, size_t *datalen) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_map (device_t device, vm_prot_t prot, vm_offset_t offset, - vm_size_t size, memory_object_t *pager, int unmap) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_set_status (device_t device, dev_flavor_t flavor, - dev_status_t status, size_t statuslen) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_get_status (device_t device, dev_flavor_t flavor, - dev_status_t status, size_t *statuslen) -{ - return D_INVALID_OPERATION; -} - -kern_return_t -ds_device_set_filter (device_t device, mach_port_t receive_port, - int priority, filter_array_t filter, size_t filterlen) -{ - return D_INVALID_OPERATION; -} - -error_t -trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) -{ - error_t err = 0; - -#define ADD_OPT(fmt, args...) \ - do { char buf[100]; \ - if (! err) { \ - snprintf (buf, sizeof buf, fmt , ##args); \ - err = argz_add (argz, argz_len, buf); } } while (0) - - if (user_device_name) - ADD_OPT ("--name=%s", user_device_name); - if (master_file) - ADD_OPT ("--master-device=%s", master_file); - - ADD_OPT ("%s", device_name); - -#undef ADD_OPT - return err; -} - -void -trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat) -{ -} - -error_t -trivfs_goaway (struct trivfs_control *fsys, int flags) -{ - int count; - - /* Stop new requests. */ - ports_inhibit_class_rpcs (trivfs_cntl_class); - ports_inhibit_class_rpcs (trivfs_protid_class); - - count = ports_count_class (trivfs_protid_class); - devnode_debug ("the number of ports alive: %d\n", count); - - if (count && !(flags & FSYS_GOAWAY_FORCE)) - { - /* We won't go away, so start things going again... */ - ports_enable_class (trivfs_protid_class); - ports_resume_class_rpcs (trivfs_cntl_class); - ports_resume_class_rpcs (trivfs_protid_class); - return EBUSY; - } - - mach_port_deallocate (mach_task_self (), master_device); - devnode_debug ("the translator is gone away\n"); - exit (0); -} - -static error_t -parse_opt (int opt, char *arg, struct argp_state *state) -{ - switch (opt) - { - case 'M': - master_file = arg; - master_device = file_name_lookup (arg, 0, 0); - if (master_device == MACH_PORT_NULL) - error (1, errno, "file_name_lookup"); - break; - case 'n': - user_device_name = arg; - break; - case ARGP_KEY_ARG: - device_name = arg; - break; - case ARGP_KEY_ERROR: - case ARGP_KEY_SUCCESS: - case ARGP_KEY_INIT: - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -int -main (int argc, char *argv[]) -{ - error_t err; - mach_port_t bootstrap; - struct trivfs_control *fsys; - const struct argp argp = { options, parse_opt, args_doc, doc }; - - port_bucket = ports_create_bucket (); - trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0); - trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0); - - argp_parse (&argp, argc, argv, 0, 0, 0); - - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (1, 0, "must be started as a translator"); - - if (master_device == MACH_PORT_NULL) - { - err = get_privileged_ports (0, &master_device); - if (err) - error (1, err, "get_privileged_ports"); - } - - /* Reply to our parent. */ - err = trivfs_startup (bootstrap, 0, - trivfs_cntl_class, port_bucket, - trivfs_protid_class, port_bucket, &fsys); - mach_port_deallocate (mach_task_self (), bootstrap); - if (err) - error (1, err, "Contacting parent"); - - /* Launch. */ - do - { - ports_manage_port_operations_one_thread (port_bucket, - devnode_demuxer, 0); - } while (trivfs_goaway (fsys, 0)); - return 0; -} diff --git a/devnode/mig-mutate.h b/devnode/mig-mutate.h deleted file mode 100644 index 0656014..0000000 --- a/devnode/mig-mutate.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2014 Free Software Foundation, Inc. - Written by Justus Winter. - - 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 the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ - -#define NOTIFY_INTRAN \ - port_info_t begin_using_port_info_port (mach_port_t) -#define NOTIFY_INTRAN_PAYLOAD \ - port_info_t begin_using_port_info_payload -#define NOTIFY_DESTRUCTOR \ - end_using_port_info (port_info_t) -#define NOTIFY_IMPORTS \ - import "libports/mig-decls.h"; diff --git a/devnode/util.h b/devnode/util.h deleted file mode 100644 index f3cc3c1..0000000 --- a/devnode/util.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2008 Free Software Foundation, Inc. - Written by Zheng Da. - - 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 the GNU Hurd; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef UTIL_H -#define UTIL_H - -#include <stdio.h> - -#ifdef DEBUG - -#define devnode_debug(format, ...) do \ -{ \ - fprintf (stderr , "devnode: " format, ## __VA_ARGS__);\ - fflush (stderr); \ -} while (0) - -#else - -#define devnode_debug(format, ...) do {} while (0) - -#endif - -#endif diff --git a/libhurd-slab/Makefile b/libhurd-slab/Makefile deleted file mode 100644 index 925f70c..0000000 --- a/libhurd-slab/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (C) 1994,95,96,97,98,99,2000,01,02,2005 Free Software Foundation, Inc. -# -# This program 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. -# -# This program 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. - -dir := libhurd-slab -makemode := library - -libname = libhurd-slab -SRCS= slab.c -LCLHDRS = slab.h -installhdrs = slab.h - -MIGSTUBS = -OBJS = $(sort $(SRCS:.c=.o) $(MIGSTUBS)) - -OTHERLIBS = -lpthread - -MIGCOMSFLAGS = - -include ../Makeconf diff --git a/libhurd-slab/slab.c b/libhurd-slab/slab.c deleted file mode 100644 index 5a12a43..0000000 --- a/libhurd-slab/slab.c +++ /dev/null @@ -1,518 +0,0 @@ -/* Copyright (C) 2003, 2005 Free Software Foundation, Inc. - Written by Johan Rydberg. - - This file is part of the GNU Hurd. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This program 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <errno.h> -#include <sys/mman.h> -#include <assert.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <stdint.h> - -#include "slab.h" - -#define SLAB_PAGES 4 - - -/* Number of pages the slab allocator has allocated. */ -static int __hurd_slab_nr_pages; - - -/* Buffer control structure. Lives at the end of an object. If the - buffer is allocated, SLAB points to the slab to which it belongs. - If the buffer is free, NEXT points to next buffer on free list. */ -union hurd_bufctl -{ - union hurd_bufctl *next; - struct hurd_slab *slab; -}; - - -/* When the allocator needs to grow a cache, it allocates a slab. A - slab consists of one or more pages of memory, split up into equally - sized chunks. */ -struct hurd_slab -{ - struct hurd_slab *next; - struct hurd_slab *prev; - - /* The reference counter holds the number of allocated chunks in - the slab. When the counter is zero, all chunks are free and - the slab can be relinquished. */ - int refcount; - - /* Single linked list of free buffers in the slab. */ - union hurd_bufctl *free_list; -}; - -/* Allocate a buffer in *PTR of size SIZE which must be a power of 2 - and self aligned (i.e. aligned on a SIZE byte boundary) for slab - space SPACE. Return 0 on success, an error code on failure. */ -static error_t -allocate_buffer (struct hurd_slab_space *space, size_t size, void **ptr) -{ - if (space->allocate_buffer) - return space->allocate_buffer (space->hook, size, ptr); - else - { - *ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); - if (*ptr == MAP_FAILED) - return errno; - else - return 0; - } -} - -/* Deallocate buffer BUFFER of size SIZE which was allocated for slab - space SPACE. Return 0 on success, an error code on failure. */ -static error_t -deallocate_buffer (struct hurd_slab_space *space, void *buffer, size_t size) -{ - if (space->deallocate_buffer) - return space->deallocate_buffer (space->hook, buffer, size); - else - { - if (munmap (buffer, size) == -1) - return errno; - else - return 0; - } -} - -/* Insert SLAB into the list of slabs in SPACE. SLAB is expected to - be complete (so it will be inserted at the end). */ -static void -insert_slab (struct hurd_slab_space *space, struct hurd_slab *slab) -{ - assert (slab->refcount == 0); - if (space->slab_first == 0) - space->slab_first = space->slab_last = slab; - else - { - space->slab_last->next = slab; - slab->prev = space->slab_last; - space->slab_last = slab; - } -} - - -/* Remove SLAB from list of slabs in SPACE. */ -static void -remove_slab (struct hurd_slab_space *space, struct hurd_slab *slab) -{ - if (slab != space->slab_first - && slab != space->slab_last) - { - slab->next->prev = slab->prev; - slab->prev->next = slab->next; - return; - } - if (slab == space->slab_first) - { - space->slab_first = slab->next; - if (space->slab_first) - space->slab_first->prev = NULL; - } - if (slab == space->slab_last) - { - if (slab->prev) - slab->prev->next = NULL; - space->slab_last = slab->prev; - } -} - - -/* Iterate through slabs in SPACE and release memory for slabs that - are complete (no allocated buffers). */ -static error_t -reap (struct hurd_slab_space *space) -{ - struct hurd_slab *s, *next, *new_first; - error_t err = 0; - - for (s = space->slab_first; s; s = next) - { - next = s->next; - - /* If the reference counter is zero there is no allocated - buffers, so it can be freed. */ - if (!s->refcount) - { - remove_slab (space, s); - - /* If there is a destructor it must be invoked for every - buffer in the slab. */ - if (space->destructor) - { - union hurd_bufctl *bufctl; - for (bufctl = s->free_list; bufctl; bufctl = bufctl->next) - { - void *buffer = (((void *) bufctl) - - (space->size - sizeof *bufctl)); - (*space->destructor) (space->hook, buffer); - } - } - /* The slab is located at the end of the page (with the buffers - in front of it), get address by masking with page size. - This frees the slab and all its buffers, since they live on - the same page. */ - err = deallocate_buffer (space, (void *) (((uintptr_t) s) - + sizeof (struct hurd_slab) - - space->slab_size), - space->slab_size); - if (err) - break; - __hurd_slab_nr_pages--; - } - } - - /* Even in the case of an error, first_free must be updated since - that slab may have been deallocated. */ - new_first = space->slab_first; - while (new_first) - { - if (new_first->refcount != space->full_refcount) - break; - new_first = new_first->next; - } - space->first_free = new_first; - - return err; -} - - -/* Initialize slab space SPACE. */ -static void -init_space (hurd_slab_space_t space) -{ - size_t size = space->requested_size + sizeof (union hurd_bufctl); - size_t alignment = space->requested_align; - - /* If SIZE is so big that one object can not fit into a page - something gotta be really wrong. */ - size = (size + alignment - 1) & ~(alignment - 1); - assert (size <= (space->slab_size - - sizeof (struct hurd_slab) - - sizeof (union hurd_bufctl))); - - space->size = size; - - /* Number of objects that fit into one page. Used to detect when - there are no free objects left in a slab. */ - space->full_refcount - = ((space->slab_size - sizeof (struct hurd_slab)) / size); - - /* FIXME: Notify pager's reap functionality about this slab - space. */ - - space->initialized = true; -} - - -/* SPACE has no more memory. Allocate new slab and insert it into the - list, repoint free_list and return possible error. */ -static error_t -grow (struct hurd_slab_space *space) -{ - error_t err; - struct hurd_slab *new_slab; - union hurd_bufctl *bufctl; - int nr_objs, i; - void *p; - - /* If the space has not yet been initialized this is the place to do - so. It is okay to test some fields such as first_free prior to - initialization since they will be a null pointer in any case. */ - if (!space->initialized) - init_space (space); - - err = allocate_buffer (space, space->slab_size, &p); - if (err) - return err; - - __hurd_slab_nr_pages++; - - new_slab = (p + space->slab_size - sizeof (struct hurd_slab)); - memset (new_slab, 0, sizeof (*new_slab)); - - /* Calculate the number of objects that the page can hold. - SPACE->size should be adjusted to handle alignment. */ - nr_objs = ((space->slab_size - sizeof (struct hurd_slab)) - / space->size); - - for (i = 0; i < nr_objs; i++, p += space->size) - { - /* Invoke constructor at object creation time, not when it is - really allocated (for faster allocation). */ - if (space->constructor) - { - error_t err = (*space->constructor) (space->hook, p); - if (err) - { - /* The allocated page holds both slab and memory - objects. Call the destructor for objects that has - been initialized. */ - for (bufctl = new_slab->free_list; bufctl; - bufctl = bufctl->next) - { - void *buffer = (((void *) bufctl) - - (space->size - sizeof *bufctl)); - (*space->destructor) (space->hook, buffer); - } - - deallocate_buffer (space, p, space->slab_size); - return err; - } - } - - /* The most activity is in front of the object, so it is most - likely to be overwritten if a freed buffer gets accessed. - Therefor, put the bufctl structure at the end of the - object. */ - bufctl = (p + space->size - sizeof *bufctl); - bufctl->next = new_slab->free_list; - new_slab->free_list = bufctl; - } - - /* Insert slab into the list of available slabs for this cache. The - only time a slab should be allocated is when there is no more - buffers, so it is safe to repoint first_free. */ - insert_slab (space, new_slab); - space->first_free = new_slab; - return 0; -} - - -/* Initialize the slab space SPACE. */ -error_t -hurd_slab_init (hurd_slab_space_t space, size_t size, size_t alignment, - hurd_slab_allocate_buffer_t allocate_buffer, - hurd_slab_deallocate_buffer_t deallocate_buffer, - hurd_slab_constructor_t constructor, - hurd_slab_destructor_t destructor, - void *hook) -{ - error_t err; - - /* Initialize all members to zero by default. */ - memset (space, 0, sizeof (struct hurd_slab_space)); - - if (!alignment) - /* FIXME: Is this a good default? Maybe eight (8) is better, - since several architectures require that double and friends are - eight byte aligned. */ - alignment = __alignof__ (void *); - - space->requested_size = size; - space->requested_align = alignment; - space->slab_size = getpagesize () * SLAB_PAGES; - - /* Testing the size here avoids an assertion in init_space. */ - size = size + sizeof (union hurd_bufctl); - size = (size + alignment - 1) & ~(alignment - 1); - if (size > (space->slab_size - sizeof (struct hurd_slab) - - sizeof (union hurd_bufctl))) - return EINVAL; - - err = pthread_mutex_init (&space->lock, NULL); - if (err) - return err; - - space->allocate_buffer = allocate_buffer; - space->deallocate_buffer = deallocate_buffer; - space->constructor = constructor; - space->destructor = destructor; - space->hook = hook; - - /* The remaining fields will be initialized by init_space. */ - return 0; -} - - -/* Create a new slab space with the given object size, alignment, - constructor and destructor. ALIGNMENT can be zero. */ -error_t -hurd_slab_create (size_t size, size_t alignment, - hurd_slab_allocate_buffer_t allocate_buffer, - hurd_slab_deallocate_buffer_t deallocate_buffer, - hurd_slab_constructor_t constructor, - hurd_slab_destructor_t destructor, - void *hook, - hurd_slab_space_t *r_space) -{ - hurd_slab_space_t space; - error_t err; - - space = malloc (sizeof (struct hurd_slab_space)); - if (!space) - return ENOMEM; - - err = hurd_slab_init (space, size, alignment, - allocate_buffer, deallocate_buffer, - constructor, destructor, hook); - if (err) - { - free (space); - return err; - } - - *r_space = space; - return 0; -} - - -/* Destroy all objects and the slab space SPACE. Returns EBUSY if - there are still allocated objects in the slab. */ -error_t -hurd_slab_destroy (hurd_slab_space_t space) -{ - error_t err; - - /* The caller wants to destroy the slab. It can not be destroyed if - there are any outstanding memory allocations. */ - pthread_mutex_lock (&space->lock); - err = reap (space); - if (err) - { - pthread_mutex_unlock (&space->lock); - return err; - } - - if (space->slab_first) - { - /* There are still slabs, i.e. there is outstanding allocations. - Return EBUSY. */ - pthread_mutex_unlock (&space->lock); - return EBUSY; - } - - /* FIXME: Remove slab space from pager's reap functionality. */ - - return 0; -} - - -/* Destroy all objects and the slab space SPACE. If there were no - outstanding allocations free the slab space. Returns EBUSY if - there are still allocated objects in the slab space. */ -error_t -hurd_slab_free (hurd_slab_space_t space) -{ - error_t err = hurd_slab_destroy (space); - if (err) - return err; - free (space); - return 0; -} - - -/* Allocate a new object from the slab space SPACE. */ -error_t -hurd_slab_alloc (hurd_slab_space_t space, void **buffer) -{ - error_t err; - union hurd_bufctl *bufctl; - - pthread_mutex_lock (&space->lock); - - /* If there is no slabs with free buffer, the cache has to be - expanded with another slab. If the slab space has not yet been - initialized this is always true. */ - if (!space->first_free) - { - err = grow (space); - if (err) - { - pthread_mutex_unlock (&space->lock); - return err; - } - } - - /* Remove buffer from the free list and update the reference - counter. If the reference counter will hit the top, it is - handled at the time of the next allocation. */ - bufctl = space->first_free->free_list; - space->first_free->free_list = bufctl->next; - space->first_free->refcount++; - bufctl->slab = space->first_free; - - /* If the reference counter hits the top it means that there has - been an allocation boost, otherwise dealloc would have updated - the first_free pointer. Find a slab with free objects. */ - if (space->first_free->refcount == space->full_refcount) - { - struct hurd_slab *new_first = space->slab_first; - while (new_first) - { - if (new_first->refcount != space->full_refcount) - break; - new_first = new_first->next; - } - /* If first_free is set to NULL here it means that there are - only empty slabs. The next call to alloc will allocate a new - slab if there was no call to dealloc in the meantime. */ - space->first_free = new_first; - } - *buffer = ((void *) bufctl) - (space->size - sizeof *bufctl); - pthread_mutex_unlock (&space->lock); - return 0; -} - - -static inline void -put_on_slab_list (struct hurd_slab *slab, union hurd_bufctl *bufctl) -{ - bufctl->next = slab->free_list; - slab->free_list = bufctl; - slab->refcount--; - assert (slab->refcount >= 0); -} - - -/* Deallocate the object BUFFER from the slab space SPACE. */ -void -hurd_slab_dealloc (hurd_slab_space_t space, void *buffer) -{ - struct hurd_slab *slab; - union hurd_bufctl *bufctl; - - assert (space->initialized); - - pthread_mutex_lock (&space->lock); - - bufctl = (buffer + (space->size - sizeof *bufctl)); - put_on_slab_list (slab = bufctl->slab, bufctl); - - /* Try to have first_free always pointing at the slab that has the - most number of free objects. So after this deallocation, update - the first_free pointer if reference counter drops below the - current reference counter of first_free. */ - if (!space->first_free - || slab->refcount < space->first_free->refcount) - space->first_free = slab; - - pthread_mutex_unlock (&space->lock); -} diff --git a/libhurd-slab/slab.h b/libhurd-slab/slab.h deleted file mode 100644 index 6eeb8e4..0000000 --- a/libhurd-slab/slab.h +++ /dev/null @@ -1,338 +0,0 @@ -/* slab.h - The GNU Hurd slab allocator interface. - Copyright (C) 2003, 2005 Free Software Foundation, Inc. - Written by Marcus Brinkmann <[email protected]> - - This file is part of the GNU Hurd. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This program 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _HURD_SLAB_H -#define _HURD_SLAB_H 1 - -#include <errno.h> -#include <stdbool.h> -#include <pthread.h> - - -/* Allocate a buffer in *PTR of size SIZE which must be a power of 2 - and self aligned (i.e. aligned on a SIZE byte boundary). HOOK is - as provided to hurd_slab_create. Return 0 on success, an error - code on failure. */ -typedef error_t (*hurd_slab_allocate_buffer_t) (void *hook, size_t size, - void **ptr); - -/* Deallocate buffer BUFFER of size SIZE. HOOK is as provided to - hurd_slab_create. */ -typedef error_t (*hurd_slab_deallocate_buffer_t) (void *hook, void *buffer, - size_t size); - -/* Initialize the slab object pointed to by OBJECT. HOOK is as - provided to hurd_slab_create. */ -typedef error_t (*hurd_slab_constructor_t) (void *hook, void *object); - -/* Destroy the slab object pointed to by OBJECT. HOOK is as provided - to hurd_slab_create. */ -typedef void (*hurd_slab_destructor_t) (void *hook, void *object); - - -/* The type of a slab space. - - The structure is divided into two parts: the first is only used - while the slab space is constructed. Its fields are either - initialized by a static initializer (HURD_SLAB_SPACE_INITIALIZER) - or by the hurd_slab_create function. The initialization of the - space is delayed until the first allocation. After that only the - second part is used. */ - -typedef struct hurd_slab_space *hurd_slab_space_t; -struct hurd_slab_space -{ - /* First part. Used when initializing slab space object. */ - - /* True if slab space has been initialized. */ - bool initialized; - - /* Protects this structure, along with all the slabs. No need to - delay initialization of this field. */ - pthread_mutex_t lock; - - /* The size and alignment of objects allocated using this slab - space. These to fields are used to calculate the final object - size, which is put in SIZE (defined below). */ - size_t requested_size; - size_t requested_align; - - /* The size of each slab. */ - size_t slab_size; - - /* The buffer allocator. */ - hurd_slab_allocate_buffer_t allocate_buffer; - - /* The buffer deallocator. */ - hurd_slab_deallocate_buffer_t deallocate_buffer; - - /* The constructor. */ - hurd_slab_constructor_t constructor; - - /* The destructor. */ - hurd_slab_destructor_t destructor; - - /* The user's private data. */ - void *hook; - - /* Second part. Runtime information for the slab space. */ - - struct hurd_slab *slab_first; - struct hurd_slab *slab_last; - - /* In the doubly-linked list of slabs, empty slabs come first, after - that the slabs that have some buffers allocated, and finally the - complete slabs (refcount == 0). FIRST_FREE points to the first - non-empty slab. */ - struct hurd_slab *first_free; - - /* For easy checking, this holds the value the reference counter - should have for an empty slab. */ - int full_refcount; - - /* The size of one object. Should include possible alignment as - well as the size of the bufctl structure. */ - size_t size; -}; - - -/* Static initializer. TYPE is used to get size and alignment of - objects the slab space will be used to allocate. ALLOCATE_BUFFER - may be NULL in which case mmap is called. DEALLOCATE_BUFFER may be - NULL in which case munmap is called. CTOR and DTOR are the slab's - object constructor and destructor, respectivly and may be NULL if - not required. HOOK is passed as user data to the constructor and - destructor. */ -#define HURD_SLAB_SPACE_INITIALIZER(TYPE, ALLOC, DEALLOC, CTOR, \ - DTOR, HOOK) \ - { \ - false, \ - PTHREAD_MUTEX_INITIALIZER, \ - sizeof (TYPE), \ - __alignof__ (TYPE), \ - ALLOC, \ - DEALLOC, \ - CTOR, \ - DTOR, \ - HOOK \ - /* The rest of the structure will be filled with zeros, \ - which is good for us. */ \ - } - - -/* Create a new slab space with the given object size, alignment, - constructor and destructor. ALIGNMENT can be zero. - ALLOCATE_BUFFER may be NULL in which case mmap is called. - DEALLOCATE_BUFFER may be NULL in which case munmap is called. CTOR - and DTOR are the slabs object constructor and destructor, - respectivly and may be NULL if not required. HOOK is passed as the - first argument to the constructor and destructor. */ -error_t hurd_slab_create (size_t size, size_t alignment, - hurd_slab_allocate_buffer_t allocate_buffer, - hurd_slab_deallocate_buffer_t deallocate_buffer, - hurd_slab_constructor_t constructor, - hurd_slab_destructor_t destructor, - void *hook, - hurd_slab_space_t *space); - -/* Destroy all objects and the slab space SPACE. If there were no - outstanding allocations free the slab space. Returns EBUSY if - there are still allocated objects in the slab space. The dual of - hurd_slab_create. */ -error_t hurd_slab_free (hurd_slab_space_t space); - -/* Like hurd_slab_create, but does not allocate storage for the slab. */ -error_t hurd_slab_init (hurd_slab_space_t space, size_t size, size_t alignment, - hurd_slab_allocate_buffer_t allocate_buffer, - hurd_slab_deallocate_buffer_t deallocate_buffer, - hurd_slab_constructor_t constructor, - hurd_slab_destructor_t destructor, - void *hook); - -/* Destroy all objects and the slab space SPACE. Returns EBUSY if - there are still allocated objects in the slab. The dual of - hurd_slab_init. */ -error_t hurd_slab_destroy (hurd_slab_space_t space); - -/* Allocate a new object from the slab space SPACE. */ -error_t hurd_slab_alloc (hurd_slab_space_t space, void **buffer); - -/* Deallocate the object BUFFER from the slab space SPACE. */ -void hurd_slab_dealloc (hurd_slab_space_t space, void *buffer); - -/* Create a more strongly typed slab interface a la a C++ template. - - NAME is the name of the new slab class. NAME is used to synthesize - names for the class types and methods using the following rule: the - hurd_ namespace will prefix all method names followed by NAME - followed by an underscore and finally the method name. The - following are thus exposed: - - Types: - struct hurd_NAME_slab_space - hurd_NAME_slab_space_t - - error_t (*hurd_NAME_slab_constructor_t) (void *hook, element_type *buffer) - void (*hurd_NAME_slab_destructor_t) (void *hook, element_type *buffer) - - Functions: - error_t hurd_NAME_slab_create (hurd_slab_allocate_buffer_t - allocate_buffer, - hurd_slab_deallocate_buffer_t - deallocate_buffer, - hurd_NAME_slab_constructor_t constructor, - hurd_NAME_slab_destructor_t destructor, - void *hook, - hurd_NAME_slab_space_t *space); - error_t hurd_NAME_slab_free (hurd_NAME_slab_space_t space); - - error_t hurd_NAME_slab_init (hurd_NAME_slab_space_t space, - hurd_slab_allocate_buffer_t allocate_buffer, - hurd_slab_deallocate_buffer_t - deallocate_buffer, - hurd_NAME_slab_constructor_t constructor, - hurd_NAME_slab_destructor_t destructor, - void *hook); - error_t hurd_NAME_slab_destroy (hurd_NAME_slab_space_t space); - - error_t hurd_NAME_slab_alloc (hurd_NAME_slab_space_t space, - element_type **buffer); - void hurd_NAME_slab_dealloc (hurd_NAME_slab_space_t space, - element_type *buffer); - - ELEMENT_TYPE is the type of elements to store in the slab. If you - want the slab to contain struct foo, pass `struct foo' as the - ELEMENT_TYPE (not `struct foo *'!!!). - -*/ -#define SLAB_CLASS(name, element_type) \ -struct hurd_##name##_slab_space \ -{ \ - struct hurd_slab_space space; \ -}; \ -typedef struct hurd_##name##_slab_space *hurd_##name##_slab_space_t; \ - \ -typedef error_t (*hurd_##name##_slab_constructor_t) (void *hook, \ - element_type *buffer); \ - \ -typedef void (*hurd_##name##_slab_destructor_t) (void *hook, \ - element_type *buffer); \ - \ -static inline error_t \ -hurd_##name##_slab_create (hurd_slab_allocate_buffer_t allocate_buffer, \ - hurd_slab_deallocate_buffer_t deallocate_buffer, \ - hurd_##name##_slab_constructor_t constructor, \ - hurd_##name##_slab_destructor_t destructor, \ - void *hook, \ - hurd_##name##_slab_space_t *space) \ -{ \ - union \ - { \ - hurd_##name##_slab_constructor_t t; \ - hurd_slab_constructor_t u; \ - } con; \ - union \ - { \ - hurd_##name##_slab_destructor_t t; \ - hurd_slab_destructor_t u; \ - } des; \ - union \ - { \ - hurd_##name##_slab_space_t *t; \ - hurd_slab_space_t *u; \ - } foo; \ - con.t = constructor; \ - des.t = destructor; \ - foo.t = space; \ - \ - return hurd_slab_create(sizeof (element_type), __alignof__ (element_type), \ - allocate_buffer, deallocate_buffer, \ - con.u, des.u, hook, foo.u); \ -} \ - \ -static inline error_t \ -hurd_##name##_slab_free (hurd_##name##_slab_space_t space) \ -{ \ - return hurd_slab_free (&space->space); \ -} \ - \ -static inline error_t \ -hurd_##name##_slab_init (hurd_##name##_slab_space_t space, \ - hurd_slab_allocate_buffer_t allocate_buffer, \ - hurd_slab_deallocate_buffer_t deallocate_buffer, \ - hurd_##name##_slab_constructor_t constructor, \ - hurd_##name##_slab_destructor_t destructor, \ - void *hook) \ -{ \ - union \ - { \ - hurd_##name##_slab_constructor_t t; \ - hurd_slab_constructor_t u; \ - } con; \ - union \ - { \ - hurd_##name##_slab_destructor_t t; \ - hurd_slab_destructor_t u; \ - } des; \ - con.t = constructor; \ - des.t = destructor; \ - \ - return hurd_slab_init (&space->space, \ - sizeof (element_type), __alignof__ (element_type), \ - allocate_buffer, deallocate_buffer, \ - con.u, des.u, hook); \ -} \ - \ -static inline error_t \ -hurd_##name##_slab_destroy (hurd_##name##_slab_space_t space) \ -{ \ - return hurd_slab_destroy (&space->space); \ -} \ - \ -static inline error_t \ -hurd_##name##_slab_alloc (hurd_##name##_slab_space_t space, \ - element_type **buffer) \ -{ \ - union \ - { \ - element_type **e; \ - void **v; \ - } foo; \ - foo.e = buffer; \ - \ - return hurd_slab_alloc (&space->space, foo.v); \ -} \ - \ -static inline void \ -hurd_##name##_slab_dealloc (hurd_##name##_slab_space_t space, \ - element_type *buffer) \ -{ \ - union \ - { \ - element_type *e; \ - void *v; \ - } foo; \ - foo.e = buffer; \ - \ - hurd_slab_dealloc (&space->space, foo.v); \ -} - -#endif /* _HURD_SLAB_H */ -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hurd/hurd.git
