This commit was manufactured by cvs2svn to create branch 'mysql-branch'. mysql-branch
authorMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 13 Mar 2007 20:28:23 +0000 (20:28 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 13 Mar 2007 20:28:23 +0000 (20:28 +0000)
311 files changed:
Xisop/LICENSE [deleted file]
Xisop/README [deleted file]
Xisop/TODO [deleted file]
Xisop/doc/clean.sh [deleted file]
Xisop/doc/make.sh [deleted file]
Xisop/doc/xisop.lyx [deleted file]
Xisop/src/clean.sh [deleted file]
Xisop/src/common/clean.sh [deleted file]
Xisop/src/common/kernel/clean.sh [deleted file]
Xisop/src/common/kernel/debug.c [deleted file]
Xisop/src/common/kernel/debug.h [deleted file]
Xisop/src/common/kernel/device.c [deleted file]
Xisop/src/common/kernel/device.h [deleted file]
Xisop/src/common/kernel/exception.c [deleted file]
Xisop/src/common/kernel/exception.h [deleted file]
Xisop/src/common/kernel/main.c [deleted file]
Xisop/src/common/kernel/main.h [deleted file]
Xisop/src/common/kernel/make.sh [deleted file]
Xisop/src/common/kernel/memory.c [deleted file]
Xisop/src/common/kernel/memory.h [deleted file]
Xisop/src/common/kernel/object.h [deleted file]
Xisop/src/common/kernel/port.c [deleted file]
Xisop/src/common/kernel/port.h [deleted file]
Xisop/src/common/kernel/scheduler.c [deleted file]
Xisop/src/common/kernel/scheduler.h [deleted file]
Xisop/src/common/kernel/signal.c [deleted file]
Xisop/src/common/kernel/signal.h [deleted file]
Xisop/src/common/kernel/statistic.c [deleted file]
Xisop/src/common/kernel/statistic.h [deleted file]
Xisop/src/common/kernel/syscall.c [deleted file]
Xisop/src/common/kernel/syscall.h [deleted file]
Xisop/src/common/kernel/task.c [deleted file]
Xisop/src/common/kernel/task.h [deleted file]
Xisop/src/common/kernlib/clean.sh [deleted file]
Xisop/src/common/kernlib/fifo.h [deleted file]
Xisop/src/common/kernlib/hash.c [deleted file]
Xisop/src/common/kernlib/hash.h [deleted file]
Xisop/src/common/kernlib/lifo.h [deleted file]
Xisop/src/common/kernlib/list.h [deleted file]
Xisop/src/common/kernlib/make.sh [deleted file]
Xisop/src/common/kernlib/rand.c [deleted file]
Xisop/src/common/kernlib/rand.h [deleted file]
Xisop/src/common/kernlib/setjmp.h [deleted file]
Xisop/src/common/kernlib/string.h [deleted file]
Xisop/src/common/kernlib/string/_strcat.c [deleted file]
Xisop/src/common/kernlib/string/_strcpy.c [deleted file]
Xisop/src/common/kernlib/string/_strdup.c [deleted file]
Xisop/src/common/kernlib/string/_strncat.c [deleted file]
Xisop/src/common/kernlib/string/_strncpy.c [deleted file]
Xisop/src/common/kernlib/string/_strndup.c [deleted file]
Xisop/src/common/kernlib/string/_strrev.c [deleted file]
Xisop/src/common/kernlib/string/bstr_alloc.c [deleted file]
Xisop/src/common/kernlib/string/bstr_free.c [deleted file]
Xisop/src/common/kernlib/string/bstr_new.c [deleted file]
Xisop/src/common/kernlib/string/case.c [deleted file]
Xisop/src/common/kernlib/string/htol.c [deleted file]
Xisop/src/common/kernlib/string/memcmp.c [deleted file]
Xisop/src/common/kernlib/string/memcpy.c [deleted file]
Xisop/src/common/kernlib/string/memhash32.c [deleted file]
Xisop/src/common/kernlib/string/memmove.c [deleted file]
Xisop/src/common/kernlib/string/memset.c [deleted file]
Xisop/src/common/kernlib/string/pageclr.c [deleted file]
Xisop/src/common/kernlib/string/straspl.c [deleted file]
Xisop/src/common/kernlib/string/strchr.c [deleted file]
Xisop/src/common/kernlib/string/strcmp.c [deleted file]
Xisop/src/common/kernlib/string/strlen.c [deleted file]
Xisop/src/common/kernlib/string/strnchr.c [deleted file]
Xisop/src/common/kernlib/string/strncmp.c [deleted file]
Xisop/src/common/kernlib/string/strnlen.c [deleted file]
Xisop/src/common/kernlib/string/strnrchr.c [deleted file]
Xisop/src/common/kernlib/string/strrchr.c [deleted file]
Xisop/src/common/kernlib/string/strspl.c [deleted file]
Xisop/src/common/make.sh [deleted file]
Xisop/src/common/types.h [deleted file]
Xisop/src/config.h [deleted file]
Xisop/src/generic_makedefs.sh [deleted file]
Xisop/src/make.sh [deleted file]
Xisop/src/ports/amiga/boot/DOTuaerc [deleted file]
Xisop/src/ports/amiga/boot/README [deleted file]
Xisop/src/ports/amiga/boot/bootf/bootf_c.c [deleted file]
Xisop/src/ports/amiga/boot/bootf/bootf_s.s [deleted file]
Xisop/src/ports/amiga/boot/bootf/bootf_script.ld [deleted file]
Xisop/src/ports/amiga/boot/clean.sh [deleted file]
Xisop/src/ports/amiga/boot/config.h [deleted file]
Xisop/src/ports/amiga/boot/image_script.ld [deleted file]
Xisop/src/ports/amiga/boot/init.c [deleted file]
Xisop/src/ports/amiga/boot/make.sh [deleted file]
Xisop/src/ports/amiga/boot/tools/aosbblock.c [deleted file]
Xisop/src/ports/amiga/boot/tools/config.c [deleted file]
Xisop/src/ports/amiga/boot/tools/dumpkern.c [deleted file]
Xisop/src/ports/amiga/clean.sh [deleted file]
Xisop/src/ports/amiga/make.sh [deleted file]
Xisop/src/ports/amiga/makedefs.sh [deleted file]
Xisop/src/ports/amiga/support.h [deleted file]
Xisop/src/ports/amiga/support_c.c [deleted file]
Xisop/src/ports/amiga/support_s.s [deleted file]
Xisop/src/processors/i386/make.sh [deleted file]
Xisop/src/processors/i386/support.h [deleted file]
Xisop/src/processors/i386/support.s [deleted file]
Xisop/src/processors/m68k/clean.sh [deleted file]
Xisop/src/processors/m68k/make.sh [deleted file]
Xisop/src/processors/m68k/math/README [deleted file]
Xisop/src/processors/m68k/math/divsi3.s [deleted file]
Xisop/src/processors/m68k/math/modsi3.s [deleted file]
Xisop/src/processors/m68k/math/mulsi3.s [deleted file]
Xisop/src/processors/m68k/math/udivsi3.s [deleted file]
Xisop/src/processors/m68k/math/umodsi3.s [deleted file]
Xisop/src/processors/m68k/support.h [deleted file]
Xisop/src/processors/m68k/support.s [deleted file]
site/contributors.html [deleted file]
site/cvs.html [deleted file]
site/donations.html [deleted file]
site/favicon.ico [deleted file]
site/images/CVS.jpg [deleted file]
site/images/key.jpg [deleted file]
site/images/sigil.jpg [deleted file]
site/index.html [deleted file]
site/mirrors.html [deleted file]
site/new/TODO [deleted file]
site/new/build/GNUmakefile [deleted file]
site/new/build/README [deleted file]
site/new/build/TODO [deleted file]
site/new/build/english/faq_mmftpd.txt [deleted file]
site/new/build/english/faq_mmmail.txt [deleted file]
site/new/build/english/faq_mmstatd.txt [deleted file]
site/new/build/english/menu_languages.txt [deleted file]
site/new/build/english/menu_main.txt [deleted file]
site/new/build/english/menu_mirrors.txt [deleted file]
site/new/build/english/page_contact.txt [deleted file]
site/new/build/english/page_contributors.txt [deleted file]
site/new/build/english/page_cvs.txt [deleted file]
site/new/build/english/page_donations.txt [deleted file]
site/new/build/english/page_index.txt [deleted file]
site/new/build/english/page_mirrors.txt [deleted file]
site/new/build/english/page_philosophy.txt [deleted file]
site/new/build/english/page_projects.txt [deleted file]
site/new/build/english/page_software.txt [deleted file]
site/new/build/english/soft_descriptions.txt [deleted file]
site/new/build/mmsite.c [deleted file]
site/new/build/mmsite.conf [deleted file]
site/new/build/site_faq.txt [deleted file]
site/new/build/site_languages.txt [deleted file]
site/new/build/site_mirrors.txt [deleted file]
site/new/build/site_pages.txt [deleted file]
site/new/build/site_software.txt [deleted file]
site/new/build/soft_development.txt [deleted file]
site/new/build/soft_old.txt [deleted file]
site/new/build/soft_stable.txt [deleted file]
site/philosophy.html [deleted file]
site/projects.html [deleted file]
site/software.html [deleted file]
tests/entropy/README [deleted file]
tests/entropy/entropy_disk.c [deleted file]
tests/js-test/README [deleted file]
tests/js-test/js/copy.js [deleted file]
tests/js-test/js/fd.js [deleted file]
tests/js-test/js/game/objects.js [deleted file]
tests/js-test/js/httpd/httpd.js [deleted file]
tests/js-test/js/httpd/ml_clean.js [deleted file]
tests/js-test/js/httpd/ml_machine.js [deleted file]
tests/js-test/js/httpd/options.js [deleted file]
tests/js-test/js/httpd/root.js [deleted file]
tests/js-test/js/httpd/string.js [deleted file]
tests/js-test/js/ml.js [deleted file]
tests/js-test/js/ml2.js [deleted file]
tests/js-test/js/ml3.js [deleted file]
tests/js-test/js/ml4.js [deleted file]
tests/js-test/js/ml5.js [deleted file]
tests/js-test/js/ml6.js [deleted file]
tests/js-test/js/parse.js [deleted file]
tests/js-test/js/poll_test.js [deleted file]
tests/js-test/js/sock_httpd.js [deleted file]
tests/js-test/js/sock_listen.js [deleted file]
tests/js-test/js/test.js [deleted file]
tests/js-test/js/test2.js [deleted file]
tests/js-test/js/test3.js [deleted file]
tests/js-test/src/GNUmakefile [deleted file]
tests/js-test/src/classes/js_errno.c [deleted file]
tests/js-test/src/classes/js_errno.h [deleted file]
tests/js-test/src/classes/js_fd.c [deleted file]
tests/js-test/src/classes/js_fd.h [deleted file]
tests/js-test/src/classes/js_global.c [deleted file]
tests/js-test/src/classes/js_global.h [deleted file]
tests/js-test/src/classes/js_mysql.c [deleted file]
tests/js-test/src/classes/js_mysql.h [deleted file]
tests/js-test/src/classes/js_pgsql.c [deleted file]
tests/js-test/src/classes/js_pgsql.h [deleted file]
tests/js-test/src/classes/js_signal.c [deleted file]
tests/js-test/src/classes/js_signal.h [deleted file]
tests/js-test/src/js-server.c [deleted file]
tests/js-test/util/spidermonkey-config [deleted file]
tests/kqueue/GNUmakefile [deleted file]
tests/kqueue/README [deleted file]
tests/kqueue/client.c [deleted file]
tests/kqueue/client.h [deleted file]
tests/kqueue/conf.h [deleted file]
tests/kqueue/daemon.c [deleted file]
tests/kqueue/daemon.h [deleted file]
tests/kqueue/kqueue.c [deleted file]
tests/kqueue/kqueue.h [deleted file]
tests/kqueue/main.c [deleted file]
tests/kqueue/net.c [deleted file]
tests/kqueue/net.h [deleted file]
tests/kqueue/packets.c [deleted file]
tests/kqueue/packets.h [deleted file]
tests/kqueue/recvq.c [deleted file]
tests/kqueue/recvq.h [deleted file]
tests/kqueue/sendq.c [deleted file]
tests/kqueue/sendq.h [deleted file]
tests/memory/README [deleted file]
tests/pthread/README [deleted file]
tests/pthread_utils/GNUmakefile [deleted file]
tests/pthread_utils/README [deleted file]
tests/pthread_utils/mm_pthread_debug.h [deleted file]
tests/pthread_utils/mm_pthread_msg.c [deleted file]
tests/pthread_utils/mm_pthread_msg.h [deleted file]
tests/pthread_utils/mm_pthread_poll.c [deleted file]
tests/pthread_utils/mm_pthread_poll.h [deleted file]
tests/pthread_utils/mm_pthread_pool.c [deleted file]
tests/pthread_utils/mm_pthread_pool.h [deleted file]
tests/pthread_utils/mm_pthread_sleep.c [deleted file]
tests/pthread_utils/mm_pthread_sleep.h [deleted file]
tests/pthread_utils/tests/msg_test.c [deleted file]
tests/pthread_utils/tests/poll_test.c [deleted file]
tests/pthread_utils/tests/polltest.c [deleted file]
tests/pthread_utils/tests/sigtest.c [deleted file]
tests/rlookup/GNUmakefile [deleted file]
tests/rlookup/main.c [deleted file]
tests/rlookup/rlc.c [deleted file]
tests/rlookup/rlc.h [deleted file]
tests/rotate/GNUmakefile [deleted file]
tests/rotate/main.c [deleted file]
tests/sdl-client/GNUmakefile [deleted file]
tests/sdl-client/README [deleted file]
tests/sdl-client/bmp/FedCA.bmp [deleted file]
tests/sdl-client/bmp/README [deleted file]
tests/sdl-client/bmp/RomDD.bmp [deleted file]
tests/sdl-client/bmp/fedship.bmp [deleted file]
tests/sdl-client/bmp/indship.bmp [deleted file]
tests/sdl-client/bmp/kliship.bmp [deleted file]
tests/sdl-client/bmp/misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1.bmp [deleted file]
tests/sdl-client/bmp/misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1.bmp [deleted file]
tests/sdl-client/bmp/misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1.bmp [deleted file]
tests/sdl-client/bmp/misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1.bmp [deleted file]
tests/sdl-client/bmp/oriship.bmp [deleted file]
tests/sdl-client/bmp/romship.bmp [deleted file]
tests/sdl-client/bmp/sbexpl.bmp [deleted file]
tests/sdl-client/bmp/shexpl.bmp [deleted file]
tests/sdl-client/conf.h [deleted file]
tests/sdl-client/debug.c [deleted file]
tests/sdl-client/debug.h [deleted file]
tests/sdl-client/decode.c [deleted file]
tests/sdl-client/decode.h [deleted file]
tests/sdl-client/dlist.h [deleted file]
tests/sdl-client/encode.c [deleted file]
tests/sdl-client/fnt/10x20.fnt [deleted file]
tests/sdl-client/fnt/5x7.fnt [deleted file]
tests/sdl-client/fnt/5x8.fnt [deleted file]
tests/sdl-client/fnt/6x10.fnt [deleted file]
tests/sdl-client/fnt/6x12.fnt [deleted file]
tests/sdl-client/fnt/6x13.fnt [deleted file]
tests/sdl-client/fnt/6x13B.fnt [deleted file]
tests/sdl-client/fnt/6x13O.fnt [deleted file]
tests/sdl-client/fnt/6x9.fnt [deleted file]
tests/sdl-client/fnt/7x13.fnt [deleted file]
tests/sdl-client/fnt/7x13B.fnt [deleted file]
tests/sdl-client/fnt/7x13O.fnt [deleted file]
tests/sdl-client/fnt/7x14.fnt [deleted file]
tests/sdl-client/fnt/7x14B.fnt [deleted file]
tests/sdl-client/fnt/8x13.fnt [deleted file]
tests/sdl-client/fnt/8x13B.fnt [deleted file]
tests/sdl-client/fnt/8x13O.fnt [deleted file]
tests/sdl-client/fnt/9x15.fnt [deleted file]
tests/sdl-client/fnt/9x15B.fnt [deleted file]
tests/sdl-client/fnt/9x18.fnt [deleted file]
tests/sdl-client/fnt/9x18B.fnt [deleted file]
tests/sdl-client/main.c [deleted file]
tests/sdl-client/main.h [deleted file]
tests/sdl-client/ogg/README [deleted file]
tests/sdl-client/packets.c [deleted file]
tests/sdl-client/packets.h [deleted file]
tests/sdl-client/pool.c [deleted file]
tests/sdl-client/pool.h [deleted file]
tests/sdl-client/rawobjs.h [deleted file]
tests/sdl-client/screen.c [deleted file]
tests/sdl-client/screen.h [deleted file]
tests/sdl-client/tests/draw.c [deleted file]
tests/sdl-client/tests/draw.h [deleted file]
tests/sdl-client/tests/fonts.c [deleted file]
tests/sdl-client/tests/fonts.h [deleted file]
tests/sdl-client/tests/msg.c [deleted file]
tests/sdl-client/tests/netrek-like.c [deleted file]
tests/sdl-client/tests/rot.c [deleted file]
tests/sdl-client/tests/snd.c [deleted file]
tests/sdl-client/thread_msg.c [deleted file]
tests/sdl-client/thread_msg.h [deleted file]
tests/sdl-client/thread_net_recv.c [deleted file]
tests/sdl-client/thread_net_recv.h [deleted file]
tests/sdl-client/thread_net_send.c [deleted file]
tests/sdl-client/thread_net_send.h [deleted file]
tests/sdl-client/wav/README [deleted file]
tests/sdl-client/wav/nt_cloaked.wav [deleted file]
tests/sdl-client/wav/nt_explosion_other.wav [deleted file]
tests/sdl-client/wav/nt_fire_torp_other.wav [deleted file]
tests/sdl-client/wav/nt_plasma_hit.wav [deleted file]
tests/sdl-client/wav/nt_shield_down.wav [deleted file]
tests/sdl-client/wav/nt_shield_up.wav [deleted file]
tests/sdl-client/wav/nt_uncloak.wav [deleted file]
tests/zlib/README [deleted file]
tests/zlib/deflate.c [deleted file]
tests/zlib/inflate.c [deleted file]

diff --git a/Xisop/LICENSE b/Xisop/LICENSE
deleted file mode 100644 (file)
index aadb1b9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id: LICENSE,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (c) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
diff --git a/Xisop/README b/Xisop/README
deleted file mode 100644 (file)
index 7681f89..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-$Id: README,v 1.7 2004/06/04 02:31:51 mmondor Exp $
-
-
-
-Xisop Copyright 2001-2003, Matthew Mondor,
-All rights reserved.
-
-Currently under development. The only current port is Amiga, and an .uaerc
-is provided for the UAE emulator to test it and possibly enhance it :)
-       Xisop/src/ports/amiga/boot/DOTuaerc
-It is recommended to run the UAE emulator using the -T command line parameter
-when on unix systems (or setting the x11.use_mitshm=true in the ~/.uaerc file).
-Note that kickstart 3.0 or later is required, and that I will not provide this
-file to anyone, as it is copyrighted material. You can buy a kickstart kit, or
-mirror the one of your amiga to file. The models which used to ship with 3.0+
-natively were the A1200 and A4000. It is possible to make Xisop kickstart 1.3
-compatible if it was to be used to make games, since only the bootloader is
-AmigaOS dependent.
-
-The compiled kernel is 30k in size if compiled with statistics support, or
-19k otherwise.
-
-The source of the port-dependent initialization function (which currently
-launches tasks displaying colors for testing and demonstrating) is located at
-       Xisop/src/ports/amiga/boot/init.c
-
-Some development notes are also being worked on according to the internal
-implementation details, programming style notes and how to port Xisop
-(also under development as the kernel interfaces are being stabilized).
-       Xisop/doc/xisop.pdf
-This file is built from xisop.lyx which is maintained using the LyX utility.
-
-Almost all the current code and documentation were re-written from scratch in
-Febuary and March 2003. The old Xisop code somewhat served as reference
-when needed.
-
-Please read TODO on what currently needs to be worked on to continue the
-project, what was done and what needs debugging. The project is to eventually
-be fully released under BSD-style license when at least one port works fine.
-Make sure to also read the documentation in doc/.
-
-To build the amiga port you should specify the location of the cross building
-tools in Xisop/src/ports/amiga/makedefs.sh, or use the defaults if you have
-a NetBSD 1.6.1 source, in which case you can simply use the build.sh script
-provided in /usr/src to build the netbsdelf-m68k target toolchain (which only
-needs to be done once):
-       cd /usr/src
-       ./build.sh -a m68k -t
-Then:
-       cd Xisop/src
-       ./make.sh -t amiga
-
-Matthew Mondor
diff --git a/Xisop/TODO b/Xisop/TODO
deleted file mode 100644 (file)
index 9c2d318..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-$Id: TODO,v 1.20 2004/10/14 15:13:20 mmondor Exp $
-
-
-- Import modifications from mmsoftware/mmlib:
-  - New more efficient pool allocator, with enhanced debugging capability.
-    This could imply reworking some of the whole system.
-  - Maybe incorporate C byteorder library, so that less processor-specific
-    code is required (of course, they can override C ones with asm ones).
-
-
-Working:
-=======
-- Memory management system and ANSI-C related functions
-- Syscalls, including one which allows to execute arbitrary code in supervisor
-       mode
-- Exclusive, recursive and read/write locks
-- User interrupt facilities
-- Preemptive multitasking, _yield() and task_sleep()/task_wakeup()
-- CPU saving ideling
-       When no tasks are on the ready queue to run, the _scontext _ctx_t
-       defined in scheduler.c is resumed, which in fact returns to main.c's
-       main() function, which sole purpose is to sys_idle(), in a loop,
-       which suspends the processor until the next interrupt occurs.
-- Serious exceptions generate a display showing a number of lines which
-  corresponds to the actual error (_ecatch() parameter), useful to debug
-  the current Amiga port.
-- Useful statistics book-keeping of global counters
-- Inter-task signals
-- Inter-task communication reliable ports and messages
-- The init and task reaper system tasks
-- Operations which need fast lookup tables to use kernlib/hash.[ch].
-  This is done for some system lists, such as for port_find().
-- Multiple tasks shareing a common mpool_t created with TF_SHARED
-
-
-Bugs to work out:
-================
-- There again is some problem with memory or stack sizes. When DEBUG and
-  STATISTICS are enabled in config.h, things do not work as intended.
-  This seems to simply arise now that the kernel image is about a k larger.
-  For some reason, the ports/amiga/boot/config.h values do not seem to
-  always generate proper kernel images, for instance when I increase the
-  stack size to 16384 I get a guru meditation...
-- The scheduler which takes task priorities into account is currently not
-  working. There is a temporary replacement scheduler which works now and
-  only performs round-robin when preempting tasks. The old one which has
-  some bugs is found in src/common/kernel/scheduler.c and is called
-  old_schedule().
-- Signals and message ports
-       Some hack should be found a more appropriate solution: signal_send()
-       needs to _yield() twice (See src/common/kernel/signal.c).
-       For some not yet determined reason, tasks would all eventually be
-       stuck on the wait queue if this was not done.
-
-
-Remaining to complete:
-=====================
-- Add system similar to mmlib/mmalarm(3) to Xisop, to go with the existing
-  MI interrupt hook management functions
-- Perhaps use hashtables in exceptions hooks management instead of linked
-  lists? Is this needed or wanted? Running through a hash table is slower,
-  but lookups are faster. Think about it and see which is best to use.
-- Fix issue with amiga port init stack size... m68k usermode() could
-  be specified a stack size for instance, at least. We also could
-  reserve some memory for the stack in advance and supply it...
-- Implement setjmp()/longjmp() for i386
-- CPU specific _bfill16 and _bfill32 etc (at least _bfillint or such),
-  to efficiently fill a native word size with an 8-bit pattern. This
-  could be used by the string library in memset() for instance...
-- Probably that the cases of usecount (devicenode_t, mpool_t) could use
-  an _rlock_t for more efficiency. It is implemented in assembler, and
-  is sure to be atomic.
-- Finish dprintf() FIFO operation optimizations, and write a generic
-  vsnprintf() implementation with stdarg. We want to enhance DPRINTF()
-  to print module and line numbers, etc.
-- _panic()
-- Console and printf() (along with corresponding console.device)
-- Map remaining exceptions to output messages on console
-       For the console.device to eventually exist, the port primitives are
-       essencial. So until they work reliably it's not really possible to
-       implement right now (at least on Amiga).
-       It would be easy to use the video hardware memory on a i386 port
-       however, so a i386 port could perhaps actually help in development
-       for the rest :)
-        Ports implementation is now working reliably. Revise.
-- Probably that the statistics would also be nice to have on a per-task basis.
-       Moreover, they are not as useful as they would if a console existed :<
-       currently, the DPRINTF() system logs to a FIFO buffer.
-- Xisop shared libraries
-- Xisop devices as a synchronization abstraction over the message ports system
-- Xisop handlers as a higher-level (filesystem/file) abstraction over devices
-  libraries and/or hardware
-- Relocatable binary loader
-       This unfortunately either implies writing a full fledged ELF or a.out
-       loader, or a BFD library for GCC ld to output in a new desired format.
-       The ELF loader was started but was not completed (not included in the
-       current sources). ELF unfortunately seems really bloated for the
-       actual needs of this project, and it's state is uncertain.
-       The loader would be used to load shared libraries, and executable
-       tasks, including devices and handlers.
-       For the moment, the system is monolithic and soon a simple interface
-       will be provided to allow the port-specific code to provide a list
-       of tasks to be launched by Xisop init.
-       That alone, even monolithic, allows Xisop to stand as a nice C
-       interface which most code is portable among 32-bit systems, to abstract
-       interrupt facilities, shared memory access and multitasking for
-       various applications. Very small, it can fit the application on a
-       floppy (which includes the kernel).
-- timer.device
-- input.device
-- console.device
-- Add necessary functions to allow linking in the common/kernlib/hash.c module
-
-
-
-NEW MEMORY MANAGEMENT SYSTEM NOTES:
-
-As before, we need several types of memory.
-For each memory type, we should still attach/detach memory chunks, like now.
-
-For each memory chunk, a new system should be implemented for page-level
-contiguous memory management and freeing, as well as a new pool allocator,
-based on the idea of the new mmlib/mmpool(3) one.
-
-Because Xisop does not rely on MMU/PMMU, we can simplify the allocator to a
-simple block allocator, without even worrying about page boundaries, if we
-wanted. This would also mean that a pool page could be virtual, that is, could
-not be dependent on the system page size at all, if we wanted. If that was the
-case, the current mmlib/mmpool(3) allocator could be used as-is.
-
-Not to say that, even if we respected page alignment, we still could use a
-better allocator.
-
-A good idea would be to maintain a list of contiguous page (or memory bytes)
-chunks. Nodes of this list would be split as necessary to provide the
-requested size in the allocation functions. The freeing functions would need
-to attempt to coalesce the contigious chunks together when possible as well.
-
-Perhaps that we also would like a best-fit strategy rather than first-fit when
-allocating, so that we could favor contiguous memory chunks that are closest
-in size to the requested amount, rather than always splitting large chunks
-unnecessarily. This would reduce fragmentation, although being slower at
-allocation. However, because this would affect the page allocator, to which
-calls would be reduced by the pool allocators, this could be reasonable.
-
-Perhaps that to observe the best-fit strategy it would be possible to somewhat
-maintain a sorted index or such, of the smaller to larger available chunks.
-It needs to be verified that the code and memory overhead for such an index
-is negligeable, however. Moreover, would keeping a sorted list of free chunks
-useful for performance? How would the allocator efficiently perform jumps in
-the list? Wouldn't it need to be a tree, instead? If we used one, wouldn't we
-need recursion or special iteration for both node insertion and lookup? I will
-need to check that out. What I should do is count the iterations in my similar
-sorted tree system in dnamed, to get an idea of the actual code overhead
-involved.
-
-struct contiguous_chunk {
-       node_t chunks_node;     /* To link in free/allocated chunks list */
-       node_t sorted_node;     /* To link in free chunks sorted list */
-       void *address;          /* Starting address of free memory */
-       size_t length;          /* Size of contiguous free memory */
-       u_int32_t pages;        /* Or, could be number of free pages */
-};
diff --git a/Xisop/doc/clean.sh b/Xisop/doc/clean.sh
deleted file mode 100755 (executable)
index f4bf49d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Id: clean.sh,v 1.2 2004/06/06 04:21:45 mmondor Exp $
-
-rm -f xisop.dvi xisop.tex xisop.lyx~ xisop.pdf xisop.ps xisop.toc .log
diff --git a/Xisop/doc/make.sh b/Xisop/doc/make.sh
deleted file mode 100755 (executable)
index 2300408..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Id: make.sh,v 1.3 2004/06/06 04:21:05 mmondor Exp $
-
-# First export LyX document to LaTeX then run this script
-
-lyx -e latex xisop.lyx
-latex xisop.tex
-latex xisop.tex
-rm -f xisop.ps xisop.aux xisop.log .log
-dvips -Pcmz -Pamz -o xisop.ps -t letter -D 300 -Z xisop.dvi
-ps2pdf xisop.ps
-rm -f *~
diff --git a/Xisop/doc/xisop.lyx b/Xisop/doc/xisop.lyx
deleted file mode 100644 (file)
index ad156ca..0000000
+++ /dev/null
@@ -1,10041 +0,0 @@
-#LyX 1.2 created this file. For more info see http://www.lyx.org/
-\lyxformat 220
-\textclass article
-\language english
-\inputencoding auto
-\fontscheme default
-\graphics default
-\paperfontsize default
-\spacing single 
-\papersize letterpaper
-\paperpackage a4
-\use_geometry 1
-\use_amsmath 0
-\use_natbib 0
-\use_numerical_citations 0
-\paperorientation portrait
-\topmargin 0.5in
-\bottommargin 0.5in
-\secnumdepth 3
-\tocdepth 3
-\paragraph_separation indent
-\defskip medskip
-\quotes_language english
-\quotes_times 2
-\papercolumns 1
-\papersides 1
-\paperpagestyle default
-
-\layout Title
-
-Xisop kernel development notes
-\layout Author
-\pagebreak_bottom 
-Copyright (c) 2001-2003, Matthew Mondor
-\newline 
-All rights reserved.
-\layout Standard
-
-
-\begin_inset LatexCommand \tableofcontents{}
-
-\end_inset 
-
-
-\layout Section
-\pagebreak_top 
-General development notes
-\layout Standard
-
-Before attempting to write software for Xisop to expand it's funtionality,
- or before porting Xisop to a new architecture, it is recommended to carefully
- read this manual entirely.
- It attempts to answer all questions one could have about it's organization
- and build process, as well as style and conventions one must follow for
- code consistancy with the rest of the project.
-\layout Subsection
-
-Development software used
-\layout Standard
-
-To develop Xisop, the GNU GCC suite of compiler, assembler, linker and binutils
- software was chosen.
- The main reasons for this consists of cost savings, and portability.
- GCC has support for many different CPU types was a main factor.
- Moreover, the AT&T assembly syntax allows to somewhat obtain some consistency.
-\layout Standard
-
-An effort was made to try to not support GCC-specific functions however,
- for portability reasons.
- For instance, the various 
-\emph on 
-_spl
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions are implemented as macros around a separate assembly function,
- located in the assembler 
-\emph on 
-.s
-\emph default 
- files, rather than embedded inside the C code using inline assembly directives.
- (
-\emph on 
-XXX
-\emph default 
-\emph on 
-actually they may be fixed to be GCC-dependent soon heh
-\emph default 
-).
-\layout Standard
-
-A choice was made to not use GNU or BSD make.
- Instead, 
-\emph on 
-/bin/sh
-\emph default 
- is assumed to exist.
- This usually consists of a POSIX compliant shell, on GNU systems (and Linux)
- the 
-\emph on 
-bash
-\emph default 
- shell usually emulates it's behavior and 
-\emph on 
-/bin/sh
-\emph default 
- then consists of a symbolic link to 
-\emph on 
-/bin/bash
-\emph default 
-.
- On BSD systems only POSIX 1003.2 and 1003.2a functionality is usually present
- in their 
-\emph on 
-/bin/sh
-\emph default 
-, which is what Xisop build scripts are making use of.
- As
-\emph on 
-\emph default 
-such,
-\emph on 
- bash
-\emph default 
- is therefore not a requirement.
-\layout Standard
-
-This document is written and maintained using LyX.
- The UAE (Amiga emulator) and Bochs (i386 emulator) utilities were useful
- to develop the current ports.
- The original host development system consists of an i386 compatible system
- running NetBSD 1.6_STABLE.
- This operating system is ideal for programming and cross compiling.
- The current Xisop building system was tuned to the NetBSD 1.6.1 toolchain.
- To compile the amiga port, for instance, you only should need to use the
- build.sh script to build the suite of netbsdelf-m68k tools.
- Using the Xisop 
-\begin_inset Quotes eld
-\end_inset 
-
-
-\emph on 
-./make.sh -t amiga
-\emph default 
-
-\begin_inset Quotes erd
-\end_inset 
-
- command should then build the amiga target.
-\layout Standard
-
-The software was written using the VIm editor, with 
-\emph on 
-ts=8
-\emph default 
-, 
-\emph on 
-sw=4
-\emph default 
- and 
-\emph on 
-cindent
-\emph default 
-.
-\layout Standard
-
-If you compile your own gcc with your intended compiling target, you simply
- need to change a file to tell the locations of the various building tools.
- See the section about 
-\begin_inset Quotes eld
-\end_inset 
-
-the build process
-\begin_inset Quotes erd
-\end_inset 
-
- later on for more information.
-\layout Subsection
-
-Xisop compatibility with other systems, and where it fits best
-\layout Subsubsection
-
-UNIX, POSIX, BSD, Linux
-\layout Standard
-
-Xisop is definitely not POSIX, although it's functions are simpler than
- POSIX is, requireing a small learning curve only to use.
- It was not designed as a general-purpose operating system to replace Unix
- and provide all it's capabilities.
- It's an entity of it's own, simpler and smaller, mostly made to suit the
- requirements of restricted embedded systems.
- To implement most POSIX requirements a larger system is required, which
- generally also results in slower code.
- For instance, Xisop addresses ports and tasks as addresses, rather than
- IDs.
- This solves the problem of allocation and reuse of process IDs.
-\layout Standard
-
-A Xisop task also is lightweight compared to a UNIX-style process.
- Moreover, the need for more custom user signals than POSIX environment
- provides made it unsuitable to reserve almost all 32 signals to reserved
- semantics.
- The concept of file descriptors and select()/poll() is also different.
- However, SIGPOLL signal was reserved in Xisop for the implementation of
- message-based signals and events using a single message port and signal.
- This can be used when there can be a large number of entities a task may
- be monitoring, and the user signals would not be appropriate.
- It would be possible to work a system out using this facility for the 32
- standard Unix signals if the need existed.
-\layout Standard
-
-Although it would be possible to implement POSIX compatibility libraries,
- it was not a main goal in Xisop development.
-\layout Subsubsection
-
-Memory and process protection
-\layout Standard
-
-Xisop was not designed to support Memory Management Unit (MMU) coprocessors
- and provide page-grained memory protection.
- This helped to implement message passing in a very efficient manner, only
- passing pointers around, and reduced considerably kernel size.
- Moreover, it allows to provide most user-access system functions in a shared
- library, reducing considerably the amount of system calls an application
- needs to make (accessed through traps).
- The number of traps being reduced, the preemtive scheduler is less clobbered.
- Calling functions of a shared library happen entirely in the caller's task
- allocated CPU time slice, which means that the kernel load is not affected.
- Not requireing MMU is also an advantage with Xisop, as it can run with
- a single MC68000L8 for instance, and a little RAM.
-\layout Standard
-
-However, we all know that without appropriate memory protection, Xisop cannot
- efficiently protect the kernel from user tasks, which can take full control
- on the system at any time.
- Clean interfaces were however implemented, which internally perform various
- sanity checking to ensure the validity of the supplied objects and arguments,
- so that common software bugs do not automatically corrupt memory and the
- system.
- Xisop knows the difference between a valid task, port, device handle, etc,
- and invalid ones.
- It also knows when to not attempt to free memory if a wrong pointer is
- supplied, since 
-\emph on 
-mnode_t
-\emph default 
- nodes are also validated using a unique magic cookie.
- Such steps permit to minimize system crashes in the event of a software
- bug.
-\layout Standard
-
-The kernel comports special macros to aid in realizing object validity sceals
- and dependancies checking, which are defined in <
-\emph on 
-common/kernel/object.h
-\emph default 
->:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-OBJECT_VALIDATE(objptr,\SpecialChar ~
-objtype)
-\emph default 
- Sets the 
-\emph on 
-objptr
-\emph default 
-->object_magic field to 
-\emph on 
-objtype
-\emph default 
-.
- This type corresponds to one of the 
-\emph on 
-OBJECT_
-\emph default 
-* names which are defined in the same headerfile.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-OBJECT_INVALIDATE(objptr)
-\emph default 
- Sets the 
-\emph on 
-objptr
-\emph default 
-->object_magic field to 0.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-OBJECT_REGISTER(objptr)
-\emph default 
- Registers 
-\emph on 
-objptr
-\emph default 
- object by setting the 
-\emph on 
-objptr
-\emph default 
-->object_id field to a unique number.
- This number will be used for matching when verifying for proper dependancy
- link.
- Only objects which may be required as dependancy to others need to use
- this.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-OBJECT_SETDEP(objptr,\SpecialChar ~
-depobjptr)
-\emph default 
- Associates 
-\emph on 
-objptr
-\emph default 
- object as requireing the 
-\emph on 
-depobjptr
-\emph default 
- object as dependancy for proper function.
- What this does is internally set 
-\emph on 
-objptr
-\emph default 
-->objdep_magic to 
-\emph on 
-depobjptr
-\emph default 
-->magic and 
-\emph on 
-objptr
-\emph default 
-->objdep_id to 
-\emph on 
-depobjptr
-\emph default 
-->object_id.
- As a result, it becomes possible to refuse to perform operations related
- to this object if the dependancy link ever dies.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-OBJECT_VALID(objptr,\SpecialChar ~
-objtype)
-\emph default 
- First verifies if objptr is non-NULL, and then evaluates if the object
- associated with 
-\emph on 
-objptr
-\emph default 
- truely corresponds to 
-\emph on 
-objtype
-\emph default 
- (
-\emph on 
-objptr
-\emph default 
- != NULL && 
-\emph on 
-objptr
-\emph default 
-->object_magic == 
-\emph on 
-objtype
-\emph default 
-).
- This consists of the reason why the various 
-\emph on 
-OBJECT_
-\emph default 
-* definitions in the headerfile should consist of unique values which are
- unlikely to occur randomly.
- Returns TRUE on success, or FALSE otherwise.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-OBJECT_DEPENDS(objptr,\SpecialChar ~
-depobjptr)
-\emph default 
- Verifies the integrity of a dependancy link, which was previously linked
- using 
-\emph on 
-OBJECT_SETDEP()
-\emph default 
- on 
-\emph on 
-objptr
-\emph default 
-.
- This in fact makes sure that the object it should relate to (
-\emph on 
-depobjptr
-\emph default 
-) is still valid, and consists of the same one (
-\emph on 
-depobjptr
-\emph default 
- != NULL && 
-\emph on 
-depobjptr
-\emph default 
-->object_magic == 
-\emph on 
-objptr
-\emph default 
-->objdep_magic && 
-\emph on 
-depobjptr
-\emph default 
-->object_id == 
-\emph on 
-objptr
-\emph default 
-->objdep_id).
- Returns TRUE on success, or FALSE otherwise.
-\layout Standard
-
-Obviously, the structure of an object only requires to hold the fields which
- are required for the functionality it requires according to these macros.
- Those fields are all expected to be of type 
-\emph on 
-u_int32_t
-\emph default 
-.
- This system allows relatively lightweight validity checking of object credentia
-ls, without the need for memory protection.
- The kernel uses them wherever needed for safety.
- Using this system also allows to use efficient dynamic memory allocation
- techniques (
-\emph on 
-pool_t
-\emph default 
- functions) to create and destroy critical system objects, and reference
- can be made using pointers through the system, rather than using less efficient
- or fixed-sized arrays and object ID allocation.
- Programming using these macros also yields in a clean interface to result
- in consistant, clean C code.
-\layout Subsubsection
-
-Multitasking
-\layout Standard
-
-While Xisop provides preemptive multitasking (more information provided
- in the next section), it can be disabled by user applications if need be.
- This means that Xisop can be used to create single-tasking applications
- where a multitasking environment is not wanted, while still taking advantage
- of the abstraction of CPU and hardware access Xisop allows.
- This for instance allows games to be written almost entirely in C, and
- be independent of an operating system such as Windows or AmigaOS, using
- Xisop instead.
- Such a small game can be booted from a single floppy, which would comport
- all necessary components of the game, including Xisop itself.
- Disabling multitasking also allows direct access to the hardware resources
- by the main application, in a safe manner.
- When multitasking is enabled, such safe access to hardware resources is
- also provided, although using the 
-\emph on 
-device
-\emph default 
- concept is required to remain multitasking friendly and access those.
- More information about Xisop devices is given later on.
-\layout Standard
-
-This means that multitasking was provided as a useful optional facility
- rather than to force limits over the applications.
- It is great to develop some kinds of systems using multitasking, while
- some other applications are much better without it.
- This was an important consideration when designing Xisop.
- Whether multitasking is enabled or disabled, the public interrupt facilities
- interface works as expected.
- More information is provided on this interface in a later section.
-\layout Subsubsection
-
-AmigaOS
-\layout Standard
-
-Although some ideas were admitedly borrowed from the Amiga Operating System,
- the compatibility stops there.
- The AmigaOS headerfiles, although publically available, or source code
- (which is unavailable publically) were not used as a reference to write
- it, nor can Xisop run AmigaOS native object files and binaries.
- Xisop is a clean-room kernel implementation, written from scratch and uses
- it's own set of ideas and conventions, which are described in this document.
-\layout Standard
-
-The Xisop signals, message ports, devices and handlers concepts were however
- borrowed from AmigaOS, as it was a great proof of feasibility using a very
- simple underlaying structure.
- The interface and internals do not behave identically but anyone who programmed
- using the AmigaOS inter-task communication and synchronization features
- will feel at ease with Xisop.
-\layout Subsubsection
-
-Where Xisop fits best
-\layout Standard
-
-The best application Xisop suits for consists of an embedded system, dedicated
- to provide specific services or tasks, running with low-cost hardware and
- restricted physical memory.
- There are however a wide range of applications which fit in this category,
- cell phones, microwave ovens, PDAs, clocks, industrial microcontrollers
- or event loggers, alarm systems, etc.
- An example of low-cost hardware Xisop runs great on is a Motorola MC68000L8
- microprocessor based board with a restricted 512 kilobytes of memory, and
- an RS-232 interface with UART controler chip.
- Xisop can also be used to develop games on 32-bit consoles or arcade hardware.
-\layout Standard
-
-Xisop consists of a nice component when simplifying hardware design of a
- project, where a simple CPU unit, little RAM and Xisop-based software can
- provide the tasks of more complex hardware-only solutions.
- This also implies that the simpler hardware may then be reused, since it
- now basically consists of a general purpose programmable system rather
- than single-purpose hardware units which can only serve for a single project.
-\layout Standard
-
-It does not consist of a full multipurpose operating system but rather of
- a collection of primitives to aid a C programmer to write his applications
- on a variety of hardware, and benefit from memory management including
- support for runtime dynamic memory addition and removal, as well as multiple
- memory types, inter-task communication primitives, a fair number of user
- signals, abstracted interrupt facilities, and a microkernel design allowing
- to add future functionality modularized as userspace tasks, shared libraries,
- devices and handlers.
-\layout Standard
-
-It's weak license (BSDL-style) makes it especially suitable for commercial
- embedded applications when a technical team can build a custom application,
- where royalties for use, or redistribution of custom changes in the code
- are not required.
- An effort is provided to make the CPU-specific interface abstract so that
- most of the code can be written in C, for code clarity, consistency, developmen
-t speed and ease.
- The assembly code is restricted to the minimum, and always consists of
- a backend to use C.
- The same is true for architecture-specific assembly low-level code.
- Those sections are described later on.
-\layout Standard
-
-As such, very little time is generally required to port the basics of Xisop
- to a new architecture (other 32-bit ones, at least).
- Engineers can then develop custom low-cost hardware and a programmer can
- write most of the software for it using C and Xisop rather than having
- to write all of it in assembly, or starting from nothing and having to
- re-invent the assembly to C support primitives.
-\layout Standard
-
-Very low cost hardware helps when many units are being deployed.
- However, in the cases where the hardware costs are higher (i.e.
- microprosessor with MMU support and 8 or more megabytes of memory), Xisop
- may seem too rudimentary, but there are then alternatives such as NetBSD
- which can be ported quite fast (when required, as it already consists of
- the most portable OS), and POSIX functionalities, with full unix features,
- networking, protected memory, etc all become available.
- It is also released under the BSD unrestrictive license and is available
- at 
-\emph on 
-http://www.netbsd.org
-\emph default 
-.
-\layout Subsection
-
-Xisop coding standards
-\layout Subsubsection
-
-Licencing issues and censorship
-\layout Standard
-
-All code which is to be publically released within the standard Xisop distributi
-on should be licensed under a BSD-style license, and should not be released
- under the GNU Public License (GPL) or GNU Lesser Public License (LGPL).
- It however is obvious that companion packages be released and distributed
- separately with the Xisop main archive, as long as it be clearly isolated
- and labeled as such, so that it can easily be stripped when code under
- such strict a license is not wanted within a project.
- It is allowed for authors to include their advertizing clause as wanted
- in the BSD license advertizing at the top of their files.
- A main file can then easily be created using a script of advertizement
- clauses and related files whcih one can append in the documentation of
- a commercial or closed source product using Xisop.
-\layout Standard
-
-This allows anyone to use Xisop for open source or closed source projects
- as wanted.
- Although it is encouraged to publically donate the new processor and architectu
-re specific modules one develops, as well as machine-independent new modules
- of interest for inclusion into the main Xisop tree, released under BSD
- license, noone is obliged to do so.
- This also allows the main tree to not become too tainted with alot of code
- everyone develops which does not serve the other Xisop users much and mostly
- bloat the project.
- The mirokernel design easy allows third party supplied libraries, devices
- and handlers to be developed, and these may also be closed source, and
- commercial.
- There of course is no problem to release such optional kernel-independent
- modules under one of the GNU licenses.
-\layout Standard
-
-If you port Xisop to a new processor or architecture, and are willing to
- contribute the code to the tree, I suggest that the source be obtained
- via CVS from the main Xisop source repository, and that 
-\emph on 
-cvs diff -u
-\emph default 
- be used to create a patch.
- This patch should be sent via email to Matthew Modor, at 
-\emph on 
-mmondor@gobot.ca
-\emph default 
-.
- I then will attempt to merge it into the main Xisop CVS tree, after performing
- basic sanity checking on the code, and fixing required bugs if possible
- (if any).
- I may also reply back if there is any reason why the changes cannot be
- applied, in which case I could help to make it conform with the requirements.
-\layout Subsubsection
-
-Standard data types and when to use them
-\layout Standard
-
-Xisop uses a defined set of data types in it's kernel, and attempts to remain
- consistant when using them for code clarity and obviousness.
- The following C standard data types are used:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-char
-\emph default 
- The standard C character type, used for C strings only in Xisop.
-\emph on 
-int8_t 
-\emph default 
-and
-\emph on 
- u_int8_t
-\emph default 
- should be used for other byte-related types.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-char\SpecialChar ~
-*
-\emph default 
- Obvious, also only used in direct relation with C strings.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void
-\emph default 
- When a function returns nothing, or has no arguments, for both prototype
- and function declaration.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*
-\emph default 
- This consists as usual, of a pointer to an abstract type, and is used where
- required.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-int
-\emph default 
- This is used as a convenient format for various return codes and variables
- where bit-size is not a concern, or should match the one which is assumed
- for the processor (although it is highly recommended to use the various
- defined types below for these).
-\layout Standard
-
-The other standard C data types are replaced by the following ones, which
- are defined in the Xisop machine-independent <
-\emph on 
-common/types.h>
-\emph default 
- headerfile:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool
-\emph default 
- Corresponds to 
-\emph on 
-int
-\emph default 
-, but specifically denotes that this variable is used for boolean operations
- and conditionals for code clarity it may only hold TRUE (1) or FALSE (0)
- values.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-int8_t
-\emph default 
- Is used everywhere byte-sized signed elements are explicitely required,
- from -127 to +128, except for strings where the standard C 
-\emph on 
-char
-\emph default 
- type should be used.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int8_t
-\emph default 
- Should be used where unsigned byte-sized elements are required, for 0-255
- values.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-int16_t
-\emph default 
- Is the data type used for 16-bit signed integers values, -32768 to +32767.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int16_t
-\emph default 
- The unsigned 16-bit value data type which can old 0 to 65535.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-int32_t
-\emph default 
- For use with 32-bit signed data types
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int32_t
-\emph default 
- 32-bit unsigned data type
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-int64_t
-\emph default 
- signed 64-bit data type (usually typedef with 
-\emph on 
-long long
-\emph default 
-)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int64_t
-\emph default 
- unsigned 64-bit data type.
- It is to be noted that operations on 64-bit objects is generally slow as
- it requires multiple instructions on 32-bit architectures.
- Currently, no 64-bit data types are beign used anymore, the few ones which
- used it were converted to use 32-bit ones instead.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-size_t
-\emph default 
- Used to represent a size in bytes, this in fact is equivalent to 
-\emph on 
-u_int32_t
-\emph default 
-.
-\emph on 
-size_t
-\emph default 
- should not be used to represent arbitary types amounts, but byte amounts
- only (corresponding to a number of 
-\emph on 
-char
-\emph default 
-, 
-\emph on 
-u_int8_t
-\emph default 
- or 
-\emph on 
-int8_t
-\emph default 
- types).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-ssize_t
-\emph default 
- Purpose is the same as for 
-\emph on 
-size_t
-\emph default 
-, but this can hold -1 for error.
-\layout Standard
-
-And other frequently used standard Xisop types, which are still defined
- in <
-\emph on 
-common/types.h
-\emph default 
->, but have their corresponding structures defined at their respective locations
- (mentionned in parentheses):
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-node_t
-\emph default 
- A doubly linked list node to be used in 
-\emph on 
-list_t
-\emph default 
- type lists.
- (common/kernlib/list.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-list_t
-\emph default 
- A doubly linked list (common/kernlib/list.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-mchunk_t
-\emph default 
- A chunk of contiguous memory pages, part of a 
-\emph on 
-ppool_t
-\emph default 
- (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-page_t
-\emph default 
- A physical memory page, or a number of contiguous physical memory pages,
- holding the necessary information for freeing back.
- (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-ppool_t
-\emph default 
- A system pool of pages, that is, what other pools allocate pages from.
- (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pool_t
-\emph default 
- A efficient fixed sized objects (
-\emph on 
-pnode_t
-\emph default 
-) memory pool with internal statistical page cacheing, which can optionally
- dynamically grow and shrink, or be static in size (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pnode_t
-\emph default 
- A pool object node, which must prefix any pool object.
- This type internally begins with a 
-\emph on 
-node_t
-\emph default 
- and can therefore be used directly for queuing in 
-\emph on 
-list_t
-\emph default 
-.
- (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-mpool_t
-\emph default 
- A multiple 
-\emph on 
-pool_t
-\emph default 
- memory pool used to serve multiple sized blocks requests.
- Of various memory types.
- Bocks which are too large are rounded at page boundaries.
- (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-mnode_t
-\emph default 
- Internally used by the 
-\emph on 
-mpool_t
-\emph default 
- related allocation primitives (common/kernel/memory.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-facility_t
-\emph default 
- A public interrupt facility which the port-specific code initializes calling
- the common 
-\emph on 
-facility_init()
-\emph default 
- function.
- (common/kernel/exception.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hook_t
-\emph default 
- An interrupt, trap or exception code vector attached to a 
-\emph on 
-facility_t
-\emph default 
-.
- (common/kernel/exception.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hookid_t
-\emph default 
- An 
-\emph on 
-hook_t
-\emph default 
- ID, internally a 
-\emph on 
-u_int32_t
-\emph default 
-, which is guarranteed to be unique for the facility it belongs to.
- (common/kernel/exception.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-task_t
-\emph default 
- Task structure (common/kernel/task.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-priority_t
-\emph default 
- A task priority number (common/kernel/task.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-signum_t
-\emph default 
- Signal number (common/kernel/signal.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-sigmask_t
-\emph default 
- Signal mask which can represent one or more 
-\emph on 
-signum_t
-\emph default 
-.
- (common/kernel/signal.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-port_t
-\emph default 
- Message port (common/kernel/port.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-message_t
-\emph default 
- A message header structure which comports the glue to queue messages in
-\emph on 
-port_t
-\emph default 
- (common/kernel/port.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-device_t
-\emph default 
- An open device handler (common/kernel/device.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-devicenode_t
-\emph default 
- A linked device hook (common/kernel/device.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-iorequest_t
-\emph default 
- An I/O request message type used for 
-\emph on 
-device_t
-\emph default 
- requests (common/kernel/device.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-fifo8_t
-\emph default 
- An 8-bit elements FIFO buffer.
-\emph on 
-fifo
-\emph default 
-*
-\emph on 
-_t
-\emph default 
- types are implemented as a fixed bytes buffer once initialized, rather
- than using linked lists.
- It is possible to easily create new 
-\emph on 
-fifo
-\emph default 
-*
-\emph on 
-_t
-\emph default 
- types of arbitrary object sizes using a macro.
- (common/kernlib/fifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-fifo16_t
-\emph default 
- A 16-bit elements FIFO buffer (common/kernlib/fifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-fifo32_t
-\emph default 
- A 32-bit elements FIFO buffer (common/kernlib/fifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-lifo8_t
-\emph default 
- A 8-bit elements LIFO buffer.
-\emph on 
-lifo
-\emph default 
-*
-\emph on 
-_t
-\emph default 
- types operate like stacks, and are internally implemented as a fixed bytes
- buffer once initialized, rather than using linked lists.
- A macro is provided to easily create new types of 
-\emph on 
-lifo
-\emph default 
-*
-\emph on 
-_t
-\emph default 
- for objects of arbitrary size.
- (common/kernlib/lifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-lifo16_t
-\emph default 
- A 16-bit elements LIFO buffer (common/kernlib/lifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-lifo32_t
-\emph default 
- A 32-bit elements LIFO buffer (common/kernlib/lifo.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hashtable_t
-\emph default 
- A hash lookup table (common/kernlib/hash.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hashnode_t
-\emph default 
- A hash lookup table node (common/kernlib/hash.h>
-\layout Standard
-
-And here are the processor and architecture specific opaque data types they
- provide:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_ipl_t
-\emph default 
- Abstract Interrupt Priority Level type, associated with the 
-\emph on 
-_spl
-\emph default 
-n
-\emph on 
-()
-\emph default 
- and 
-\emph on 
-_splx()
-\emph default 
- functions.
- (processor/support.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_ctx_t
-\emph default 
- Abstract processor-specific supplied context handle, associated to 
-\emph on 
-_ctx_init()
-\emph default 
- function which is used by 
-\emph on 
-task_alloc()
-\emph default 
- and internal kernel context switching.
- (processor/support.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_lock_t
-\emph default 
- Abstract processor-specific supplied atomic simple lock handle.
- Associated to the 
-\emph on 
-_lock_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions.
- (processor/support.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_rlock_t
-\emph default 
- An abstract atomic recursive lock handle (needs to be unlocked the same
- number of times it was locked to free the 
-\emph on 
-_rlock_t
-\emph default 
-).
- Associated to the 
-\emph on 
-_rlock_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions.
- (processor/support.h)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-XXX
-\emph default 
- The 64-bit related types are currently unused.
- On most processors the GCC compiler requires additional libraries to support
- these, which are currently not part of Xisop.
- There however exist such implementations fully written in C, like the one
- used on BSD systems which would not be hard to include if it was necessary.
- An effort was made to also not include software which requires the use
- of floating point, for code size and efficiency.
-\layout Subsubsection
-
-Programming style and conventions
-\layout Standard
-
-It is a fact that consistency is a must for readibility, especially in an
- open source project which many others may need to modify to suit their
- particular needs.
- The following programming conventions are used, and are defined for assembly
- and C code.
-\layout Paragraph
-
-Function names
-\layout Standard
-
-All functions which are not behaving identically to ANSI-C or POSIX or other
- widely standarized ones, but have the same name should have their name
- prefixed by an underscore ('_').
- Others which behave exactly like the standards should have the same name
- the standard expects.
- Other functions which have nothing in common with standard names should
- not be prefixed by underscores, except for the defined processor and port-speci
-fic functions, which names should also begin with an underscore.
- Of course, if a hardware-specific function is provided as a replacement
- to a common portable one for performance considerations, it obviously should
- bear the same name, however.
-\layout Paragraph
-
-Formatting
-\layout Standard
-
-Line termination should consist of 
-\begin_inset Quotes eld
-\end_inset 
-
-
-\backslash 
-n
-\begin_inset Quotes erd
-\end_inset 
-
- (linefeed, as is used on Amiga and Unix), rather than 
-\begin_inset Quotes eld
-\end_inset 
-
-
-\backslash 
-r
-\backslash 
-n
-\begin_inset Quotes erd
-\end_inset 
-
- which is used on MS-DOS and Windows for text file storage.
- Other than tab (
-\begin_inset Quotes eld
-\end_inset 
-
-
-\backslash 
-t
-\begin_inset Quotes erd
-\end_inset 
-
-) and linefeed (
-\begin_inset Quotes eld
-\end_inset 
-
-
-\backslash 
-n
-\begin_inset Quotes erd
-\end_inset 
-
-), no other control characters should be found within the source files.
- Moreover, every line of the source files should not exceed 79 characters.
-\layout Paragraph
-
-C language sections
-\layout Standard
-
-It is important that C files be using the standard eight (8) tab size for
- real tabs.
- However, the software tab should consist of four (4) characters.
- Tabs should be used where 8 space tabs are needed, and spaces used to fill
- the 4 character tabs.
- When using the VIm editor, these should be used: 
-\emph on 
-ts=8
-\emph default 
-, 
-\emph on 
-sw=4
-\emph default 
-, and 
-\emph on 
-cindent
-\emph default 
-.
- This allows the files to be printable using text file viewers properly
- at all times, and to also be printable as-is on most printers.
-\emph on 
-XXX
-\emph default 
- Add settings for emacs
-\layout Itemize
-
-C program suffix should consist of lower case 
-\emph on 
-.c
-\layout Itemize
-
-C headerfiles should use the lower case suffix 
-\emph on 
-.h
-\layout Itemize
-
-ANSI-C programming norms should be observed as much as possible.
-\layout Itemize
-
-ANSI convention for function arguments specification rather than K&R.
-\layout Itemize
-
-BSD programming style used rather than GNU style, especially for opening
- and closing braces convention.
- This corresponds to the formatting performed using GNU indent program with
- the following parameters: 
-\emph on 
-gindent -kr -ncs <file>.c
-\layout Itemize
-
-Functions and global variables which are specific to the current module
- should be declared 
-\emph on 
-static
-\emph default 
-, and their prototypes should be in a private headerfile or in the current
- C source file, not in a public headerfile which is included by any other
- C source module.
-\layout Itemize
-
-Macros and variables directly refering to hardware architecture-specific
- registers should use the 
-\emph on 
-volatile
-\emph default 
- keyword.
-\layout Itemize
-
-Every function must have a corresponding prototype, defined either at the
- top of the current C file (if static) or in a corresponding headerfile
- (public ones).
-\layout Itemize
-
-For kernel code, the conventions should be followed about the choice of
- variable types to use (described in the previous section).
-\layout Itemize
-
-No C++ or other language should be used within the kernel code.
- Of course there is no such restriction for any user program.
-\layout Itemize
-
-Code should obviously be commented as required for clarity, but 
-\emph on 
-
-\begin_inset Quotes eld
-\end_inset 
-
-/*
-\begin_inset Quotes erd
-\end_inset 
-
-
-\emph default 
- and 
-\emph on 
-
-\begin_inset Quotes eld
-\end_inset 
-
-*/
-\begin_inset Quotes erd
-\end_inset 
-
-
-\emph default 
- C-style delimited comments only are allowed, not 
-\emph on 
-
-\begin_inset Quotes eld
-\end_inset 
-
-//
-\begin_inset Quotes erd
-\end_inset 
-
-
-\emph default 
- C++ ones.
-\layout Itemize
-
-Code should not invoke general purpose memory allocation routines when a
- special fast access pool was provided already to allocate and free these
- types of items.
- Where appropriate, the general kernel objects pool system should be expanded
- when a new object is frequently allocated and freed, rather than using
- the general purpose management functions.
- These obviously should be common, machine-independent objects (which can
- possibly use machine-specific definitions, if they become standard and
- documented in this document so all ports provide them).
- See the memory management section later on for more information.
-\layout Itemize
-
-General purpose libraries supplied in 
-\emph on 
-src/common/kernlib/
-\emph default 
- should normally have each function implemented as a separate C file into
- the library's directory.
- During the build process they will get compiled independently, and then
- archived together using 
-\emph on 
-ar
-\emph default 
-.
-\emph on 
-ranlib
-\emph default 
- will then be executed on the archive.
- This ensures that unused functions do not be included into the end kernel
- result, reducing kernel size considerably when full multipurpose libraries
- are used (such as complete string libraries).
-\layout Paragraph
-
-Assembly sections
-\layout Standard
-
-For assembly sections, the AT&T style should be observed, and the assembly
- should not be embedded into the C code using inline assembly routines.
- Often a library requireing both assembly and C will at build time assemble
- it's assembly section file (
-\emph on 
-.s
-\emph default 
-), compile it's C part (
-\emph on 
-.c
-\emph default 
-), and link the two together into an object file (
-\emph on 
-.o
-\emph default 
-) using the 
-\emph on 
--r
-\emph default 
- linker switch, which then gets linked with the kernel.
- In other situations one may want to instead compile all modules to objects
- (
-\emph on 
-.o
-\emph default 
-), create an 
-\emph on 
-ar
-\emph default 
- archive (
-\emph on 
-.a
-\emph default 
-), run 
-\emph on 
-ranlib
-\emph default 
- on it, and link it to the kernel (in which case all unused functionality
- which was isolated into it's own module does not get included by the linker,
- reducing kernel size).
- This applies to both processor-specific and architecture-specific backends.
- The rest is written in C.
- It is encouraged to write most of the architecture-specific boot loader
- code in C and provide a companion assembly file to interface and call the
- C loader main function.
- This minimizes assembly code, and C is more consistant and readable, it
- can be more suitable to sometimes write tricky sections like relocators,
- etc.
-\layout Standard
-
-The assembly sections should ensure to be reeintrant, that is, using the
- stack to save registers rather than using temporary registers to save other
- registers, and using the stack as well for temporary variables for which
- registers cannot be used, rather than static memory locations.
- These are usually indended to be called from C, and because of the way
- Xisop shared libraries work, is a main reason to follow these directives.
- An assembly section which is known to execute uninterruptably may at it's
- discretion use static memory if needed.
-\layout Itemize
-
-Assembly files should have the following lowercase suffix: 
-\emph on 
-.s
-\layout Itemize
-
-Tabulation should be set to use real tabs (not spaces), with a standard
- tab width of 8.
-\layout Itemize
-
-Assembler opcodes should be located after the first tab.
-\layout Itemize
-
-Operands should be located after the second tabulation.
-\layout Itemize
-
-Where more than an operand is required and are separated by a comma, a space
- is required after the comma.
-\layout Itemize
-
-Opcode names should be lowercase, and must match those shown by objdump
- when dissassembling.
- This allows consistancy between all code for a particular processor.
- Although this may sound tidious at first, it is not as hard as it sounds
- to learn the specific mnemonic names objdump displays, with some little
- practice.
- Adventages results in consistency, where it also becomes possible to locate
- specific instructions in the code with regular expressions, etc.
-\layout Itemize
-
-
-\emph on 
-.equ
-\emph default 
- and 
-\emph on 
-=
-\emph default 
- directives, if any, should be located at the top of the assembly file.
-\layout Itemize
-
-
-\emph on 
-.globl
-\emph default 
- directives to declare public functions should also be located at the top
- of the file.
-\layout Itemize
-
-All code should be within the 
-\emph on 
-.text
-\emph default 
- section, along with any static memory variables if need be (although use
- of these is discouraged, except for instance in the kernel loader bootblock
- where they can be useful, or in special context code where one knows what
- he's doing rather than only using the stack).
-\layout Itemize
-
-A comment on a line or two should be placed before each function, especially
- the ones which are intended to be called from C, along with the C prototype.
-\layout Itemize
-
-Other comments should be found along the code where required for obviousness.
-\layout Itemize
-
-Obviously, registers which a function modifies should be saved in the stack,
- and restored upon function return, except (if any) the register corresponding
- to the return code expected in C for that processor.
-\layout Itemize
-
-Interrupt, trap and exception assembly sections should normally save all
- registers which are commonly used for the particular processor, and restore
- them before returning.
- It is wrong to assume that C compiled functions always save all registers
- they modify other than the expected result register.
- This was learned from experience using GCC.
-\layout Subsection
-
-Xisop scheduler and inter-task communication
-\layout Subsubsection
-
-The multitasking scheduler
-\layout Standard
-
-The scheduler currently allows to set priorities for each task, between
- -128 and 127.
- It is preemptive and will make sure to allow other tasks to run even when
- a particular task hugs the CPU by not going to sleep.
- A task can be in two main states: running, and sleeping.
-\layout Standard
-
-When a task sleeps, it has a mask of signals that will awake it as soon
- as possible if it receives any signal it waits for, and leaves more opportuniti
-es for other tasks to execute their shores when it is sleeping.
- When a task runs, it usually executes it's shores and goes back to sleep
- for the next event to process, when running in a multitasking system.
- However, if it does not return to sleep fast enough, the scheduler preemtive
- nature will suspend it and allow other tasks to also get a fair CPU time
- share, depending on the priority of the running tasks, unless the task
- has disabled scheduling, in which case it will remain running until it
- decides to delegate control to the system again.
-\layout Standard
-
-The task priority controls the speed and frequency at which a running task
- awakes, or runs.
- What the scheduler does is assign a set of credits to all tasks in the
- run queue, according to their priority one another.
- Then using round-robin at each scheduler round, the task with the highest
- amount of credits is given some CPU time, and a credit is taken out from
- it.
- If a task expired it's credits, it is no longer given a round, until all
- other tasks also expired their credits.
- When this happens, all tasks are given credits according to their priority
- again.
- Some care is taken to not constantly give a turn to the last task even
- if it has more credits, to allow to make the best out of Xisop asynchroneous
- facilities, but such a high priority task will have more turns within the
- run still, observing it's relative priority to the others.
-\layout Standard
-
-When a task goes to sleep, it is immediately taken out of the run queue
- and will not be awaken until a signal it awaits for is received.
- When it does, it will be moved in the running queue as fast as possible,
- at which point the time elapsing before it can act to the signal is directly
- dependent on the priority of the task related to the other ready to run
- tasks.
- However, when the task is moved in the run queue, it is immediately given
- it's credits at the maximum it's priority permits, thus increasing the
- chances it can answer in a fast manner among the other tasks in the run
- queue, which may already have been there before, and elapsed their credits.
-\layout Standard
-
-This means that if all tasks run with the default priority of 0, they all
- get a fair share of the CPU, and are naturally awaking very fast when one
- get a signal.
- In the case where one of the tasks remains running, the speed of signal
- responsiveness will ususally consist of the frequency of the scheduler.
- This frequency is usually configurable, and depends on the capacity of
- the timers available for the particular architecture (and of course on
- CPU speed).
-\layout Standard
-
-In the case where the scheduler detects that all tasks are sleeping, it
- attempts to reduce it's CPU usage by calling the 
-\emph on 
-_idle()
-\emph default 
- processor-specific function, which will only awaken the scheduler again
- when the next interrupt, trap or exception occurs.
- It is possible in Xisop to have dead locked tasks, if they decide to wait
- for no signals, or if they wait for a signal to occur which never does.
-\layout Standard
-
-Following are described all functions which are related to tasks and scheduler,
- or which are useful to synchronize resources, other than the 
-\emph on 
-signal_t
-\emph default 
- and 
-\emph on 
-port_t
-\emph default 
- based systems, which are described in a further section.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-task_t\SpecialChar ~
-*task_alloc(int\SpecialChar ~
-(*start)(void\SpecialChar ~
-*,\SpecialChar ~
-void\SpecialChar ~
-*), void\SpecialChar ~
-*res,\SpecialChar ~
-void\SpecialChar ~
-*args,\SpecialChar ~
-priority_t\SpecialChar ~
-priorit
-y,\SpecialChar ~
-size_t\SpecialChar ~
-stacksize,\SpecialChar ~
-u_int8_t\SpecialChar ~
-flags)
-\emph default 
- Allocates a task which can then be started or freed back.
-\emph on 
-start
-\emph default 
- specifies the entry point function, 
-\emph on 
-res
-\emph default 
- an optional pointer to a buffer for results which the task may need to
- use or NULL, and 
-\emph on 
-args
-\emph default 
- an optional pointer to a buffer which may be used by the task to obtain
- it's argument, or NULL.
- When 
-\emph on 
-start
-\emph default 
- is called, 
-\emph on 
-res
-\emph default 
- is passed as the first argument and 
-\emph on 
-args
-\emph default 
- as the second one.
-\emph on 
-priority
-\emph default 
- consists of the task initial running priority which may be in the range
- of -128 to 127, 0 being the normal running priority.
-\emph on 
-stacksize
-\emph default 
- specifies the size of the stack in bytes which should be dedicated to the
- task, a common size being 4096 bytes.
-\emph on 
-flags
-\emph default 
- may be 0, or ORed 
-\emph on 
-TS_
-\emph default 
-* flags which are defined in <
-\emph on 
-src/common/kernel/task.h
-\emph default 
->.
- The task is not yet launched by Xisop.
- If the 
-\emph on 
-TS_SHARED
-\emph default 
- flag is supplied, this task will use the 
-\emph on 
-mpool_t
-\emph default 
- of it's parent (the current task which allocates it).
- This means that all memory allocated by one of the tasks sharing a memory
- pool is inherently shared.
- One task ending will not cause the allocated regions to be freed unless
- explicitely freed.
- When all tasks shareing a memory pool exit, all allocated memory by any
- of them is automatically freed back.
- This feature can be used when memory should inherently be shared among
- the tasks, or when memory resources are very scarce.
- However, unlike using Xisop messages which provide synchronization to share
- arbitrary memory regions among tasks, implicit synchronization should be
- used by the tasks when accessing the same shared memory locations which
- they should access concurrently.
- For this, 
-\emph on 
-rwlock_t
-\emph default 
- and 
-\emph on 
-_lock_t
-\emph default 
- based systems can be used, or a custom system based around Xisop signals
- and/or messages.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-task_t\SpecialChar ~
-*task_free(task_t\SpecialChar ~
-*task)
-\emph default 
- Allows to free 
-\emph on 
-task
-\emph default 
- which was previously allocated by 
-\emph on 
-task_alloc()
-\emph default 
-.
- Only tasks which have been allocated but which have not been launched may
- be freed using this function, or it internally does nothing.
- NULL is returned.
- The kernel automatically frees tasks which have been launched when they
- exit.
- When a task is freed, all the resources it allocated using standard Xisop
- functions are automatically freed back to the system as well.
- The exception is when the task was setup with the 
-\emph on 
-TS_SHARED
-\emph default 
- flag, where the memory is only freed when all tasks sharing that memory
- pool ended.
- This does not affect message ports, signals, devices, libraries or handlers,
- however, which are released by each task, always, as they exit.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-task_start(task_t\SpecialChar ~
-*task)
-\emph default 
- Launches 
-\emph on 
-task
-\emph default 
- which should have previously been allocated using 
-\emph on 
-task_alloc()
-\emph default 
-.
- The task is moved to the ready queue and will start executing as soon as
- the current task yields calling 
-\emph on 
-_yield()
-\emph default 
- or is preempted by the scheduler.
- The delay for it to actually execute also depends on the relative priority
- of the tasks on the ready queue and their current credits.
- If synchronization is needed with it's startup, signals or messages can
- be used.
- TRUE is returned on success, or FALSE if the task is invalid, or was already
- launched.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-task_end(task_t\SpecialChar ~
-*task)
-\emph default 
- Immediately forces termination of the specified 
-\emph on 
-task
-\emph default 
-, which may consist of the current task, or of another task.
- The task is cleanly freed as if it exited itself.
- Can also be used on a task which is locked on the waiting queue, perhaps
- waiting for events it will never receive.
- When a task ends and needs to be freed, it is moved in a queue for a dedicated
- task called the reaper, which chores consist of freeing all resources related
- to each task and the tasks themselves on it's own scheduler CPU time slices.
- Other tasks and the kernel are then releaved from that work.
- When a task ends it will soon automatically be freed by Xisop, and the
- resources it allocated are automatically freed as well.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_yield(task_t\SpecialChar ~
-*task)
-\emph default 
- Permits a currently running task to immediately yield control back to the
- scheduler to allow other tasks to have an immediate opportunity to execute,
- rather than leaving the preemtive scheduler interrupt it.
- The task is not moved to the wait queue, and will have an opportunity to
- resume again very soon.
-\emph on 
-task
-\emph default 
- consists of a suggestion to which task to delegate control to, which should
- also currently be in the ready queue.
- When 
-\emph on 
-task
-\emph default 
- is invalid or NULL, the scheduler is left to decide which task to execute
- next.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-task_sleep(task_t\SpecialChar ~
-*task,\SpecialChar ~
-u_int32_t\SpecialChar ~
-flags,\SpecialChar ~
-task_t\SpecialChar ~
-*yield)
-\emph default 
- Allows to immediately switch the specified task (which may also be the
- currently running task) to the waiting queue.
- The task will be unable to execute again until it is specifically moved
- back again on the ready queue by calling 
-\emph on 
-task_wakeup()
-\emph default 
- on it with at least one of the same bits in 
-\emph on 
-flags
-\emph default 
-.
- This can be useful when custom interrupt attached code hooks need to synchroniz
-e tasks and such and that signals and message ports are not desired.
- If the task being put to sleep consists of the current task, 
-\emph on 
-yield
-\emph default 
- can specify another optional ready task to run immediately, if non-NULL.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-task_wakeup(task_t\SpecialChar ~
-*task,\SpecialChar ~
-u_int32_t\SpecialChar ~
-flags)
-\emph default 
- Immediately awakes the specified task if it currently is sleeping in the
- waiting queue.
- This is normally used after a 
-\emph on 
-task_sleep()
-\emph default 
- call was made on the task.
- However, it is possible to use this function to wake a task which is waiting
- for a signal as well if 
-\emph on 
-TSF_SIGNAL
-\emph default 
- flag is specified.
- This is normally used by custom interrupt hooks which need to synchronize
- tasks, when they cannot use signals or message ports.
- They then can share a 
-\emph on 
-fifo_t
-\emph default 
- buffer, or custom 
-\emph on 
-list_t
-\emph default 
- queue, with the wanted tasks and cause them to awake and sleep at will
- for instance.
- The task is only awaken if at least one bit supplied in 
-\emph on 
-flags
-\emph default 
- matches one of the bits of the 
-\emph on 
-flags
-\emph default 
- which were used at 
-\emph on 
-task_sleep()
-\emph default 
-.
- TRUE is returned if the task could be awaken, or FALSE if the flags do
- not permit to awake it or another problem occurs.
-\layout Standard
-
-The current sleeping flags are described as follows (as defined in <
-\emph on 
-src/common/kernel/scheduler.h
-\emph default 
->) :
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-TSF_KERNEL
-\emph default 
- Kernel-reserved, used by the task reaper for instance.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-TSF_SIGNAL
-\emph default 
- Task is waiting for the reception of at least of one of the signal bits
- in 
-\emph on 
-task_t->sigwait
-\emph default 
-.
- Internally used bu the signal subsystem.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-TSF_CUSTOM
-\emph default 
- As the name implies, may be used by user tasks.
-\layout Standard
-
-Here are then described the scheduler control functions:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-priority_t\SpecialChar ~
-task_getpriority(task_t\SpecialChar ~
-*task)
-\emph default 
- Obtains the current running priority level of 
-\emph on 
-task
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-priority_t\SpecialChar ~
-task_setpriority(task_t\SpecialChar ~
-*task,\SpecialChar ~
-priority_t\SpecialChar ~
-p)
-\emph default 
- Permits to change the running priority of 
-\emph on 
-task
-\emph default 
- to 
-\emph on 
-p
-\emph default 
-.
- Returned is the previous priority of 
-\emph on 
-task
-\emph default 
- which could be used to restore it.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sched_disable(void)
-\emph default 
- Allows to disable the preemptive scheduler, which will only be re-enabled
- when a corresponding number of 
-\emph on 
-sched_enable()
-\emph default 
- have been called, as the scheduler lock consists of a recursive 
-\emph on 
-_rlock_t
-\emph default 
-.
- It is important to not call 
-\emph on 
-yield()
-\emph default 
-, 
-\emph on 
-port_wait(), port_send(), signal_send()
-\emph default 
- or 
-\emph on 
-signal_wait()
-\emph default 
- when the scheduler is disabled, because it would prevent the task from
- ever being awaken again.
- Obviously, this call should be used with care, if any.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sched_enable(void)
-\emph default 
- Re-enables the scheduler if the same number of instances of this function
- matched with the previous 
-\emph on 
-sched_disable()
-\emph default 
- calls.
-\layout Subsubsection
-
-Locks and synchronization primitives
-\layout Standard
-
-Other synchronization systems such as signals and message ports are later
- described in a next section.
- However, these are also very useful synchronization primitives which Xisop
- provides to both kernelspace and userspace software:
-\layout Paragraph
-
-Exclusive access locks
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_init(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Initializes an exclusive access a lock.
- This has to be used before using other functions 
-\emph on 
-lock
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_acquire(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- This function is not multitasking-friendly in that the current task loops
- in an endless loop until exclusive obtention of the 
-\emph on 
-_lock_t
-\emph default 
- is acquired.
- Tasks should normally use 
-\emph on 
-lock_acquire()
-\emph default 
- instead.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_release(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Immediately releases the exclusive 
-\emph on 
-_lock_t
-\emph default 
-\emph on 
-lock
-\emph default 
- to allow another locker to obtain it.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_lock_try(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Attempts to exclusively acquire 
-\emph on 
-lock
-\emph default 
-, but returns immediately with FALSE if it cannot.
- TRUE is returned on success.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_lock_available(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Returns TRUE if there currently are no locker on 
-\emph on 
-lock
-\emph default 
-, but does not attempt to lock it.
- It is unsafe to attempt to implement 
-\emph on 
-_lock_try()
-\emph default 
- using this function, obviously.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-lock_acquire(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Similarily to 
-\emph on 
-_lock_acquire()
-\emph default 
-, locks execution of the current task until 
-\emph on 
-lock
-\emph default 
- is exclusively obtained.
- This function is however better according to multitasking as it immediately
- yields CPU time to allow the current locker to free it as soon as possible
- for the current task to own it.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-lock_release(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Identical to 
-\emph on 
-_lock_release()
-\emph default 
-, made to match 
-\emph on 
-lock_acquire()
-\emph default 
- for consistency.
-\layout Paragraph
-
-Recursive locks
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_init(_rlock_t\SpecialChar ~
-*lock)
-\emph default 
- Initializes a recursive lock of type 
-\emph on 
-_rlock_t
-\emph default 
-.
- This needs to be performed before calling other recursive lock operations
- on 
-\emph on 
-lock
-\emph default 
-.
- Recursive locks are different from exclusive locks in that there can be
- any number of concurrent lockers at the same time.
- They are usually used for systems which execute at intervals, like the
- Xisop scheduler and interrupt facilities which also make use of this system.
- They can then make sure to be the only locker before performing their critical
- work.
- This way arbitrary tasks may disable the facilities safely by locking the
- lock, and unlocking it when they are done with their critical section.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_acquire(_rlock_t\SpecialChar ~
-*lock)
-\emph default 
- Locks recusively the 
-\emph on 
-lock
-\emph default 
-\emph on 
-_rlock_t
-\emph default 
-.
- This basically atomically increases the lockers counter of the lock, and
- never fails.
- It always returns immediately.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_release(_rlock_t\SpecialChar ~
-*lock)
-\emph default 
- Releases the 
-\emph on 
-lock
-\emph default 
-\emph on 
-_rlock_t
-\emph default 
-.
- Note that the same number of release operations must be performed on 
-\emph on 
-lock
-\emph default 
- for it to become available again.
- This only atomically decreases the lockers counter of the lock, and returns
- immediately.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_rlock_trylock(_rlock_t\SpecialChar ~
-*lock)
-\emph default 
- If the lock is free/available, that is, no current lockers exist on 
-\emph on 
-lock
-\emph default 
-, this function atomically locks it and returns TRUE immediately.
- Otherwise it returns FALSE and returns immediately, in which case the lock
- is left in it's original state before the call.
- This can be very useful for an event-driven system which needs to make
- sure that the lock is free to perform it's tasks, but also needs to prevent
- it's own recursion.
- Obviously, if it returned TRUE, 
-\emph on 
-_rlock_release()
-\emph default 
- is expected to be called when done.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_rlock_available(_rlock_t\SpecialChar ~
-*lock)
-\emph default 
- Returns FALSE if there are any lockers on 
-\emph on 
-lock
-\emph default 
-, or TRUE if the lock is currently free from any lockers.
- This however only performs the check, and does not change the lock state.
- It is unsafe to use this function along with 
-\emph on 
-_rlock_acquire()
-\emph default 
- to implement a 
-\emph on 
-_rlock_trylock()
-\emph default 
- replacement as it would not be atomic.
-\layout Paragraph
-
-Read/Write locks
-\layout Standard
-
-These locks internally consist of a combination of exclusive and recursive
- locks.
- They are ideal for instance to protect synchronization of resources where
- multiple readers are allowed but that exclusive access is required for
- write operations.
- There currently is provided no way to upgrade a currently held shared access
- lock to an exclusive lock, or to downgrade an exclusively held lock to
- a shared access lock, other than releasing the lock and re-locking it.
- However, if this proves necessary in the future, we shall implement these
- features.
- These locks are especially adequate to protect resources which are frequently
- accessed in read-only mode, but which occasionally need to be updated,
- which obviously requires write/exclusive access, which is the case with
- several Xisop system lists, and these locks are then used by the involved
- kernel functions as well.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-rwlock_init(rwlock_t\SpecialChar ~
-*lock)
-\emph default 
- Initializes 
-\emph on 
-lock
-\emph default 
-, which is necessary before using any other 
-\emph on 
-rwlock_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- function on it.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-rwlock_acquire(rwlock_t\SpecialChar ~
-*lock,\SpecialChar ~
-bool\SpecialChar ~
-exclusive)
-\emph default 
- Locks the current task until the 
-\emph on 
-lock
-\emph default 
-\emph on 
-rwlock_t
-\emph default 
- can be exclusively accessed (for read and/or writing access) if 
-\emph on 
-exclusive
-\emph default 
- is TRUE, or until a shared recursive access is obtained (for read-only
- access) if 
-\emph on 
-exclusive
-\emph default 
- is FALSE.
- Is multitasking-safe.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-rwlock_release(rwlock_t\SpecialChar ~
-*lock)
-\emph default 
- Releases the access on 
-\emph on 
-lock
-\emph default 
- which was obtained using 
-\emph on 
-rwlock_acquire()
-\emph default 
- or 
-\emph on 
-rwlock_try()
-\emph default 
-.
- Whether this access was exclusive or shared is internally remembered.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-rwlock_try(rwlock_t\SpecialChar ~
-*lock,\SpecialChar ~
-bool\SpecialChar ~
-exclusive)
-\emph default 
- Very similar to 
-\emph on 
-rwlock_acquire()
-\emph default 
- but always immediately returns with FALSE if the access cannot be obtained
- immediately.
- TRUE is returned with the lock held on success.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-rwlock_upgrade(rwlock_t\SpecialChar ~
-*lock)
-\emph default 
- Permits to upgrade an already obtained shared lock to an exclusive lock.
- The current task may sleep as required until all shared lockers free their
- lock.
- The caller 
-\emph on 
-MUST
-\emph default 
- already be holding the lock in shared mode.
- This function is most useful for operations such as check-and-modify, when
- read-only access is generally required to a resource, but that under certain
- conditions write access is needed to modify the resource after the check.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-rwlock_downgrade(rwlock_t\SpecialChar ~
-*lock)
-\emph default 
- Conversely to 
-\emph on 
-rwlock_upgrade()
-\emph default 
-, allows to downgrade an already obtained exclusive lock to a shared lock.
- The caller 
-\emph on 
-MUST
-\emph default 
- already be holding this lock in exclusive mode.
- The usefulness of this function is questionable.
- Although provided, the kernel does not use it.
-\layout Paragraph
-
-System lists access
-\layout Standard
-
-Several system lists require internal 
-\emph on 
-rwlock_t
-\emph default 
- for synchronization against corruption.
- In <
-\emph on 
-common/kernel/main.h
-\emph default 
-> are defined several macros which can be used to access those securely
- by kernel functions.
- The 
-\emph on 
-enum systables
-\emph default 
- specifies various system lists which can be accessed using these methods,
- called 
-\emph on 
-SYSTABLE_
-\emph default 
-*.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-SYSTABLE_RLOCK(enum\SpecialChar ~
-systables\SpecialChar ~
-table)
-\emph default 
- Locks the 
-\emph on 
-rwlock_t
-\emph default 
- of the specified 
-\emph on 
-table
-\emph default 
-, in shared mode (read-only access).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-SYSTABLE_WLOCK(enum\SpecialChar ~
-systables\SpecialChar ~
-table)
-\emph default 
- Locks the 
-\emph on 
-rwlock_t
-\emph default 
- of the specified 
-\emph on 
-table
-\emph default 
-, in exclusive mode (read/write access).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-SYSTABLE_UNLOCK(enum\SpecialChar ~
-systables\SpecialChar ~
-table)
-\emph default 
- Unlocks the 
-\emph on 
-rwlock_t
-\emph default 
- of the specified 
-\emph on 
-table
-\emph default 
-, which should have previously been locked using 
-\emph on 
-SYSTABLE_RLOCK()
-\emph default 
- or 
-\emph on 
-SYSTABLE_WLOCK()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-SYSTABLE_UPGRADE(enum\SpecialChar ~
-systables\SpecialChar ~
-table)
-\emph default 
- Allows a caller which 
-\emph on 
-MUST
-\emph default 
- hold a shared read-only access lock (after using 
-\emph on 
-SYSTABLE_RLOCK()
-\emph default 
-) to upgrade the lock to exclusive mode.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hashtable_t\SpecialChar ~
-*SYSTABLE(enum\SpecialChar ~
-systables\SpecialChar ~
-table)
-\emph default 
- Returns the 
-\emph on 
-hashtable_t
-\emph default 
- pointer associated with the system list 
-\emph on 
-table
-\emph default 
-.
- Obviously, this should only be used when the lock is held, and should only
- be used for the access corresponding to the currently obtained lock type.
-\layout Standard
-
-The following two functions, as opposed to macros, are implemented as C
- functions and perform boundary checking on the arguments, as they are provided
- for user tasks rather than for the kernel, for which the previous macros
- were designed:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hashtable_t\SpecialChar ~
-*systable_lock(u_int32_t\SpecialChar ~
-systable,\SpecialChar ~
-bool\SpecialChar ~
-exclusive)
-\emph default 
- Attempts to lock access to the system list 
-\emph on 
-systable
-\emph default 
-, in exclusive or shared mode.
- A pointer to the 
-\emph on 
-hashtable_t
-\emph default 
- is returned on success, or NULL otherwise.
- As usual, shared locks should be obtained when read-only access is performed
- on a list, but an exclusive lock is required if there is any need to modify
- a system list.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-systable_unlock(u_int32_t\SpecialChar ~
-systable)
-\emph default 
- Unlocks a previously held lock for 
-\emph on 
-systable
-\emph default 
-, which should have previously been obtained using 
-\emph on 
-systable_lock()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-systable_upgrade(u_int32_t\SpecialChar ~
-systable)
-\emph default 
- Upgrades a previously held lock for systable in shared mode to exclusive
- mode.
- The lock 
-\emph on 
-MUST
-\emph default 
- previously be obtained in shared mode.
-\layout Subsubsection
-
-Signals
-\layout Standard
-
-Very few signals are reserved by the system, SIGTERM and SIGPOLL, respectively.
- As Xisop currently supports 32 different signals per task, this results
- in 30 user signals the applications programmer may play with.
- Signals are internally implemented as bits, and are not reliably queued,
- which means that although a task will always know that a particular signal
- was received, it cannot know if it occured more than once before it had
- the chance to process it.
- It ressembles alot to a hardware bus line, which can be activated by the
- other end, although our capacity to monitor a single signal state is dependent
- on the rate at which we run.
-\layout Standard
-
-Note that sending a SIGTERM signal to a task does not force it to exit.
- It merely consists of a request to exit to the task, and the task may ignore
- it or respect it.
-\layout Standard
-
-
-\emph on 
-XXX 32 is no longer a fixed value now that signum_t and sigmask_t are abstracted
- and could be set by the port-specific code.
-\layout Standard
-
-Message ports are used when the need for reliable event queuing is met.
- The signals merely allow a task to sleep and be awaken on specified events,
- like a message arriving on a port, which internally uses a signal bit.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-signum_t\SpecialChar ~
-signal_alloc(void)
-\emph default 
- Attempts to allocate an available signal bit from the current task.
- Returns the signal number allocated, or -1 if no more signals available.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-signal_free(sigmask_t\SpecialChar ~
-sigmask)
-\emph default 
- Frees all specified signals in 
-\emph on 
-sigmask
-\emph default 
-, which should previously have been obtained using 
-\emph on 
-signal_alloc()
-\emph default 
-.
- If reserved signals are part of the supplied 
-\emph on 
-sigmask
-\emph default 
-, those are ignored.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-sigmask_t\SpecialChar ~
-signal_wait(sigmask_t\SpecialChar ~
-sigmask,\SpecialChar ~
-task_t\SpecialChar ~
-*task)
-\emph default 
- Suspends the current task until at least one of the supplied signals in
-\emph on 
-sigmask
-\emph default 
-, or a system reserved signal occurs.
- Returned is the mask of signals we received which caused an awakening.
- Multitasking-friendly applications usually spend most of their time suspended
- by this call, and are awakening to perform their operations asynchroneously,
- and go back to sleep as soon as possible, to allow other tasks to also
- respond and execute efficienty.
- However, because of the nature of the preemptive scheduler, a task which
- remains in running state will not prevent others from executing.
-\emph on 
-task
-\emph default 
-, which may be NULL, optionally specifies which task should be favored as
- a suggestion to the scheduler, which allows to implement cooperative tasks
- more efficiently.
- The current task is guaranteed to awake at the occurance of the specified
- signals, but will not be able to determine how many occurances of each
- signal occurred as no queueing is performed.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-signal_send(task_t\SpecialChar ~
-*task,\SpecialChar ~
-sigmask_t\SpecialChar ~
-sigmask)
-\emph default 
- Atomically sends the supplied signals in 
-\emph on 
-sigmask
-\emph default 
- to the specified 
-\emph on 
-task
-\emph default 
-.
- The task, if suspended waiting for signals, is awaken if a signal it waits
- for is included in 
-\emph on 
-sigmask
-\emph default 
-, and will have a chance to run.
- The delay elapsing between 
-\emph on 
-signal_send()
-\emph default 
- and the task being able to process the signal depends on three factors:
-\begin_deeper 
-\layout Itemize
-
-The speed at which the current task returns to sleep (using 
-\emph on 
-yield()
-\emph default 
-, 
-\emph on 
-port_wait()
-\emph default 
- or 
-\emph on 
-signal_wait()
-\emph default 
-).
-\layout Itemize
-
-If it does not return to sleep, the current task will continue running until
- it is preempted by the scheduler, which is dependent on the scheduler timer
- interrupt frequency.
-\layout Itemize
-
-The priority of the tasks in the ready queue, that is, which are currently
- awake.
- This factor takes place after the other end was awaken, and before it gets
- an opportunity to actually execute.
-\end_deeper 
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-sigmask_t\SpecialChar ~
-SIGMASK(signum_t\SpecialChar ~
-signum)
-\emph default 
- Consists of a useful macro to convert a signal number (
-\emph on 
-signum_t
-\emph default 
-) to a signal mask (
-\emph on 
-sigmask_t
-\emph default 
-).
- Those may then be ORed together (using C '|' bitwise operator character)
- to represent multiple signals.
-\layout Subsubsection
-
-Message ports
-\layout Standard
-
-In the UNIX world, this is called Inter Process Communication (IPC).
- In the case of Xisop, we communicate between light-weight tasks, rather
- than between full fledged processes, using signals, datagram messages and
- connectionless, unidirectional ports.
- The Xisop port functions internally operate using signal primitives and
- message queues (in FIFO order).
- These are safe to call from userspace as well as kernelspace tasks.
- However, it is not safe to transfer messages among ports in an interrupt
- handler context without using 
-\emph on 
-_splhigh()
-\emph default 
- for synchronization.
-\emph on 
-XXX
-\layout Standard
-
-A Xisop message consists of an arbitrary sized object prefixed with a 
-\emph on 
-message_t
-\emph default 
- structure, which is internally used for message queueing and replying informati
-on.
- Because the message is internally 
-\begin_inset Quotes eld
-\end_inset 
-
-moved
-\begin_inset Quotes erd
-\end_inset 
-
- by only swapping pointers efficiently, memory copy operations are minimized.
- However, this also means that the original creator of the message, as well
- as the other end to which the message is passed, are responsible to synchronize
- operations properly among eachother on the message memory area (more informatio
-n on this below).
- The 
-\emph on 
-message_t
-\emph default 
- header starts with a 
-\emph on 
-pnode_t
-\emph default 
- internally, which means that the user can use 
-\emph on 
-pool_t
-\emph default 
- primitives to efficiently and arbitrarily create and destroy messages.
- It also means that at their discretion the ends are able to internally
- queue the message in custom 
-\emph on 
-list_t
-\emph default 
- lists when necessary (after 
-\emph on 
-port_get()
-\emph default 
-, and taking care to unlink it before 
-\emph on 
-port_send()
-\emph default 
-/
-\emph on 
-port_reply()
-\emph default 
-, obviously).
-\layout Standard
-
-Some care was made when implementing Xisop message ports to take in consideratio
-n tasks and or ports which may be destroyed before a message is replied
- back by the other end, or for cases where a public port address, after
- being obtained once, becomes invalid as the public service dies.
- Instead of implementing a higher overhead or less versatile unique port
- ID allocation, validation and lookup system, or using expensive string
- operations with a 
-\emph on 
-hashtable_t
-\emph default 
- using 
-\emph on 
-hashtable_lookup()
-\emph default 
- for every message send, the following techniques were implemented:
-\layout Itemize
-
-A special magic cookie is set on a valid, existing port.
- This means that when attempting to perform any operation on a 
-\emph on 
-port_t
-\emph default 
- pointer which does not resolve to an actual, currently valid port, operation
- is refused to take place.
- When a message port is destroyed, that magic number is reset to zero, which
- renders it unusable.
-\layout Itemize
-
-Because an efficient 
-\emph on 
-pool_t
-\emph default 
- is used to allocate and free back 
-\emph on 
-port_t
-\emph default 
- objects, it would be possible for an intended reply port to be destroyed,
- and for another port, belonging to any task, to be created at the same
- address.
- To solve this issue, each port also comports an internal unique ID.
- When a message is sent to a port, from which a reply is expected, the 
-\emph on 
-message_t
-\emph default 
- is made to remember both the reply 
-\emph on 
-port_t
-\emph default 
- address and unique ID.
- When attempting to reply, the 
-\emph on 
-port_t
-\emph default 
- validity is performed as usual via the magic number, and the unique ID
- is then evaluated for a match.
- This way, a reply message will never be queued back on an unexpected port,
- or to a nonexisting one which may just have died.
-\layout Itemize
-
-The unique ID supplied to a port only consists of an unsigned 32-bit integer,
- which is obtained from a global shared counter, which is incremented and
- used whenever required.
- This means that the odds of another 
-\emph on 
-port_t
-\emph default 
- using the same address and ID within the delay of a send/reply are probably
- always none.
-\layout Itemize
-
-Using this method prevented restrictions on the maximum number of ports
- and tasks which can exist in Xisop.
- The overhead is also smaller than having to run through an array looking
- for an empty slot, and having to re-allocate the memory area to dynamically
- grow or shrink it, because without MMU support alot of memory copying would
- be required for those operations.
- Using a 
-\emph on 
-pool_t
-\emph default 
- then is ideal for speed.
- Using a relatively fast lookup hash table would require a lookup to be
- performed before every message send, which was considered suboptimal when
- designing Xisop.
- Although 
-\emph on 
-port_find()
-\emph default 
- uses this, it would have been absurd to need to perform this lookup before
- sending any message.
- Especially considering that locking must be used when accessing the system
- hash table for synchronization.
-\layout Standard
-
-Usually, the tasks should be written to be reliable and to synchronize well
- within eachother.
- However, with these precautions, supported by well written applications,
- the 
-\emph on 
-port_t
-\emph default 
- system is always very reliable and predictable.
- Here are described the functions:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-port_t\SpecialChar ~
-*port_create(const\SpecialChar ~
-char\SpecialChar ~
-*name)
-\emph default 
- Allows to create a message port on the current task.
- This internally also needs to allocate a signal bit using 
-\emph on 
-signal_alloc()
-\emph default 
-, which is associated to the 
-\emph on 
-port_t
-\emph default 
- for the 
-\emph on 
-port_wait()
-\emph default 
- internals.
- NULL is returned on failure, or a pointer to the new 
-\emph on 
-port_t
-\emph default 
- on success.
-\emph on 
-name
-\emph default 
- is optional and should be NULL if the port does not need to be advertized
- to the whole system.
- If other tasks need to find our port by name, then 
-\emph on 
-name
-\emph default 
- will be usable with 
-\emph on 
-port_find()
-\emph default 
- to locate it, and listing the system public ports would advertize it as
- well.
- Ports are generally private, except for special public services.
- The length of 
-\emph on 
-name
-\emph default 
- will be truncated to 32 characters if it is longer.
- If a public port is created, but that another public port bears the same
- name alerady, the operation fails.
- The port name is case-sensitive.
- If the task exists without closing it's ports, they are automatically destroyed
- by the kernel.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-port_t\SpecialChar ~
-*port_destroy(port_t\SpecialChar ~
-*port)
-\emph default 
- Destroys a message port of the current process, which was created using
-\emph on 
-port_create()
-\emph default 
-.
- The internally allocated signal bit and memory are released back to the
- system.
- If any queued messages exist, the queue is lost, but the 
-\emph on 
-message_t
-\emph default 
- objects are untouched, as they remain the responsibility of the application
- who created them.
- NULL is returned.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-port_t\SpecialChar ~
-*port_find(const\SpecialChar ~
-char\SpecialChar ~
-*name)
-\emph default 
- Allows to locate a public message port by name.
- If the port can be found, it's address is returned.
- NULL is returned otherwise.
- Because this needs to lookup through a system's public ports hash table
- it needs to lock it internally using a 
-\emph on 
-rwlock_t
-\emph default 
- in shared access mode.
- The port name is case-sensitive.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-port_send(port_t\SpecialChar ~
-*port,\SpecialChar ~
-port_t\SpecialChar ~
-*replyport,\SpecialChar ~
-message_t\SpecialChar ~
-*message)
-\emph default 
- Queues the supplied 
-\emph on 
-message_t
-\emph default 
- to the specified 
-\emph on 
-port_t
-\emph default 
- in FIFO order, and internally 
-\emph on 
-send_signal()
-\emph default 
- the associated process with the internal port signal.
- This means that the other process could be sleeping using 
-\emph on 
-signal_wait()
-\emph default 
- or 
-\emph on 
-port_wait()
-\emph default 
- and will be awakened so that it may process the message.
- The supplied message then becomes owned by the other end, and should be
- left alone by the current task until a reply be obtained from the other
- side on the 
-\emph on 
-message_t
-\emph default 
-'s 
-\emph on 
-replyport
-\emph default 
-.
- This 
-\emph on 
-port_send()
-\emph default 
- and 
-\emph on 
-port_reply()
-\emph default 
- mechanism serves for synchronization.
- This means that normally, 
-\emph on 
-replyport
-\emph default 
- is supplied the address of a local 
-\emph on 
-port_t
-\emph default 
- used to receive results from the task we send messages to via it's own
-\emph on 
-port_t
-\emph default 
-.
- TRUE is returned on success, or FALSE if the message could not be delivered
- (in which case the supplied 
-\emph on 
-port_t
-\emph default 
- address is probably invalid and a 
-\emph on 
-port_find()
-\emph default 
- operation can be used again to attempt to locate the port, if it consists
- of a public port which should exist).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-message_t\SpecialChar ~
-*port_get(port_t\SpecialChar ~
-*port)
-\emph default 
- If at least one message is available in the specified 
-\emph on 
-port_t
-\emph default 
-, the first one is unqueued from it in FIFO order and the address to it
- is returned.
- Otherwise, NULL is returned.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-port_reply(message_t\SpecialChar ~
-*msg)
-\emph default 
- Sends back the supplied 
-\emph on 
-message_t
-\emph default 
- to the reply 
-\emph on 
-port_t
-\emph default 
- of the task that previously sent it to us.
- This port corresponds to the 
-\emph on 
-replyport
-\emph default 
- argument that was used at 
-\emph on 
-port_send()
-\emph default 
-.
- Normally, the other end waits until we are done with the message, and we
- use this function to notify that it can safely continue to do whatever
- it wants with the 
-\emph on 
-message_t
-\emph default 
- data.
- TRUE is returned on success, or FALSE if no 
-\emph on 
-replyport
-\emph default 
- was set for the 
-\emph on 
-message_t
-\emph default 
-, or that the reply port is no longer valid.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-port_t\SpecialChar ~
-*port_wait(port_t\SpecialChar ~
-**ports,\SpecialChar ~
-u_int32_t\SpecialChar ~
-num,\SpecialChar ~
-task_t\SpecialChar ~
-*task)
-\emph default 
- Suspends the current task until a message is received through one of the
- supplied port(s) specified in the array of 
-\emph on 
-port_t
-\emph default 
- pointers 
-\emph on 
-ports
-\emph default 
-.
-\emph on 
-num
-\emph default 
- specifies the number of 
-\emph on 
-port_t
-\emph default 
- pointers supplied in the ports array.
-\emph on 
-task
-\emph default 
- specifies a suggestion preference of which task to switch to, or NULL to
- let the scheduler choose.
- Returned is the pointer to the 
-\emph on 
-port_t
-\emph default 
- which received the message, or NULL if a reserved signal was the awakening
- cause.
- If one of the ports already has queued messages the task will not be set
- to sleep and the aforementionned port will be returned immediately.
- If it is necessary to monitor other signals as well as port message arrivals,
- it is advised to manually assemble the 
-\emph on 
-sigmask_t
-\emph default 
- from all monitored signals, including the ones associated to the monitored
- ports, and to use 
-\emph on 
-signal_wait()
-\emph default 
- instead.
- Evaluating the resulting 
-\emph on 
-sigmask_t
-\emph default 
- will permit to know which ports received messages, if any.
- Use of the 
-\emph on 
-PORT_SIGMASK()
-\emph default 
- macro will then be useful.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-port_flush(port_t\SpecialChar ~
-*port)
-\emph default 
- Unqueues all pending messages in the supplied 
-\emph on 
-port_t
-\emph default 
-, if any.
- This can be useful to discard unused 
-\emph on 
-port_reply()
-\emph default 
- results which are obtained where no result codes are needed, rather than
- using a 
-\emph on 
-while()
-\emph default 
- loop of 
-\emph on 
-port_get()
-\emph default 
- statements.
- Also useful before destroying ports when desired.
- Returns TRUE on success, or FALSE if the port is invalid.
- Should obviously not be used on other tasks' ports, only ours.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-sigmask_t\SpecialChar ~
-PORT_SIGMASK(port_t\SpecialChar ~
-*port)
-\emph default 
- Is useful when it is necessary to know which signal bit is associated with
- a particular port.
- The returned 
-\emph on 
-sigmask_t
-\emph default 
- can be ORed with the other masks to provide to 
-\emph on 
-signal_wait()
-\emph default 
-.
- This way, it is possible for a task to monitor the state of other signals
- while at the same time monitoring message ports for events.
- This macro, just like 
-\emph on 
-SIGMASK()
-\emph default 
-, should be used instead of expressions such as 
-\emph on 
-(1L << n)
-\emph default 
- both for code obviousness and backwards compatibility, because the number
- of available signals could eventually grow.
-\layout Subsubsection
-
-The special SIGPOLL signal and the poll port
-\layout Standard
-
-
-\emph on 
-XXX needs to be rethinked and re-written :)
-\layout Standard
-
-As there only are 30 user signals, and that a message port is usually associated
- with a signal, it may be useful to assign more than one message port to
- a single signal, or process more than one event using a single signal and
- message port.
-\layout Standard
-
-The SIGPOLL signal is reserved for just that, and each task always has a
- message port associated with this signal.
- Through this port can be sent various type of messages for more than one
- event the task may want to be awakened for.
- This provides message multiplexing, while the method for multiple message
- ports using the same signal would provide port multiplexing.
- The reason why message multiplexing was chosen as a standard in Xisop was
- because it requires less resources.
- The more ports there are on the system, the larger the system ports pool
- grows and it will never shrink for considerations described in the previous
- subsection.
-\emph on 
-XXX
-\layout Standard
-
-This special system-reserved port can be used to transfer reliable signals,
- possibly emulating POSIX semantics, or to transfer many other types of
- events a task may all be waiting for.
- It also is useful to have a high number of concurrently opened high-level
- files, and implement filedescriptors.
- A special set of functions is provided by Xisop machine-independent layer
- to transfer messages through this port, and to evaluate the type of event
- that originated the message, along with message size.
- Because unlike for standard message ports where messages of a fixed size
- are usually transfered, the message size changes here, depending on the
- event type and message.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsection
-
-Xisop memory management system
-\layout Standard
-
-Xisop provides three types of memory management primitives for the kernel.
- These are provided by the Xisop machine-independent layer.
- It also provides distinction between the various types of memory, when
- an architecture has more than one (i.e.
- Amiga CHIP and FAST RAM, peripheral memory, etc).
- Special care was used to prevent the memory management system from having
- to disable interrupts (which may be very useful when the 
-\emph on 
-_FACILITY_SCHEDTIMER
-\emph default 
- consists of the only timing source for an architecture and needs to be
- as reliable as possible).
- A 
-\emph on 
-_lock_t
-\emph default 
- is internally used by the system page primitives to sychronize access to
- the system page pools.
- This also avoids having to export them as system calls via traps.
-\layout Subsubsection
-
-Page primitives
-\layout Standard
-
-The first level system consists of page allocation and freeing.
- The page size is dependent on architecture when MMU is concerned, however
- within Xisop which provides it's own memory management, a page is typically
- 4096 bytes.
- Primitives are provided to allocate a single page, or number of physically
- contiguous pages, and to free back one page, or a number of contiguous
- pages.
- At system initialization, the page pools are initiated to provide access
- to the physical memory areas, and are classified by memory type.
- There are a few functions also defined by Xisop which allow to add physical
- memory areas to the page pools, and specify their type, so that the architectur
-e-dependent initialization code be simpler, and also that at runtime it
- be possible to attach new RAM which was mapped from external devices, possibly
- hot-pluggable ones such as PCMCIA memory cards, etc.
- Here are described the dynamic memory linking functions.
- Note that these functions internally use a 
-\emph on 
-_lock_t
-\emph default 
- which is acquired to access the system pages pools.
- This means that they are generally safe to call anytime, but from interrupt
- handler context.
-\emph on 
-XXX
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-mchunk_t\SpecialChar ~
-*mchunk_init(void\SpecialChar ~
-*mem,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Internally prepares the supplied memory block to pages which can later
- be linked into the system.
- The internal control structures are setup in hidden data which will not
- be added into the public pages.
- This is dependent on 
-\emph on 
-_PAGE_SIZE
-\emph default 
-, which should be defined by the port-specific <
-\emph on 
-port/support.h
-\emph default 
-> headerfile.
- NULL is returned if the supplied memory area was too small to be split
- into pages and to store the necessary control data.
- Otherwise, a pointer to the 
-\emph on 
-mchunk_t
-\emph default 
- is provided.
- After using this call, the memory area should never be manipulated anymore,
- other than using other Xisop standard calls, unless it is known that the
- area is not linked into the system pages.
- The supplied memory is expected to be physical contiguous memory.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-mchunk_attach(int\SpecialChar ~
-memtype,\SpecialChar ~
-mchunk_t\SpecialChar ~
-*mchunk)
-\emph default 
- Allows to link an 
-\emph on 
-mchunk_t
-\emph default 
- which was previously prepared using 
-\emph on 
-mchunk_init()
-\emph default 
-, to the system 
-\emph on 
-ppool_t
-\emph default 
- associated with the specified memory type.
- After this is performed, it is possible to allocate memory pages from this
- memory chunk until it be unlinked using 
-\emph on 
-mchunk_detach()
-\emph default 
-.
- This depends on 
-\emph on 
-_MEM_MAX
-\emph default 
-, which is defined by the port specific <
-\emph on 
-port/support.h
-\emph default 
-> headerfile.
- TRUE is normally returned, unless the chunk is seen to already have been
- attached, or that the supplied memory type is invalid, in which case FALSE
- is returned.
- It is possible to setup and append as many 
-\emph on 
-mchunk_t
-\emph default 
- as wanted.
- For instance, the port-specific code which sets up the kernel pages for
- available memory may need to call 
-\emph on 
-mchunk_init()
-\emph default 
- and 
-\emph on 
-mchunk_attach()
-\emph default 
- multiple times, one for each contiguous memory block.
- It is safe to call this function to attach new memory at system runtime,
- anytime.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-mchunk_detach(int\SpecialChar ~
-memtype,\SpecialChar ~
-mchunk_t\SpecialChar ~
-*mchunk)
-\emph default 
- Permits to safely detach from the system an 
-\emph on 
-mchunk_t
-\emph default 
- which previously was attached using 
-\emph on 
-mchunk_attach()
-\emph default 
-.
- TRUE is returned on success, or FALSE if the memory type is invalid, if
- the supplied 
-\emph on 
-mchunk_t
-\emph default 
- was not currently attached, or if any memory from that 
-\emph on 
-mchunk_t
-\emph default 
- is still currently allocated, in which case the chunk is not unliked.
-\layout Standard
-
-The first level of allocation primitives allow to allocate and free one
- or multiple contiguous pages of physical memory to and from the system
- pools (
-\emph on 
-ppool_t
-\emph default 
- of each memory type).
- Internally, the list of linked 
-\emph on 
-mchunk_t
-\emph default 
- for a memory type is ran through.
- These functions also acquire the system pools safety lock while working
- on the system memory pools:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-page_t\SpecialChar ~
-*pages_alloc(int\SpecialChar ~
-memtype,\SpecialChar ~
-u_int32_t\SpecialChar ~
-many,\SpecialChar ~
-bool\SpecialChar ~
-zero)
-\emph default 
- Allocates 
-\emph on 
-many
-\emph default 
- contiguous memory pages of 
-\emph on 
-_PAGE_SIZE
-\emph default 
- bytes, of the supplied 
-\emph on 
-memtype
-\emph default 
-, which can be 
-\emph on 
-_MEM_ANY
-\emph default 
- in which case all memory types are tried sequencially, favoring the first
- memory type to the last.
- A 
-\emph on 
-page_t
-\emph default 
- pointer is returned which can be used to access the memory area via 
-\emph on 
-page_t->address
-\emph default 
-, or to free back the memory using 
-\emph on 
-pages_free()
-\emph default 
-.
- NULL is returned if not enough memory can be found to satisfy the request.
- If 
-\emph on 
-zero
-\emph default 
- is TRUE and pages could be allocated, the memory area is zeroed using 
-\emph on 
-pageclr()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-pages_free(page_t\SpecialChar ~
-*pages)
-\emph default 
- Releases to the system one or more contiguous memory pages which previously
- were allocated using 
-\emph on 
-pages_alloc()
-\emph default 
-.
- TRUE is returned on success, or FALSE if the supplied pointer was NULL,
- or if the 
-\emph on 
-page_t
-\emph default 
- was already freed back.
-\layout Subsubsection
-
-Simple object pool primitives
-\layout Standard
-
-The second level consists of a pool of fixed sized entities, the 
-\emph on 
-pool_t
-\emph default 
-.
- A pool can be pre-allocated once, with a fixed maximum number of elements,
- setup to grow automatically when new elements are needed, internally allocating
- and preparing new pages as required, and can optionally also shrink smaller
- automatically, releasing back to the system the unused pages.
- When a pool is about to shrink, it evaluates statistics about the number
- of pages the pool normally holds on average, so that primitives to free
- the page are not called too often unnecessarily.
- Such pages are buffered by the pool for future use, if they are expected
- to be reclaimed back soon.
- Using these functions is more efficient in speed and memory than using
- page allocation primitives, calls to which it attempts to minimize, while
- filling each page of memory with the most objects possible.
-\layout Standard
-
-A C structure should be defined for the type of object which is to be allocated,
- and the first element of that structure should consist of a 
-\emph on 
-pnode_t
-\emph default 
- element.
- These functions, unlike page allocation ones, do not synchronize if multiple
- tasks or interrupt handlers share a 
-\emph on 
-pool_t
-\emph default 
-.
- The caller should therefore provide synchronization whenever necessary.
- However, if the 
-\emph on 
-pool_t
-\emph default 
- allocates or frees system pages, the 
-\emph on 
-pages_alloc()
-\emph default 
- and 
-\emph on 
-pages_free()
-\emph default 
- functions are used which internally use synchronization to ensure that
- the system pools do not corrupt.
- These functions are mostly for kernel use.
- If used from userspace, these pools will not be automatically freed back
- to the system unless the tasks specifically destroys them before exiting.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-pool_init(pool_t\SpecialChar ~
-*p, u_int32_t\SpecialChar ~
-stepp, u_int32_t\SpecialChar ~
-minp, u_int32_t\SpecialChar ~
-maxp, size_t\SpecialChar ~
-node
-size, int\SpecialChar ~
-memtype)
-\emph default 
- Initializes the supplied 
-\emph on 
-pool_t
-\emph default 
- object 
-\emph on 
-p
-\emph default 
- to be used to allocate objects of 
-\emph on 
-nodesize
-\emph default 
- length (size which should include the 
-\emph on 
-pnode_t
-\emph default 
- element).
- This size should be equal or smaller than 
-\emph on 
-_PAGE_SIZE
-\emph default 
- * 
-\emph on 
-stepp
-\emph default 
- / 2.
-\emph on 
-stepp
-\emph default 
- specifies how many contiguous pages should be allocated and freed at once
- using 
-\emph on 
-pages_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- primitives, when required.
- If 
-\emph on 
-stepp
-\emph default 
- appears too small to fit a useful number of nodes in a 
-\emph on 
-page_t
-\emph default 
-, it will be automatically grown until it reaches a maximum of 8, after
- which FALSE will be returned for failure (although there is no such limit
- for the 
-\emph on 
-stepp
-\emph default 
- argument itself when manually set high enough).
- Each 
-\emph on 
-page_t
-\emph default 
- is then internally split into objects.
-\emph on 
-minp
-\emph default 
- tells the minimum number of 
-\emph on 
-page_t
-\emph default 
- which should always remain into the 
-\emph on 
-pool_t
-\emph default 
-, or 0 if it is allowed to shrink totally when it needs no memory.
- The pool will initially allocate those at initialization, and it will never
- shrink smaller during it's lifetime, if non-zero.
-\emph on 
-maxp
-\emph default 
- similarily specifies the maximum number of 
-\emph on 
-page_t
-\emph default 
- which the 
-\emph on 
-pool_t
-\emph default 
- should eventually grow to, or 0 for no limit.
- For instance, using 
-\emph on 
-minp
-\emph default 
- and 
-\emph on 
-maxp
-\emph default 
- of 0 allows the pool_t to dynamically grow and shrink as necessary and
- it could eventually use all available RAM.
- Using a 
-\emph on 
-minp
-\emph default 
- and 
-\emph on 
-maxp
-\emph default 
- of 2 ensures that at least two 
-\emph on 
-page_t
-\emph default 
- be initially allocated, which will never be freed back unless the 
-\emph on 
-pool_t
-\emph default 
- is destroyed, and also tells that the pool should never allocate more pages.
- This can be useful in interrupt context or some situations where we do
- not want the system pool pages to be accessed.
- A fixed number of maximum object nodes will be available to allocate and
- free efficiently then.
-\emph on 
-memtype
-\emph default 
- specifies the memory type which this pool will use to allocate the pages.
- It is invalid to specify 
-\emph on 
-_MEM_ANY
-\emph default 
- here.
- TRUE is returned on success, or FALSE on failure (invalid memory type or
- not enough available memory).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-pool_destroy(pool_t\SpecialChar ~
-*pool)
-\emph default 
- Frees all memory currently being used by the specified 
-\emph on 
-pool_t
-\emph default 
- and destroys the pool object, which can no longer be used by pool object
- allocation primitives unless it is re-initialized.
- Any currently allocated objects from the 
-\emph on 
-pool_t
-\emph default 
- become invalid immediately and should therefore not be accessed anymore,
- they get freed as well.
- TRUE is returned on success, or FALSE if the supplied 
-\emph on 
-pool_t
-\emph default 
- was not previously initialized successfully.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pnode_t\SpecialChar ~
-*pool_alloc(pool_t\SpecialChar ~
-*pool,\SpecialChar ~
-bool\SpecialChar ~
-zero)
-\emph default 
- Attempts to allocate a single object from the specified 
-\emph on 
-pool_t
-\emph default 
-.
- The object size depends on the 
-\emph on 
-nodesize
-\emph default 
- parameter which was supplied at 
-\emph on 
-pool_init()
-\emph default 
-.
- A pointer to the object is returned on success, or NULL if not enough memory
- is available, either for the 
-\emph on 
-pool_t
-\emph default 
-, if 
-\emph on 
-maxp
-\emph default 
- was non-zero, or system memory.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pnode_t\SpecialChar ~
-*pool_free(pnode_t\SpecialChar ~
-*node)
-\emph default 
- Releases the specified object 
-\emph on 
-node
-\emph default 
- which was previously allocated using 
-\emph on 
-pool_alloc()
-\emph default 
-, back to the 
-\emph on 
-pool_t
-\emph default 
- it belongs to.
- NULL is returned.
-\layout Subsubsection
-
-General purpose memory pools
-\layout Standard
-
-The third level memory management system, working with 
-\emph on 
-mpool_t
-\emph default 
-, consists of a number of 
-\emph on 
-pool_t
-\emph default 
-, adapted to serve most byte requirement requests, through more standard
- malloc() and free() like functions.
- For a system with a 
-\emph on 
-_PAGE_SIZE
-\emph default 
- of 4096, 
-\emph on 
-_MPOOLSTEP
-\emph default 
- of 1 and 
-\emph on 
-_MPOOLS
-\emph default 
- of 7 and 
-\emph on 
-_MPOOLSTART
-\emph default 
- of 16, there are 7 
-\emph on 
-pool_t
-\emph default 
-, deserved to serve element sized as closely possible to the requested number
- of bytes (smallest nodesize 16 + sizeof(mnode_t)), and a 
-\emph on 
-list_t
-\emph default 
- designed to hold 
-\emph on 
-page_t
-\emph default 
- pointers to satisfy larger requests, which get rounded on page boundaries.
- An 
-\emph on 
-mpool_t
-\emph default 
- is capable of serving requests for various memory types, including 
-\emph on 
-_MEM_ANY
-\emph default 
-, where the first memory types are privileged over the last ones.
- Like their 
-\emph on 
-pool_t
-\emph default 
- counterparts, these functions do not perform any special synchronization
- which may be necessary if an 
-\emph on 
-mpool_t
-\emph default 
- was shared among several tasks.
- Here are the functions related to the 
-\emph on 
-mpool_t
-\emph default 
-:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-mpool_init(mpool_t\SpecialChar ~
-*mpool)
-\emph default 
- Initializes an 
-\emph on 
-mpool_t
-\emph default 
- to accept allocation requests.
- TRUE is returned on success, or FALSE if there is a problem initializing
- the 
-\emph on 
-pool_t
-\emph default 
- elements, or if the supplied 
-\emph on 
-mpool
-\emph default 
- pointer is NULL.
- This function is dependent on the port-specific 
-\emph on 
-_MPOOLS
-\emph default 
-, 
-\emph on 
-_MPOOLSTEP, _MPOOLSTART
-\emph default 
- and the 
-\emph on 
-enum _memtypes 
-\emph default 
-holding 
-\emph on 
-_MEM_MAX
-\emph default 
- which should have been defined in <
-\emph on 
-port/support.h
-\emph default 
->.
-\emph on 
-_MPOOLS
-\emph default 
- specifies the number of 
-\emph on 
-pool_t
-\emph default 
- objects, 
-\emph on 
-_MPOOLSTEP
-\emph default 
- the 
-\emph on 
-stepp
-\emph default 
- argument to 
-\emph on 
-pool_init()
-\emph default 
-, 
-\emph on 
-_MPOOLSTART
-\emph default 
- the maximum bytesize request for the first 
-\emph on 
-pool_t
-\emph default 
-, and 
-\emph on 
-_MEM_MAX
-\emph default 
- the number of memory types supplied by the system.
- See the port-dependent section for more information on how to set these.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-mpool_destroy(mpool_t\SpecialChar ~
-*mpool)
-\emph default 
- Frees all memory currently associated with the specified 
-\emph on 
-mpool_t
-\emph default 
-, which should have previously been initialized by 
-\emph on 
-mpool_init()
-\emph default 
-, and disables the 
-\emph on 
-mpool_t
-\emph default 
-.
- Any pointers to memory which were obtained via 
-\emph on 
-_malloc()
-\emph default 
- using this pool become invalid.
- No more requests will be allowed on this 
-\emph on 
-mpool_t
-\emph default 
- unless re-initialized using 
-\emph on 
-mpool_init()
-\emph default 
-.
- TRUE is returned, or FALSE if the 
-\emph on 
-mpool_t
-\emph default 
- was already destroyed, or that the supplied pointer is NULL.
- It is also possible for this function to return FALSE without error, in
- the case where at least another task shares this 
-\emph on 
-mpool_t
-\emph default 
-.
- (See the 
-\emph on 
-TS_SHARED
-\emph default 
- flag to 
-\emph on 
-task_alloc()
-\emph default 
-).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*_malloc(mpool_t\SpecialChar ~
-*mpool,\SpecialChar ~
-int\SpecialChar ~
-memtype,\SpecialChar ~
-size_t\SpecialChar ~
-size,\SpecialChar ~
-bool\SpecialChar ~
-zero)
-\emph default 
- Attempts to allocate the requested 
-\emph on 
-size
-\emph default 
- contiguous bytes from the supplied 
-\emph on 
-mpool
-\emph default 
-, using memory of type 
-\emph on 
-memtype
-\emph default 
-.
- _MEM_ANY is valid, and will cause any available memory type to be returned.
- A pointer is returned to a memory area holding the number of bytes that
- were requested, or NULL if there is not enough memory to satisfy the request,
- or if the parameters are wrong.
- If 
-\emph on 
-zero
-\emph default 
- is TRUE, the memory area is cleared with 0x00 bytes.
- Automatic synchronization is performed if the 
-\emph on 
-mpool_t
-\emph default 
- is shared by more than one task.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*_free(void\SpecialChar ~
-*mem)
-\emph default 
- Frees back the memory to which the supplied 
-\emph on 
-mem
-\emph default 
- points, to where it belongs.
- NULL is returned.
- Automatic synchronization is performed if the 
-\emph on 
-mpool_t
-\emph default 
- is shared by more than one task.
-\layout Paragraph
-
-Kernel code
-\layout Standard
-
-Here are variants which can be used by kernel functions.
- Note that the kernel can use all the above previously mentionned functions
- as well, however for consistency it is good to use the following where
- appropriate.
- All of these, contrary to the previously described primitives, internally
- use exclusive locks as necessary to ensure the integrity of the system
- pools, so that disabling the scheduler is unnecessary:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*_kmalloc(int\SpecialChar ~
-memtype,\SpecialChar ~
-size_t\SpecialChar ~
-size,\SpecialChar ~
-bool\SpecialChar ~
-zero)
-\emph default 
- Allocates general-purpose memory from the kernel memory pool, which should
- be released using 
-\emph on 
-kfree()
-\emph default 
-.
- When a task uses this function the memory is not restored to the system
- automatically when it exists.
- Special syncronization is used internally so that it is safe to use by
- multiple tasks.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*_kfree(void\SpecialChar ~
-*mem)
-\emph default 
- Frees back to the kernel memory pools memory which has previously been
- allocated by 
-\emph on 
-kmalloc()
-\emph default 
-.
- Internal special synchronization is used.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*TMALLOC(int\SpecialChar ~
-memtype,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Equivalent to calling 
-\emph on 
-kmalloc(memtype, size, FALSE);
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*TCMALLOC(int\SpecialChar ~
-memtype,\SpecialChar ~
-int\SpecialChar ~
-number,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Equivalent to calling 
-\emph on 
-kmalloc(memtype, number * size, TRUE);
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*MALLOC(size_t\SpecialChar ~
-size)
-\emph default 
- Identical to calling 
-\emph on 
-kmalloc(_MEM_ANY, size, FALSE);
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*CMALLOC(int\SpecialChar ~
-number,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Like calling 
-\emph on 
-_kmalloc(_MEM_ANY, number * size, TRUE);
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*FREE(void\SpecialChar ~
-*mem)
-\emph default 
- Equivalent to 
-\emph on 
-_kfree(mem);
-\emph default 
- but made to match all above macros.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*kmalloc(size_t\SpecialChar ~
-size)
-\emph default 
- Like 
-\emph on 
-MALLOC()
-\emph default 
- but implemented as an ANSI-C compliant function.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-kfree(void\SpecialChar ~
-*mem)
-\emph default 
- Counterpart to 
-\emph on 
-kmalloc()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pnode_t\SpecialChar ~
-*spool_alloc(u_int32_t\SpecialChar ~
-pool)
-\emph default 
- Allows to efficiently allocate a frequently used kernel object for which
- a special system pool exists.
-\emph on 
-pool
-\emph default 
- may consist of one of the 
-\emph on 
-POOL_
-\emph default 
-* names which are defined in the 
-\emph on 
-enum _syspools
-\emph default 
- in <
-\emph on 
-src/kernel/memory.h
-\emph default 
->.
- Automatic synchronization is performed.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-pnode_t\SpecialChar ~
-*spools_free(u_int32_t\SpecialChar ~
-pool,\SpecialChar ~
-pnode_t\SpecialChar ~
-*node)
-\emph default 
- Made to free a system object which was previously allocated using 
-\emph on 
-spool_alloc()
-\emph default 
-.
- Automatic synchronization is performed.
-\layout Paragraph
-
-User space tasks
-\layout Standard
-
-The following can be called by user tasks to allocate memory using their
- own memory pool, which is automatically released back to the system when
- they exit.
- They behave identically to the standard ANSI-C functions bearing the same
- name.
- They are implemented as functions rather than macros, for inclusion into
- the Xisop shared library.
- These are also safe to use in the case where more than one tasks are sharing
- an 
-\emph on 
-mpool_t
-\emph default 
- (see the 
-\emph on 
-TS_SHARED
-\emph default 
- flag to 
-\emph on 
-task_alloc()
-\emph default 
-).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*malloc(size_t\SpecialChar ~
-size)
-\emph default 
- Behaves identically to the standard ANSI-C 
-\emph on 
-malloc()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*calloc(int\SpecialChar ~
-number,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Identical to ANSI-C 
-\emph on 
-calloc()
-\emph default 
- semantics.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*realloc(void\SpecialChar ~
-*ptr,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Like ANSI-C 
-\emph on 
-realloc()
-\emph default 
- semantics.
- Note that like the standard, the returned pointer can point to a new memory
- area, in which case the previous contents will have been copied over.
- The use of this function is generally discouraged against generally more
- efficient dynamic allocation techniques using linked lists.
- It is however provided for compatibility with ANSI-C.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-free(void\SpecialChar ~
-*ptr)
-\emph default 
- Again like the ANSI-C 
-\emph on 
-free()
-\emph default 
- function.
- Note that this function can also free memory which has been allocated using
-\emph on 
-tmalloc()
-\emph default 
- and 
-\emph on 
-tcmalloc()
-\emph default 
-.
-\layout Standard
-
-ANSI-C however has no concept of multiple memory types, and as such 
-\emph on 
-tmalloc()
-\emph default 
- had to be included.
-\emph on 
-free()
-\emph default 
- can be used to free back memory which they allocate still:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*tmalloc(int\SpecialChar ~
-memtype,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Like 
-\emph on 
-malloc()
-\emph default 
- but allows to specify a Xisop port-dependent memory type.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*tcmalloc(int\SpecialChar ~
-memtype,\SpecialChar ~
-int\SpecialChar ~
-number,\SpecialChar ~
-size_t\SpecialChar ~
-size)
-\emph default 
- Like 
-\emph on 
-calloc()
-\emph default 
-, but can also be told the type of memory wanted.
-\layout Subsubsection
-
-A note about absolute memory allocation
-\layout Standard
-
-Xisop does not provide an allocation function which can be told the absolute
- memory location area desired.
- There are several reasons for this which this section attempts to explain.
-\layout Standard
-
-Xisop provides the necessary inter-task communications tools to prevent
- the need of using absolute memory addresses for rendez-vous among tasks.
- Moreover, it has the concept of devices, which can be left the task to
- perform synchronization among tasks which need to share a specific resource.
- Additionally, Xisop does not setup the MMU in a way to prevent user tasks
- from accessing any memory.
-\layout Standard
-
-This means that if absolute memory locations need to be reserved by the
- system, they normally should not be included into the general purpose memory
- pools.
- A user device task can then specifically handle those locations as necessary
- and provide multitasking-friendly access to them.
-\layout Standard
-
-For instance, the video memory should not be attached to the system memory
- pools by the port-specific code.
- Instead, a device task should be written and provided to allow safe access
- to the video hardware, and basic console support.
- Optionally, a handler can be provided, which even allows a higher abstraction
- to access the device.
- For instance, the device could supply basic resource allocation and access
- primitives, while the handler could support vt100 emulation over the device.
-\layout Standard
-
-In the case of a single-tasking application being developped around Xisop,
- once the scheduler is disabled there is no need for any special handling
- to access the wanted memory regions.
- The memory allocator is no longer necessary to use, even.
-\layout Standard
-
-Another consideration to realize is that if for instance video memory was
- part of the system memory pools, it could automatically be allocated by
- another task which was only requesting some memory.
- If we had support for reserved pages, then there would be no point in allocatin
-g them, also.
- Only general-purpose memory should be attached into the system.
- There exists the possibility of reserving a specific memory type for some
- memory however, if there is a need for specific regions to only be used
- by certain applications but that general purpose management primitives
- are still desired.
-\layout Standard
-
-Other than the Xisop message port system which allows tasks to share and
- synchronize arbitrary memory regions, it is possible for several tasks
- to inherently share a common memory pool, using the 
-\emph on 
-TS_SHARED
-\emph default 
- flag to 
-\emph on 
-task_alloc()
-\emph default 
-.
- This can in some circumstances be used if the memory resources are quite
- scarce (many tasks which only allocate few but various sized memory blocks
- of different memory types can waste quite a large amount of pages.
- Using the same pool would then permit the same pages to be used among the
- tasks for their similar allocation needs.
- Their allocated blocks generally consist of a page which is split in equally
- sized blocks).
- Moreover, in such a setup, one task which allocates a block of memory does
- not implicitly free it on exit, if other tasks are still running sharing
- the memory.
- Those blocks need to be explicitely freed unless all tasks exit to really
- be released back to the system.
- Moreover, special synchronization must be used by the tasks if they want
- to access the same memory addresses.
- This is usually done using an 
-\emph on 
-rwlock_t
-\emph default 
-, or disabling the scheduler temporarily.
-\layout Subsection
-
-Xisop public interrupt abstraction facilities
-\layout Standard
-
-To allow Xisop architecture-specific devices to attach interrupt handler
- hooks, and for portable code to make use of a few basic interrupt facilities
- like timers, it is a good idea to provide a few access functions to allow
- this.
- The idea is to provide a facility which allows the kernel code, or userspace
- tasks, to run a piece of code once, a certain number of times, or indefinitely,
- as part of the low-level interrupt handling code.
- It thus should be possible to add and delete their code handlers from each
- of the wanted interrupt handlers.
- To provide this multi-purpose facility, the following system was developed,
- and almost entirely consists of portable common code.
-\layout Subsubsection
-
-Internals
-\layout Standard
-
-The following structure is defined in <
-\emph on 
-common/kernel/exception.h
-\emph default 
->:
-\layout Quote
-
-
-\emph on 
-typedef struct _int_hook {
-\newline 
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-pnode_t node; 
-\newline 
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-hookid_t id;
-\newline 
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-u_int32_t skipcount, runcount;
-\newline 
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-void (*code)(hookid_t, int, void *); 
-\newline 
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-\SpecialChar ~
-void *data;
-\newline 
-} hook_t;
-\layout Standard
-
-Where 
-\emph on 
-node
-\emph default 
- is used for internal linking, 
-\emph on 
-id 
-\emph default 
-consists of a unique ID for this facility, 
-\emph on 
-skipcount
-\emph default 
- of the number of times this handler will execute before calling the 
-\emph on 
-code
-\emph default 
- hook, 
-\emph on 
-runcount
-\emph default 
- of the number of times the hook 
-\emph on 
-code
-\emph default 
- will be called before it gets automatically deleted, or 0 if it should
- execute everytime this interrupt occurs.
-\emph on 
-void\SpecialChar ~
-(*code)(hookid_t, int, void\SpecialChar ~
-*)
-\emph default 
- consists of the C function to invoke when the event occurs.
- The abstracted arguments 
-\emph on 
-void
-\emph default 
- pointer may serve any purpose the application wants.
-\emph on 
-void\SpecialChar ~
-*data
-\emph default 
- pointer to abstract user-defined data will be passed as argument to the
- called function.
- The 
-\emph on 
-hookid_t
-\emph default 
- argument will consist of the ID of the 
-\emph on 
-hook_t
-\emph default 
- into the facility which caused the call, and is made to be unique.
- The supplied 
-\emph on 
-int
-\emph default 
- argument may be useless, or can serve to determine the origin of the interrupt,
- somewhat like the 
-\emph on 
-hookid_t
-\emph default 
-, but will use a facility-specific semantics, which could include a key
- being pressed in the case of a keyboard interrupt, etc.
- The kernel uses an efficient memory 
-\emph on 
-pool_t
-\emph default 
- to internally allocate and free these automatically when hooks are attached
- and detached from facilities.
-\layout Standard
-
-The following machine-independent function is also provided so that the
- port-specific code (from assembly or C) may easily order an execution of
- all attached hooks on a facility.
- The hook ids are made to be unique so that it is safe for the one who attached
- a hook to try to delete it, assuming that if it exists in the list, it
- cannot be any other hook supplied by other code (even if it expired and
- another hook replaced it internally).
- This consists of an interface for the port, not of the general user interface
- to the facilities:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-facility_exechooks(u_int32_t\SpecialChar ~
-facility,\SpecialChar ~
-int\SpecialChar ~
-origin)
-\emph default 
- executes all attached code hooks of the specified 
-\emph on 
-facility
-\emph default 
-, sequencially (if any).
- This means that for each existing hook, the corresponding function is called
- if it's 
-\emph on 
-skipcount
-\emph default 
- is 0, or 
-\emph on 
-skipcount
-\emph default 
- is simply decreased by 1 otherwise.
- When the hook is to be called, it is passed the corresponding user data
- pointer (which can be NULL) to it, the 
-\emph on 
-hookid_t
-\emph default 
- id for the hook, and 
-\emph on 
-origin
-\emph default 
- into the 
-\emph on 
-int
-\emph default 
- argument.
- The hook is then evaluated for expiration if 
-\emph on 
-runcount
-\emph default 
- was non-zero at insertion with 
-\emph on 
-hook_attach()
-\emph default 
-, and automatically destroyed if it expires.
- The caller should normally disable the interrupt associated with the facility
- temporarily before calling this function, however the associated 
-\emph on 
-facility_t
-\emph default 
- internally uses an 
-\emph on 
-_rlock_t
-\emph default 
- to prevent self-recursion, lock which is also used by 
-\emph on 
-hook_attach()
-\emph default 
- and 
-\emph on 
-hook_detach()
-\emph default 
- for safety.
- This function is made for the port-specific code to call when the interrupt
- this facility is concerned with occurs.
- This function is dependent on 
-\emph on 
-_FACILITY_MAX
-\emph default 
- and the 
-\emph on 
-enum _facilities
-\emph default 
- which are port-specific in <
-\emph on 
-port/support.h
-\emph default 
->.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-facilities_init(void)
-\emph default 
- is provided to ease initialization of the system facility arrays from the
- port-specific code.
- This function depends on the port-specific 
-\emph on 
-_FACILITY_MAX
-\emph default 
- and the 
-\emph on 
-enum _facilities
-\emph default 
- defined in <
-\emph on 
-port/support.h
-\emph default 
->.
- More informaton on port-specific initialization is provided in a next chapter.
-\layout Standard
-
-Decision was made to provide the above functions even though their functionality
- is simple for a few reasons.
- It prevents code duplication among ports, minimises assembly sections in
- machine-dependent sections, and they are known to work, providing the required
- functionality.
- Being abstracted, their internals may change over time affecting all ports
- simultaneously without requireing changes in the machine-specific sections.
- Moreover, they use an internal memory 
-\emph on 
-pool_t
-\emph default 
- per 
-\emph on 
-facility_t
-\emph default 
- for efficiency.
- Once initialized, those will never need to query the system page primitives,
- and are thus very efficient, as well as safe to use from interrupt context
- without special handling.
-\layout Standard
-
-Because these facilities are transparent to the Xisop microkernel itself,
- and are provided by port-specific code, although driven by common portable
- code, the interrupt sources are not required to internally correspond to
- actual hardware interrupts.
- The port-specific code is free to provide the wanted interrupt sources
- and facilities in the manner it wishes.
- As such they can be used for various hardware and sotfware event types.
-\layout Subsubsection
-
-User interface
-\layout Standard
-
-Here is now described the kernel user interface to manipulate custom interrupt
- hooks on the provided facilities.
- These are also machine-independent.
- They were implemented around 
-\emph on 
-_rlock_t
-\emph default 
- and 
-\emph on 
-pool_t
-\emph default 
- primitives in a way to make it possible for userland to access their functional
-ity without the need for system call traps.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-hookid_t\SpecialChar ~
-hook_attach(u_int32_t\SpecialChar ~
-facility, u_int32_t\SpecialChar ~
-skipcount, u_int32_t\SpecialChar ~
-runcount,
- void\SpecialChar ~
-(*code)(hookid_t,\SpecialChar ~
-int,\SpecialChar ~
-void\SpecialChar ~
-*), void\SpecialChar ~
-*data)
-\emph default 
- Allows to append or insert a user supplied code hook to the wanted interrupt
- facility.
- The 
-\emph on 
-facility
-\emph default 
- argument specifies what type of exception, trap or interrupt is wanted,
- and is port-specific.
- An example would be 
-\emph on 
-_FACILITY_VBLANK
-\emph default 
-.
-\emph on 
-code
-\emph default 
- specifies which function to call as the user hook handler, which should
- never be NULL.
-\emph on 
-data
-\emph default 
- points to an optional user data block which will be passed back when calling
- the function handler, and can be NULL.
- The argument of type 
-\emph on 
-hookid_t
-\emph default 
- which will be passed will consist of the unique ID representing this 
-\emph on 
-hook_t
-\emph default 
- into the 
-\emph on 
-facility
-\emph default 
-, while the 
-\emph on 
-int
-\emph default 
- argument, which is facility-specific, could serve to determine the origin
- of the event if the facility serves several.
- The return value is 0 in the case of an error (unknown public facility),
- or a unique ID which can be used to eventually delete that particular hook.
- This is required to not correspond to the hook function address, since
- multiple hooks may call the same function if wanted.
- This ID is always unique to this facility.
- It is safe to attach a code hook function which can expire and then attempt
- to remove it using the supplied 
-\emph on 
-hookid_t
-\emph default 
-.
- If it expired and another hook now uses the same 
-\emph on 
-hook_t
-\emph default 
- address, it's 
-\emph on 
-hookid_t
-\emph default 
- will still be different.
- The semantics of 
-\emph on 
-skipcount
-\emph default 
- and 
-\emph on 
-runcount
-\emph default 
- are explained in the internals above.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-hook_detach(u_int32_t\SpecialChar ~
-facility,\SpecialChar ~
-hookid_t\SpecialChar ~
-id)
-\emph default 
- Permits to remove a user supplied hook on the wanted 
-\emph on 
-facility
-\emph default 
-, with the specfied 
-\emph on 
-id
-\emph default 
-.
- Returns TRUE if it could find and delete the hook, or FALSE if the hook
- did not exist, or no longer does (it may have expired).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-facility_disable(u_int32_t\SpecialChar ~
-facility)
-\emph default 
- Disables all hooks of the specified facility temporarily.
- They cannot expire during the period they are suspended, and none will
- be executed, even when the interrupt source occurs.
- It does not disable the interrupt source.
- This system is recursive, in that the exact same number of calls to 
-\emph on 
-facility_enable()
-\emph default 
- must be made to re-enable the facility.
- Note that it is safe to attach and detach hooks from a facility at any
- time, and that this function is only provided as a feature.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-facility_enable(u_int32_t\SpecialChar ~
-facility)
-\emph default 
- Re-enables the specified facility which was previously suspended using
-\emph on 
-facility_disable()
-\emph default 
-, if the 
-\emph on 
-facility_t
-\emph default 
- internal 
-\emph on 
-_rlock_t
-\emph default 
- reaches 0 (that is all previous calls to 
-\emph on 
-facility_disable()
-\emph default 
- were matched by a 
-\emph on 
-facility_disable()
-\emph default 
-).
-\layout Subsubsection
-
-Common facilities
-\layout Standard
-
-Not all ports have all these facilities, and some may provide more.
- However, this consists of a guide so that facilities which are intended
- to provide the same functionality on the various architectures bear the
- same name.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_SCHEDTIMER
-\emph default 
- This is the only facility which must be available on all ports.
- It usually executes at intervals governed by 
-\emph on 
-_SCHEDTIMER_HZ
-\emph default 
-, a frequency defined in instances per second (hertz), which is defined
- in <
-\emph on 
-port/support.h
-\emph default 
->.
- Systems which only comport one hardware timer source will at least always
- have this timer facility available for multiple uses, although internally
- used by the scheduler.
- Disabling the scheduler does not disable the timer facility, as the scheduler
- lock consists of an 
-\emph on 
-_rlock_t
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_KEYBOARD
-\emph default 
- As the name implies, this facility is concerned with keyboard key presses.
- The key code is usually returned in the 
-\emph on 
-int
-\emph default 
- argument when calling the attached hooks.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_VBLANK
-\emph default 
- This facility is very useful for graphic-oriented software which need to
- synchronize operations with the video refresh rate.
- The frequency of a vertical blank interrupt varies with the underlaying
- hardware, but usually consists of 50Hz for PAL (europe) and 60Hz for NTSC
- (american) systems.
- This is very useful to implement double buffering, and can also be used
- to synchronize audio events like music and sound effects with animations.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_TRAP
-\emph default 
-* These type of facilities can be directly tied to user traps which may
- remain available, and associated to a related 
-\emph on 
-_cause()
-\emph default 
- function to allow user tasks to both attach handlers to receive those events
- and call 
-\emph on 
-_cause()
-\emph default 
- to trigger such events.
- However, because of the Xisop 
-\emph on 
-sys_custom()
-\emph default 
- system call, the use of such facilities become questionable.
-\emph on 
-XXX
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_FLOPPYSYNC
-\emph default 
- Triggered when a floppy drive notifies that it found the sync code of a
- track.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_FLOPPYBLOCK
-\emph default 
- Triggered when the floppy drive finished reading a requested block to memory.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_AUDIO
-\emph default 
- Notification that an audio channel finished playing a sample, or starts
- looping back the supplied sample buffer again.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_BLITTERREADY
-\emph default 
- Notification by a parallel hardware blitter that it is done with the requested
- operations and may now be ordered new instructions again.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_COPPER
-\emph default 
- A hardware raster parrallel blitter originated interrupt
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_SERIAL
-\emph default 
- A generic serial interrupt
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_SERIALRBF
-\emph default 
- A serial Read Buffer Full interrupt
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_FACILITY_SERIALTBE
-\emph default 
- A serial Transmit Buffer Empty interrupt
-\layout Standard
-
-Many other types of facilities may exist, although what should be taken
- as an example consists of the clear names that they are given, which directly
- reference to their origin as much as possible, while attempting to avoid
- cryptic names such as KBD for keyboard, etc.
- Where required, the label can be long enough as long as it remains meaningful.
-\layout Subsection
-
-Kernel statistics
-\layout Standard
-
-The 
-\emph on 
-src/common/kernel/statistic.
-\emph default 
-(
-\emph on 
-c
-\emph default 
-|
-\emph on 
-h
-\emph default 
-) module defines primitives for statistic counters.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsection
-
-Xisop binaries and executables
-\layout Standard
-
-The Xisop kernel currently has no ELF or a.out relocatable executable loader,
- and no custom format was implemented, which would require a GCC ld BFD
- backend to be written.
- This means that at current time, all the shared libraries, devices, handlers
- and user tasks need to be started by the kernel at startup.
- This is easily done however, but prevents the microkernel from using all
- it's features of attaching required components at runtime as wanted, although
- it was designed to eventually be able to do so efficiently.
- It however currently allows Xisop to be useable in embedded systems which
- have defined components, like for monolithic kernels.
-\layout Subsection
-
-Xisop devices
-\layout Standard
-
-Xisop devices generally consist of a medium-level backend to hardware-assisted
- services, such as keyboard input, tty output, RS-232 communication, etc.
- As such, they are generally architecture-dependent.
- Of course, machine-independent devices may be written as wanted, where
- the high-level handler interface is considered unadequate and that shared
- access to some kind of ressource is wanted, however.
-\layout Standard
-
-The Xisop devices are implemented around the message port system.
- There were two main reasons which determined this decision compared to
- using a shared library type system.
- First, the message receiving responsiveness and speed can be determined
- by the task priority, which allows the administrator to decide which devices
- and tasks to prioritize over others.
- Secondly, the message passing system already provides reliable FIFO queuing,
- and each message/request can be replied to when wanted, allowing a device
- to easily serve resources in a multitasking-friendly, asynchroneous manner
- to the simultaneous requesters.
-\layout Standard
-
-A device is thus implemented by a task, which decides to attach a system
- device node and then takes the responsibility to serve the expected requests.
- Each task may only attach one device to the system lists, and has to specify
- the device name and version which are used for other tasks to open the
- device.
- This means that a device name may have several simultaneous versions running
- on the system.
-\layout Standard
-
-Of course, there are cases where only a single device may control a specific
- hardware resource for instance, and in this case the versionning system
- becomes less useful, in which case version 0 is usually used.
- However, the version may still be useful if the various versions of the
- device had changes to the user interface.
- In this case, using the version is still useful, as opening using the wrong
- version (the one a task expects) will at least always fail cleanly with
- an error, rather than leaving the task to open a device which does not
- act as expected when sending requests.
-\layout Subsubsection
-
-User interface
-\layout Standard
-
-Here are described the device interface functions.
- Let's first present the functions which are intended for client tasks to
- access device server ones:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-device_t\SpecialChar ~
-*device_open(const\SpecialChar ~
-char\SpecialChar ~
-*name,\SpecialChar ~
-u_int32_t\SpecialChar ~
-version,\SpecialChar ~
-u_int32_t\SpecialChar ~
-unit)
-\emph default 
- Allows the task to open the unit number 
-\emph on 
-unit
-\emph default 
- of device 
-\emph on 
-name
-\emph default 
- of version 
-\emph on 
-version
-\emph default 
-.
- NULL is returned on failure, which can occur because of lack of memory,
- or if the specified device name of the specified version does not exist.
- Otherwise, a 
-\emph on 
-device_t
-\emph default 
- handle pointer is returned, which may then be used at 
-\emph on 
-iorequest_init()
-\emph default 
-.
- Device names are case-sensitive.
- If the task exists and that open devices have not been explicitely closed,
- the kernel automatically closes them.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-device_t\SpecialChar ~
-*device_close(device_t\SpecialChar ~
-*handle)
-\emph default 
- Closes a device handle which previously was opened using 
-\emph on 
-device_open()
-\emph default 
-.
- Always returns NULL.
- Any 
-\emph on 
-iorequest_t
-\emph default 
- associated to this 
-\emph on 
-device_t
-\emph default 
- may not be used anymore, as it becomes invalid, unless it be reinitialized
- again using 
-\emph on 
-iorequest_init()
-\emph default 
- using a new 
-\emph on 
-device_t
-\emph default 
- handle.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_init(iorequest_t\SpecialChar ~
-*message,\SpecialChar ~
-device_t\SpecialChar ~
-*handle,\SpecialChar ~
-port_t\SpecialChar ~
-*replyport)
-\emph default 
- Initializes an 
-\emph on 
-iorequest_t
-\emph default 
-\emph on 
-message
-\emph default 
-, which is necessary to use other 
-\emph on 
-iorequest_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions to perform device requests.
-\emph on 
-handle
-\emph default 
- specifies the 
-\emph on 
-device_t
-\emph default 
- which will serve requests for this message during future requests, and
-\emph on 
-replyport
-\emph default 
- of a generally 
-\emph on 
-iorequest_t
-\emph default 
--specific private port which was previously created, through which request
- result messages will be sent back to us by the device.
- The 
-\emph on 
-iorequest_t
-\emph default 
- buffer is the responsibility of the task, just like 
-\emph on 
-port_t
-\emph default 
-\emph on 
-message_t
-\emph default 
- are.
- Returns TRUE on success, or FALSE on failure (invalid arguments or out
- of memory).
- The device may optionally internally allocate device-specific additional
- data which will then attach to the 
-\emph on 
-iorequest_t
-\emph default 
-.
- These will however be allocated on the current task's memory pool, and
- are therefore released automatically if the task exists.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_destroy(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Invalidates the 
-\emph on 
-iorequest_t
-\emph default 
-\emph on 
-message
-\emph default 
- which was previously initialized using 
-\emph on 
-iorequest_init()
-\emph default 
-.
- As devices may internally allocate device-specific additional data and
- attach it to an 
-\emph on 
-iorequest_t
-\emph default 
- at initialization, a task should call this function when it no longer needs
- the 
-\emph on 
-iorequest_t
-\emph default 
-.
- Of course, if the task exists, the resources are automatically released
- back to the system, however.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_sync(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Permits to send a synchroneous request to a device, via 
-\emph on 
-message
-\emph default 
-.
- This means that the task is suspended until the request completes.
- The reply result is also automatically extracted from the reply port associated
- to the 
-\emph on 
-iorequest_t
-\emph default 
-.
- Before sending a request, some fields of the 
-\emph on 
-iorequest_t
-\emph default 
- message should be set.
- When it completes, the result fields will have been set.
- Both can have device-dependent semantics, although there is generally a
- standard, which is described in the internals section.
- Returns TRUE if the request could be sent, or FALSE if there was an internal
- problem (invalid 
-\emph on 
-message
-\emph default 
-, or no longer existing device).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_async(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Very similar to 
-\emph on 
-iorequest_sync()
-\emph default 
-, but permits to launch the request without waiting until it completes,
- performing an asynchroneous request.
- Upon completion, the device will internally 
-\emph on 
-port_reply()
-\emph default 
- into the reply port associated with 
-\emph on 
-message
-\emph default 
-, and the task is then responsible for extracting the reply message from
- the reply port.
- This allows to launch several asynchroneous requests and to monitor signals
- or ports to detect when they occur.
- For instance, a task may launch an asynchroneous request to read one character,
- and when the request completes, specifying that data exists to read.
- It can then send synchroneous requests to read larger blocks until no more
- data is available, in which case it may then again send an asynchroneous
- request and resume normal activity.
- TRUE is returned if the request could be launched, or FALSE if it failed
- (invalid 
-\emph on 
-message
-\emph default 
- or no longer existing device).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_abort(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- If 
-\emph on 
-message
-\emph default 
- currently consists of an asynchroneous request which was made using 
-\emph on 
-iorequest_async()
-\emph default 
- and is still pending, an abort request is sent to cancel it.
- Like usual, the device will reply still as soon as the request could be
- aborted, and the task becomes responsible to unlink the reply message from
- the reply port associated with 
-\emph on 
-message
-\emph default 
-.
- TRUE is returned on success, or FALSE if 
-\emph on 
-message
-\emph default 
- does not consist of a currently pending asynchroneous request.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_wait(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Waits until a currently pending (or aborted which not yet replied) asynchoneous
- request terminates, and automatically unlinks the reply message received
- through the reply port of 
-\emph on 
-message
-\emph default 
-.
- This can especially be useful after an 
-\emph on 
-iorequest_abort()
-\emph default 
-.
- Returns TRUE on success, or FALSE if 
-\emph on 
-message
-\emph default 
- is not currently a pending (or aborted which did not yet return) asynchroneous
- request.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_pending(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Returns TRUE if 
-\emph on 
-message
-\emph default 
- currently consists of an asynchroneously pending request, or FALSE otherwise.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_aborted(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Returns TRUE if 
-\emph on 
-message
-\emph default 
- consists of a request which just completed, but which was an asynchroneous
- request and was aborted.
-\layout Standard
-
-These utility functions, although performing the most basic Xisop device
- operations, are provided to minimize code duplication, for very simple
- synchroneous I/O.
- Normally, tasks will address requests using 
-\emph on 
-iorequest_sync()
-\emph default 
- and 
-\emph on 
-iorequest_async()
-\emph default 
- as needed, but this can be useful to have:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-ssize_t\SpecialChar ~
-device_read(iorequest_t\SpecialChar ~
-*req,\SpecialChar ~
-void\SpecialChar ~
-*buf,\SpecialChar ~
-size_t\SpecialChar ~
-len)
-\emph default 
- Similarily to unix 
-\emph on 
-read()
-\emph default 
-, reads at most 
-\emph on 
-len
-\emph default 
- bytes of data from the opened device and unit associated with 
-\emph on 
-req
-\emph default 
- into 
-\emph on 
-buf
-\emph default 
-, and returns the number of actually read bytes, or -1 on error.
- The current task is suspended until the operation completes, since 
-\emph on 
-iorequest_sync()
-\emph default 
- is internally used.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-ssize_t\SpecialChar ~
-device_write(iorequest_t\SpecialChar ~
-*req,\SpecialChar ~
-void\SpecialChar ~
-*buf,\SpecialChar ~
-size_t\SpecialChar ~
-len)
-\emph default 
- Like unix 
-\emph on 
-write()
-\emph default 
-, writes at most 
-\emph on 
-len
-\emph default 
- bytes of data from 
-\emph on 
-buf
-\emph default 
-, to the opened device and unit associated with 
-\emph on 
-req
-\emph default 
-, and returns the number of actually written bytes, or -1 on error.
- The current task is suspended until the operation completes as it internally
- uses 
-\emph on 
-iorequest_sync()
-\emph default 
-.
-\layout Subsubsection
-
-Device server interface
-\layout Standard
-
-Here follows functions which are only useful to device server tasks to call:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-device_attach(const\SpecialChar ~
-char\SpecialChar ~
-*name, u_int32_t\SpecialChar ~
-version, port_t\SpecialChar ~
-*port, void\SpecialChar ~
-(*clean)(vo
-id), bool\SpecialChar ~
-(*open)(void\SpecialChar ~
-**,\SpecialChar ~
-u_int32_t), void\SpecialChar ~
-(*close)(void\SpecialChar ~
-*,\SpecialChar ~
-u_int32_t), void\SpecialChar ~
-*(*iorini
-t)(void), void\SpecialChar ~
-(*iordestroy)(void\SpecialChar ~
-*), u_int8_t\SpecialChar ~
-flags)
-\emph default 
-
-\newline 
-Allows the current task to become a system device.
-\emph on 
-name
-\emph default 
- consists of the unique case-sensitive device name to assign to the system
- device node, which will be required to use at 
-\emph on 
-device_open()
-\emph default 
-, and will be truncated to 32 characters if longer.
-\emph on 
-version
-\emph default 
- specifies the version number to use, which will also need to match at 
-\emph on 
-device_open()
-\emph default 
-, for this device name.
-\emph on 
-port
-\emph default 
- consists of the device server's private port, through which requests should
- be sent.
-\emph on 
-flags
-\emph default 
- consists of one or combination of 
-\emph on 
-DNF_
-\emph default 
-* flags described in the header file, like 
-\emph on 
-DNF_RESIDENT
-\emph default 
- which tells Xisop to never cause the device task to exit if there exist
- no more client open instances.
- The various function pointers which must be supplied are explained below:
-\begin_deeper 
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-(*clean)(void)
-\emph default 
- is a function which the device task can provide for Xisop to call when
- no more client open instances exist for this device, unless the device
- is resident (and 
-\emph on 
-flags
-\emph default 
- comported 
-\emph on 
-DNF_RESIDENT
-\emph default 
- at device creation).
- This function is responsible to restore the hardware which this device
- may have been serving to a consistant and known state.
- It will also be called automatically by Xisop when the task exits normally.
- Note that 
-\emph on 
-clean()
-\emph default 
- should not comport any special function to cause the task to end.
- Xisop will send a 
-\emph on 
-SIGTERM
-\emph default 
- signal when the task should do so.
- If the task exits by itself, 
-\emph on 
-clean()
-\emph default 
- will be called automatically nevertheless.
- Because this function may be called under the context of any other task,
- it should not expect to execute under the device's task memory pool (and
- therefore should normally not call allocation functions).
- It is possible to specify NULL for this function if the device has no need
- for any special cleanup function.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-(*open)(void\SpecialChar ~
-**udata,\SpecialChar ~
-u_int32_t\SpecialChar ~
-unit)
-\emph default 
- All devices are required to provide this function.
- It's purpose is to validate if 
-\emph on 
-unit
-\emph default 
- can be opened (some devices limit the number of open instances of a unit,
- to protect their resources), and to optionally allocate any needed device-speci
-fic data which it may need to attach to 
-\emph on 
-device_t
-\emph default 
- nodes.
-\emph on 
-open()
-\emph default 
- is called at each 
-\emph on 
-device_open()
-\emph default 
- function instance called on this device.
- It is expected to return FALSE if it refuses to open the specified 
-\emph on 
-unit
-\emph default 
- or if it cannot allocate any required resources, or TRUE on success.
- If the task allocates data which is needed to be attached to the 
-\emph on 
-device_t
-\emph default 
- handle, it should supply the address of the allocated data block into the
- supplied 
-\emph on 
-udata
-\emph default 
-.
- It should set NULL there otherwise.
- Although the device may at it's discretion maintain counters on the number
- of currently opened units, etc, Xisop will automatically send a SIGTERM
- to the device task if it is non-resident and that there exist no more openers.
- Note that this function is called under the context of the task which calls
-\emph on 
-device_open()
-\emph default 
-.
- As such, the memory allocations, such as the optional 
-\emph on 
-udata
-\emph default 
- block will be automatically freed when the other task ends, not ours.
- For this reason, the function can use 
-\emph on 
-malloc()
-\emph default 
- and companions safely, but should not use lower-level Xisop kernel allocation
- primitives.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-(*close)(void\SpecialChar ~
-*udata,\SpecialChar ~
-u_int32_t\SpecialChar ~
-unit)
-\emph default 
- This function is also required for all device tasks to provide, and is
- called by 
-\emph on 
-device_close()
-\emph default 
- on a 
-\emph on 
-device_t
-\emph default 
- handle which was previously associated to this task by 
-\emph on 
-device_open()
-\emph default 
-.
- The function is responsible for calling 
-\emph on 
-free()
-\emph default 
- on the supplied 
-\emph on 
-udata
-\emph default 
- pointer if needed, and to perform the necessary device-specific cleanup
- required when a device handle closes.
-\emph on 
-unit
-\emph default 
- specifies the unit which was opened by this handle.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*(*iorinit)(void)
-\emph default 
- Devices may optionally provide this function to allocate 
-\emph on 
-iorequest_t
-\emph default 
- message specific data which it might need, very similarily to 
-\emph on 
-open()
-\emph default 
- which can attach data to a 
-\emph on 
-device_t
-\emph default 
- handle.
- NULL can be supplied if there is no need for 
-\emph on 
-iorequest_t
-\emph default 
- specific extention data.
- This function is called under the context of the task calling 
-\emph on 
-iorequest_init()
-\emph default 
- and as such no Xisop low-level allocation functions should be called.
- The function may allocate the data block with 
-\emph on 
-malloc()
-\emph default 
-, initialize it and return a pointer to it, or NULL on failure (out of memory).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-(iordestroy)(void\SpecialChar ~
-*udata)
-\emph default 
- May also be supplied NULL if NULL was supplied for 
-\emph on 
-iorinit()
-\emph default 
-.
- Otherwise, this function is responsible to 
-\emph on 
-free()
-\emph default 
- the supplied 
-\emph on 
-udata
-\emph default 
-, which corresponds to a block of memory which was returned by a previous
-\emph on 
-iorinit()
-\emph default 
- call.
-\end_deeper 
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-iorequest_satisfy(iorequest_t\SpecialChar ~
-*message,\SpecialChar ~
-bool\SpecialChar ~
-result)
-\emph default 
- Is a useful utility function to set the main request success result code
- and reply to the task that it has completed.
-\layout Standard
-
-Various macros of interest may be used by device tasks:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*DEVICEHANDLE_UDATA(device_t\SpecialChar ~
-*handle)
-\emph default 
- Returns the 
-\emph on 
-udata
-\emph default 
- pointer associated with the supplied 
-\emph on 
-device_t
-\emph default 
-\emph on 
-handle
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-*IOREQUEST_UDATA(iorequest_t\SpecialChar ~
-*message)
-\emph default 
- Returns the 
-\emph on 
-udata
-\emph default 
- pointer associated with the supplied 
-\emph on 
-iorequest_t message
-\emph default 
-.
-\layout Subsubsection
-
-Internals
-\layout Standard
-
-This system based upon the Xisop message ports system and the previously
- described functions permit to open or provide devices, and to communicate
- requests from the client-side and completion from the server-side, through
- a special message, the 
-\emph on 
-iorequest_t
-\emph default 
-.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsection
-
-Xisop handlers
-\layout Standard
-
-Handlers provide a higher-level abstraction to devices or resources.
- It should be noted that unlike devices, these are implemented in the form
- of a standard shared library format.
- This means that devices are usually a nice abstraction to mount handlers
- on, as devices naturally perform the queuing, etc.
-\emph on 
-XXX
-\layout Subsection
-
-Xisop shared libraries
-\layout Standard
-
-The concept of Xisop shared libraries is both very simple, and unusual.
- It is important that all functions a library provides publically be reentrant.
- Opening a library basically obtains the pointer to a structure which is
- necessary to access it's function pointers.
- As such, only one resident copy is required for all applications, and new
- applications can 
-\begin_inset Quotes eld
-\end_inset 
-
-attach
-\begin_inset Quotes erd
-\end_inset 
-
- the libraries they need as required.
- The system keeps track of how many times it is currently being open by
- various tasks, and can therefore know when the library should be expunged
- from memory.
- Obviously, when a library is requested which is not currently in RAM, it
- should be loaded in the system from disk.
-\layout Standard
-
-Each library may have concurrent versions on the same system, in memory
- and on disk.
- When an application requests access to a library, it optionally specifies
- the expected version, without which the latest is assumed.
- This way, it is possible for the administrator to get rid of the obsolete
- libraries but only after making sure that no applications require them
- anymore.
- While software is being developped, it becomes possible to have concurrent
- versions of applications each using their respectively related material.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsubsection
-
-The Xisop library
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsection
-
-Xisop system calls
-\layout Standard
-
-System calls are different than normal functions in that they allow userspace
- tasks to execute instructions which are normally only allowed to call in
- supervisor mode, or in kernel space.
- Moreover, system calls are currently uninterruptible in Xisop, which means
- that the task is guaranteed to not be preempted while executing a system
- call function, until it returned.
- These are internally implemented using processor traps, by the port-specific
- code.
- However, the system call functions themselves are portable and part of
- the Xisop common code.
- Because Xisop does not use MMU facilities, system calls are very fast to
- execute compared to on unix systems.
- Xisop design attempts to require the less of these possible however, because
- they also disable the scheduler when executing.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-struct\SpecialChar ~
-xisop_root\SpecialChar ~
-*sys_getroot(void)
-\emph default 
- Permits a task to obtain the address of the main Xisop control structure,
- where system lists are stored.
- Obviously, if a task uses this information in any way, it has to be careful
- not to disrupt Xisop activities.
- It is recommended to disable the scheduler and/or interrupts where required
- to access the information which that structure provides.
- It is made for people who know Xisop inside out only.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sys_int_disable(void)
-\emph default 
- This internally calls 
-\emph on 
-_splhigh()
-\emph default 
- which ensures to mask all interrupts, including that of the preemptive
- scheduler.
- Precautions should be made about the calls used similarly to when disabling
- the scheduler.
- However, this call permits a task to completely take control over Xisop.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sys_int_enable(void)
-\emph default 
- Internally calling 
-\emph on 
-_spl0()
-\emph default 
-, this re-enables all interrupts.
-\emph on 
-XXX
-\emph default 
- heh actually, can the 
-\emph on 
-_syscall()
-\emph default 
- trap actually occur after a 
-\emph on 
-sys_int_disable()
-\emph default 
-? Will need to check this out.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sys_idle(void)
-\emph default 
- Permits to suspend the processor until the next trap, interrupt or exception
- occurs.
- This internally calls the 
-\emph on 
-_idle()
-\emph default 
- processor-specific function.
- This is mostly used by Xisop 
-\emph on 
-main()
-\emph default 
- which is returned control to when no tasks are currently on the ready queue.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-sys_custom(void\SpecialChar ~
-*res,\SpecialChar ~
-void\SpecialChar ~
-(*func)(void\SpecialChar ~
-*,\SpecialChar ~
-void\SpecialChar ~
-*),\SpecialChar ~
-void\SpecialChar ~
-*args)
-\emph default 
- A very special system call, allows user tasks to execute arbitrary code
- in supervisor mode, uninterruptibly (scheduler will not preempt, but interrupts
- can still take place).
-\emph on 
-func
-\emph default 
- specifies the function to call, which will be passed 
-\emph on 
-res
-\emph default 
- as the first argument and 
-\emph on 
-args
-\emph default 
- as the second argument, which can be used by the function to acquire parameters
- and return results.
-\emph on 
-res
-\emph default 
- and 
-\emph on 
-args
-\emph default 
- can be NULL when they are not needed.
- Because Xisop attempts to be more useful to the programmer than to secure
- the kernel against userland, this was beleived to be a very useful function,
- where user tasks can create their custom system calls as required.
-\layout Subsection
-
-Xisop general programming interfaces
-\layout Standard
-
-In an attempt to keep the code unified and clean, multipurpose interfaces
- were provided.
-\layout Subsubsection
-
-Byte alignment macros
-\layout Standard
-
-In 
-\emph on 
-<common/types.h>
-\emph default 
- the following macros are provided for byte alignment.
-\layout Standard
-
-These macros permit object size related byte alignment:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-size_t\SpecialChar ~
-OALIGN_CEIL(size_t\SpecialChar ~
-v,\SpecialChar ~
-o)
-\emph default 
-\emph on 
-o
-\emph default 
--aligns 
-\emph on 
-v
-\emph default 
-.
- This macro rounds 
-\emph on 
-v
-\emph default 
- to the nearest larger unit as required.
-\emph on 
-o
-\emph default 
- should be any native C or custom structure type, to which 
-\emph on 
-v
-\emph default 
- should be aligned relative to.
-\emph on 
-v
-\emph default 
- is not modified, the new value is returned.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-size_t\SpecialChar ~
-OALIGN_FLOOR(size_t\SpecialChar ~
-v,\SpecialChar ~
-o)
-\emph default 
-\emph on 
-o
-\emph default 
--aligns 
-\emph on 
-v
-\emph default 
-.
- Unlike 
-\emph on 
-OALIGN_CEIL()
-\emph default 
- this macro rounds to the nearest smaller unit as required.
-\layout Standard
-
-And these macros permit byte size related alignment:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-size_t\SpecialChar ~
-BALIGN_CEIL(size_t\SpecialChar ~
-v,\SpecialChar ~
-size_t\SpecialChar ~
-s)
-\emph default 
- This macro aligns 
-\emph on 
-v
-\emph default 
- to the nearest larger unit relative to 
-\emph on 
-s
-\emph default 
- size as required.
-\emph on 
-v
-\emph default 
- is not modified, the new value is returned.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-size_t\SpecialChar ~
-BALIGN_FLOOR(size_t\SpecialChar ~
-v,\SpecialChar ~
-size_t\SpecialChar ~
-s)
-\emph default 
- Very similar to 
-\emph on 
-BALIGN_CEIL()
-\emph default 
-, but rounds 
-\emph on 
-v
-\emph default 
- to the nearest smaller unit relative to 
-\emph on 
-s
-\emph default 
- size as required.
-\layout Subsubsection
-
-Byte order manipulation macros
-\layout Standard
-
-In 
-\emph on 
-<common/types.h>
-\emph default 
- the following macros are provided for byte order/endian conversions.
- These are most useful for network Remote Procedure Call implementations,
- as well as for binary file formats which can be in network order so that
- multiple architectures may easily use the same file format.
- Depending on the native host byte order (the 
-\emph on 
-_ARCH_BIG_ENDIAN
-\emph default 
- and 
-\emph on 
-_ARCH_LITTLE_ENDIAN
-\emph default 
- definitions defined by processor-specific code), these will perform no
- action where no conversion is necessary.
- The network order should be used for transferring over networks or writing
- to binary files, and actually corresponds to the native host byte order
- on big endian architectures.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int16_t\SpecialChar ~
-BYTEORDER_NETWORK16(u_int16_t)
-\emph default 
- Converts the specified 16-bit word to network order for sending through
- the network or writing to a binary file.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int16_t\SpecialChar ~
-BYTEORDER_HOST16(u_int16_t)
-\emph default 
- Converts the specified network order 16-bit word to native host order after
- reading from a binary file or receiving through the network.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int32_t\SpecialChar ~
-BYTEORDER_NETWORK32(u_int32_t)
-\emph default 
- Converts the specified 32-bit word to network order for sending through
- the network or writing to a binary file.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int32_t\SpecialChar ~
-BYTEORDER_HOST32(u_int32_t)
-\emph default 
- Converts the specified network order 32-bit word to native host order after
- reading from a binary file or receiving through the network.
-\layout Subsubsection
-
-Doubly linked lists
-\layout Standard
-
-These macros, as well as the 
-\emph on 
-list_t
-\emph default 
- and 
-\emph on 
-node_t
-\emph default 
- types are defined in 
-\emph on 
-<common/types.h>
-\emph default 
- and 
-\emph on 
-<common/kernlib/list.h>
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_INIT(list_t\SpecialChar ~
-*list)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_APPEND(list_t\SpecialChar ~
-*list,\SpecialChar ~
-node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_INSERT(list_t\SpecialChar ~
-*list,\SpecialChar ~
-node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_INSERTAT(list_t\SpecialChar ~
-*list,\SpecialChar ~
-node_t\SpecialChar ~
-*atnode,\SpecialChar ~
-node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_SWAP(list\SpecialChar ~
-t\SpecialChar ~
-*dstlist,\SpecialChar ~
-list_t\SpecialChar ~
-*srclist,\SpecialChar ~
-node_t\SpecialChar ~
-*srcnode,\SpecialChar ~
-bool\SpecialChar ~
-insert)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_UNLINK(list_t\SpecialChar ~
-*list,\SpecialChar ~
-node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int32_t\SpecialChar ~
-DLIST_NODES(list_t\SpecialChar ~
-*list)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-node_t\SpecialChar ~
-*DLIST_TOP(list_t\SpecialChar ~
-*list)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-node_t\SpecialChar ~
-*DLIST_BOTTOM(list_t\SpecialChar ~
-*list)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-node_t\SpecialChar ~
-*DLIST_NEXT(node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-node_t\SpecialChar ~
-*DLIST_PREV(node_t\SpecialChar ~
-*node)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-DLIST_FOREACH(list_t\SpecialChar ~
-*list,\SpecialChar ~
-node_t\SpecialChar ~
-*iterator)
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsubsection
-
-Hash based fast lookup tables
-\layout Standard
-
-The prototypes and types for these are defined in 
-\emph on 
-<common/types.h>
-\emph default 
- and 
-\emph on 
-<common/kernlib/hash.h>
-\emph default 
-.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsubsection
-
-FIFO (First In, First Out) buffers
-\layout Standard
-
-These macros as well as the default FIFO types are defined in 
-\emph on 
-<common/types.h>
-\emph default 
- and 
-\emph on 
-<common/kernlib/fifo.h>
-\emph default 
-.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsubsection
-
-LIFO (Last In, First Out / Stack) buffers
-\layout Standard
-
-These macros as well as the default LIFO types are defined in 
-\emph on 
-<common/types.h>
-\emph default 
- and 
-\emph on 
-<common/kernlib/lifo.h>
-\emph default 
-.
-\layout Standard
-
-
-\emph on 
-XXX
-\layout Subsection
-
-Xisop source tree organization
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-doc/
-\emph default 
- This directory holds this file, as well as various notes of interest
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/
-\emph default 
- Where all source resides
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/
-\emph default 
- All machine-independent Xisop source
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/kernel/
-\emph default 
- Xisop kernel main code
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/kernlib/
-\emph default 
- Xisop kernel main machine-independent libraries
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/library/
-\emph default 
- Xisop machine-independent shared libraries
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/device/
-\emph default 
- Xisop machine-independent devices
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/handler/
-\emph default 
- Xisop machine-independent handlers
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/common/task/
-\emph default 
- Xisop machine-independent resident tasks
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/processors/
-\emph default 
- Holds all processor-specific code
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/processors/m68k/
-\emph default 
- The Motorola m68k support (MC68000L8/L10)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/processors/m68k/kernlib/
-\emph default 
- m68k specific replacement functions for wanted standard machine-independent
- kernlib ones (optional)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/
-\emph default 
- Holds all port-specific code, including boot loaders
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/
-\emph default 
- The Amiga port of Xisop code resides here
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/kernlib/
-\emph default 
- Amiga-specific replacement functions for wanted standard machine-independent
- kernlib ones (optional)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/boot/
-\emph default 
- The Amiga-specific code to generate a bootable kernel
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/library/
-\emph default 
- Amiga-specific shared libraries (optional)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/device/
-\emph default 
- Amiga-specific devices (optional)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/handler/
-\emph default 
- Amiga-specific handlers (optional)
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/ports/amiga/task/
-\emph default 
- Amiga-specific resident tasks (optional)
-\layout Subsection
-
-The build process
-\layout Standard
-
-Here is described the way the Xisop source is built to create a binary kernel
- image.
-\emph on 
-/bin/sh
-\emph default 
- is also assumed to exist for the building process.
- The convention for the script names are as follows:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/generic_makedefs.sh
-\emph default 
- contains various sh functions and variables assigned to local utilities
- which are required by all 
-\emph on 
-clean.sh
-\emph default 
- scripts, and the main 
-\emph on 
-src/make.sh
-\emph default 
- script.
- Those scripts 
-\emph on 
-source
-\emph default 
- this file to obtain the common information.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/makedefs.sh
-\emph default 
- consists of a symbolic link to 
-\emph on 
-port/makedefs.sh
-\emph default 
-, which contains the configuration information required to build the for
- the target port system.
- The paths to the various useful utilities are assigned to shell variables.
- If functions need to be supplied for other build scripts, they also should
- be defined here.
- This file is sourced (included) by all other build scripts.
- They all should use the variables supplied by this file when accessing
- the cross-compile or local utilities.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/make.sh
-\emph default 
- allows to fully compile the kernel to result in a kernel image.
- Requires the target port name to be specified, as it also sets up required
- symbolic links.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-src/clean.sh
-\emph default 
- cleans the source tree, that is, deletes all files which may have been
- created by the build process.
-\layout List
-\labelwidthstring 00.00.0000
-
-*
-\emph on 
-/make.sh
-\emph default 
- The various sections described below will need such a script which should
- perform the necessary steps to compile the section.
- These 
-\emph on 
-source
-\emph default 
- src/
-\emph on 
-makedefs.sh
-\emph default 
- to know which commands to invoke and access useful 
-\emph on 
-/bin/sh
-\emph default 
- macros..
-\layout List
-\labelwidthstring 00.00.0000
-
-*
-\emph on 
-/clean.sh
-\emph default 
- The sections also need such a script which is expected to delete all files
- which the 
-\emph on 
-make.sh
-\emph default 
- script counterpart creates.
- These 
-\emph on 
-source
-\emph default 
-\emph on 
-src/generic_makedefs.sh
-\emph default 
-.
-\layout Paragraph
-
-Cleaning the whole source tree
-\layout Standard
-
-The 
-\emph on 
-src/clean.sh
-\emph default 
- script ensures to clean the whole source tree by calling the 
-\emph on 
-clean.sh
-\emph default 
- script for each section, including all ports and processors.
- The invoker is expected to be in the 
-\emph on 
-src/
-\emph default 
- directory.
-\layout Paragraph
-
-Building the system
-\layout Standard
-
-The 
-\emph on 
-src/make.sh
-\emph default 
- script builds the entire system.
- The main steps performed to compile the system are described as follows,
- in order.
-\layout Subsubsection
-
-Preliminary building process setup
-\layout Standard
-
-The 
-\emph on 
-src/processor,
-\emph default 
-\emph on 
-src/port
-\emph default 
- and 
-\emph on 
-src/makedefs.sh
-\emph default 
- symbolic links should point to their corresponding 
-\emph on 
-src/processors/<directory>
-\emph default 
- and 
-\emph on 
-src/ports/<directory>
-\emph default 
- and 
-\emph on 
-src/ports/<directory>/makedefs.sh
-\emph default 
-.
- These are setup depending on the target system for which Xisop is being
- built.
- Each of these (port and processor sections) supplies a 
-\emph on 
-support.h
-\emph default 
- headerfile which should be sufficient for the rest of the kernel code to
- access the functionality of the hardware specific code they provide.
- Moreover, each of them will after building provide 
-\emph on 
-ar
-\emph default 
- archives (
-\emph on 
-.a
-\emph default 
- files) into their respective 
-\emph on 
-ar/
-\emph default 
- directory, resulting from their various object files, which will be sufficient
- to link with the rest of the kernel code to achieve the end result.
- The 
-\emph on 
-src/make.sh
-\emph default 
- script creates these symbolic links when supplied with a valid 
-\emph on 
-target
-\emph default 
- (using the 
-\emph on 
--t
-\emph default 
- parameter).
-\layout Standard
-
-
-\emph on 
-src/make.sh
-\emph default 
- also ensures to set the 
-\emph on 
-$SRCDIR
-\emph default 
- environment variable to the absolute path to the current directory (
-\emph on 
-src/
-\emph default 
-), which should be used by other build scripts when compiling modules so
- that 
-\emph on 
-#include
-\emph default 
- directives in the source can locate the file using 
-\emph on 
--I
-\emph default 
- parameter, etc.
-\layout Subsubsection
-
-Building the processor-specific support code
-\layout Standard
-
-Control is delegated to 
-\emph on 
-src/processor
-\emph default 
-/
-\emph on 
-make.sh
-\emph default 
-.
- This is expected to assemble and compile the various sections it comports
- to binary objects independently (
-\emph on 
-.o
-\emph default 
-) using 
-\emph on 
--c
-\emph default 
- parameter to 
-\emph on 
-gcc
-\emph default 
- command, and to then archive them as 
-\emph on 
-ar
-\emph default 
- archives into the 
-\emph on 
-src/processor/ar
-\emph default 
- directory using the 
-\emph on 
-ar
-\emph default 
- and 
-\emph on 
-ranlib
-\emph default 
- commands.
- This final object will be linked with the kernel code by another section
- of the build process.
- It is to be noted that it will be linked before the general common machine-inde
-pendent kernel library, so that it is possible to provide processor-specific
- replacements to standard low-level functions, such as 
-\emph on 
-memcpy()
-\emph default 
-, 
-\emph on 
-memset()
-\emph default 
-, etc.
- These could however be overriden by the port-specific support code.
- When control is given to 
-\emph on 
-make.sh
-\emph default 
- of this section, the current directory will have been changed as well so
- that it is safe to access the section files relatively to the current (section)
- directory.
-\layout Subsubsection
-
-Building the port-specific support code
-\layout Standard
-
-Control is given to 
-\emph on 
-src/port/make.sh
-\emph default 
- to compile this section, and very similarly to the processor-specific section,
- the goal is to generate one or more 
-\emph on 
-ar
-\emph default 
- archive in the 
-\emph on 
-src/port/ar
-\emph default 
- directory.
-\emph on 
-src/port/support.h
-\emph default 
- will also contain all necessary information for the rest of the kernel
- code to use the port-specific support.
- This code will be linked with the global kernel before s
-\emph on 
-rc/processor/ar/*.a
-\emph default 
-, which means that it is possible to provide port-specific standard functions
- overriding the processor-specific ones, as well as kernel machine-independent
- common ones.
- This could allow for instance to provide 
-\emph on 
-memcpy()
-\emph default 
- and 
-\emph on 
-memset()
-\emph default 
- functions using specialized data moving hardware such as blitters, etc.
- It is however recommended that libraries be built in a way to not force
- the whole library to be included into the final kernel if only a few of
- the functions were necessary.
- To do this, a library could consists of a directory, with all functions
- isolated in their own 
-\emph on 
-.c
-\emph default 
- file.
- The 
-\emph on 
-ar
-\emph default 
- archive then results in a bunch of very small 
-\emph on 
-.o
-\emph default 
- files which will be ignored by the linker when unrequired.
- It is important to also run 
-\emph on 
-ranlib
-\emph default 
- on the 
-\emph on 
-ar
-\emph default 
- archive.
-\layout Standard
-
-
-\emph on 
-XXX
-\emph default 
-\emph on 
-Hmm I should find a nice way to define the resident libraries, devices and
- handlers, both common and port-specific ones.
- Also, which tasks should be initially started, etc.
- Actually, resident devices and handlers, being tasks, would just need to
- be included in the tasks to start, I guess...
-\layout Standard
-
-
-\emph on 
-XXX This next paragraph is currently invalid.
-\layout Standard
-
-The 
-\emph on 
-ar/*.a
-\emph default 
- result should also include 
-\emph on 
-_init_libraries()
-\emph default 
-, 
-\emph on 
-_init_devices()
-\emph default 
- and 
-\emph on 
-_init_handlers()
-\emph default 
- functions, which should as required attach the wanted shared libraries,
- devices and handlers in the kernel by calling their init function.
- These also should initialize machine-independent ones.
- If there are port-dependent ones, their code should be located into the
-\emph on 
-library/
-\emph default 
-, 
-\emph on 
-device/
-\emph default 
- and 
-\emph on 
-handler/
-\emph default 
- directories in 
-\emph on 
-src/port/
-\emph default 
-.
-\layout Subsubsection
-
-Building the machine-independent main Xisop code
-\layout Standard
-
-The 
-\emph on 
-src/common/kernlib/
-\emph default 
- directory comports a directory for each internal kernel library, which
- each contain functions isolated into a single file each.
- These are built separately as object modules, and are archived using 
-\emph on 
-ar
-\emph default 
- and 
-\emph on 
-ranlib
-\emph default 
- into 
-\emph on 
-src/common/kernlib/ar 
-\emph default 
-directory.
- The reason for this is that it allows the resulting kernel image to be
- smaller when not all of the functions of a particular library are used.
- If all string functions were located into the same 
-\emph on 
-string.c
-\emph default 
- file for instance, all of the string functions would automatically be linked
- within the result even if only two string functions were actually used,
- for instance.
-\layout Standard
-
-The 
-\emph on 
-src/common/kernel/
-\emph default 
- and 
-\emph on 
-src/common/kernlib/
-\emph default 
- sections containing only portable C code are compiled, and their modules
- archived with 
-\emph on 
-ar
-\emph default 
- and 
-\emph on 
-ranlib
-\emph default 
-, to 
-\emph on 
-src/common/kernel/ar/*.a
-\emph default 
- and 
-\emph on 
-src/common/kernlib/ar/*.a
-\emph default 
- files.
- At current time, 
-\emph on 
-src/common/library/
-\emph default 
-, 
-\emph on 
-src/common/device/
-\emph default 
- and 
-\emph on 
-src/common/handler/
-\emph default 
- sections are all compiled and archived together as 
-\emph on 
-src/common/ar/*.a
-\emph default 
-.
-\emph on 
-XXX This last statement is false as nothing is done for libraries, devices
- and handlers at current time..
-\layout Subsubsection
-
-Linking the final kernel
-\layout Standard
-
-
-\emph on 
-src/common/kernel/kernel
-\emph default 
-.
-\emph on 
-a
-\emph default 
-, 
-\emph on 
-src/port/support.
-\emph default 
-a, 
-\emph on 
-src/processor/support.a
-\emph default 
-, 
-\emph on 
-src/common/kernlib/kernlib.a
-\emph default 
- and 
-\emph on 
-src/common/shared.a
-\emph default 
- are linked together, in that order, into the ELF relocatable 
-\emph on 
-src/xisop.o
-\emph default 
- file (using 
-\emph on 
--r
-\emph default 
- option to ld).
- This allows processor-specific libraries to replace 
-\emph on 
-common/kernlib
-\emph default 
- functions, and port-specific ones to override both processor-specific and
- common ones.
-\layout Subsubsection
-
-Linking the final kernel and building the bootable Xisop result
-\layout Standard
-
-After building both the machine dependent and independent sections described
- above, the control is then left to 
-\emph on 
-src/port/boot/make.sh
-\emph default 
-, after changing to the 
-\emph on 
-src/port/boot directory
-\emph default 
-.
- The role of this final script is to complete the linking and building process.
- Here is what currently happens:
-\layout Standard
-
-As a general rule, image_script.ld file in that directory comports the necessary
- information to statically link monolithically the whole kernel as a binary
- image.
- Here is an excerpt of what 
-\emph on 
-src/ports/amiga/boot/make.sh
-\emph default 
- does:
-\layout Itemize
-
-show $C_COMPC -I$SRCDIR init.c
-\layout Itemize
-
-A=`$L_LS ../../../common/kernel/ar/*.a ../ar/*.a ../../../processor/ar/*.a ../..
- /../common/kernlib/ar/*.a`
-\layout Itemize
-
-show $C_LD -nostdlib -e _start -Ttext 0x005f8000 -o image.o init.o $A
-\layout Itemize
-
-show $C_LD -T image_script.ld -nostdlib -o image.bin init.o $A
-\layout Itemize
-
-...
-\layout Standard
-
-The first operation compiles it's initialization code, which provides the
-\emph on 
-_start
-\emph default 
- entrypoint, which eventually calls Xisop 
-\emph on 
-main()
-\emph default 
-.
- Then is compiled a list of the various 
-\emph on 
-ar
-\emph default 
- archives which should be linked.
- The order of these archives is important, as it permits the processor-specific
- code to override the common code, and the port-specific code to override
- the processor specific and common code.
-\layout Standard
-
-Then follows the linking process, which is done two time.
- The first instance creates 
-\emph on 
-image.o
-\emph default 
- which can then be viewed and disassembled using the 
-\emph on 
-objdump
-\emph default 
- utility.
- This is mostly used for debugging so that at runtime in the emulator it
- is possible to stop the emulation process and fall into the debugger, which
- then discloses the current executing address.
- That same address in image.o disassembly should match, and this is where
- it can be handy.
-\layout Standard
-
-The second linking command creates the binary Xisop kernel image using the
-\emph on 
-image_script.ld
-\emph default 
- linker script, to result in 
-\emph on 
-image.bin
-\emph default 
-.
- This is the actual image, which expects to be loaded into memory at the
- address 0x005f8000, and jumped to.
- (See the 
-\emph on 
-image_script.ld
-\emph default 
- and 
-\emph on 
-make.sh
-\emph default 
- scripts for more information).
-\layout Standard
-
-The script then proceeds to compile the disk boot loader (floppy in this
- case), which is located into the 
-\emph on 
-bootf/
-\emph default 
- directory.
- It then compiles the tools which are needed to assemble the result and
- fix the bootblock checksum using the the local compiler (not the cross
- compiler, although the same compiler could be used for both local and cross,
- if the target and the build system are the same).
- It finally uses those tools to create the final xisop.adf floppy image,
- and advertizes the location of this file to the user.
-\layout Standard
-
-Those last steps are very port-specific and are best done by someone with
- a good amount of experience for the particular port to ensure that it works
- right.
- It is important to advertize the location of the final result to the user
- at the very end.
-\layout Section
-\pagebreak_top 
-Hardware specific development notes
-\layout Standard
-
-This chapter describes which hardware specific sections are required to
- support Xisop.
- They in fact provide the low-level glue which all the machine-independent
- common code replies on.
- As such, they should be small, effective, and as efficient and stable as
- possible.
- They should be well tested before releasing an official new Xisop port.
-\layout Standard
-
-To aid in having a well organized source tree, and to prevent code duplication,
- hence enhancing stability with time, the processor-specific and port-specific
- sections have been separated into two.
- Several ports may then take advantage of the same processor-specific code,
- such as atomic locking primitives, which are known to work well, which
- helps alot to speed up development.
-\layout Subsection
-
-Microprocessor specific notes
-\layout Subsubsection
-
-Required backend functions and support
-\layout Standard
-
-Each processor is different but it is great to abstract most CPU-specific
- functions into a standard set.
- The headerfile which will be invoked by the common machine-independent
- parts of the kernel to acquire support for the hardware specific functions
- is 
-\emph on 
-processor/support.h
-\emph default 
-, where 
-\emph on 
-processor
-\emph default 
- will consist of a symbolic link to the actual 
-\emph on 
-processor
-\emph default 
- directory in use in the 
-\emph on 
-processors
-\emph default 
- directory.
- Although the general organization of the processor specific code is implementat
-ion dependent, it is important that 
-\emph on 
-support.h
-\emph default 
- loads support for all necessary functions and data types which are processor-sp
-ecific, and that 
-\emph on 
-ar/*.a
-\emph default 
- be the only necessary modules to link with the rest of the kernel.
-\layout Standard
-
-It is allowed if desired to also supply processor specific functions to
- replace some of the common machine-independent ones, which may be desired
- for speed at occasions.
- When this is done, the functions should behave identically as expected,
- should bear the same names, and no prototypes should be provided for them
- in 
-\emph on 
-support.h
-\emph default 
-.
- The processor-specific code will be linked to the final kernel before the
- common libraries and those functions will replace the machine-independent
- ones then.
- These functions could be for instance: 
-\emph on 
-memcmp()
-\emph default 
-,
-\emph on 
- memcpy()
-\emph default 
-, 
-\emph on 
-memset()
-\emph default 
-, etc.
-\layout Standard
-
-Here are the various recommended functions which each CPU should support,
- and make public to the rest of the kernel, at a minimum:
-\layout Paragraph
-
-Context manipulation
-\layout Standard
-
-The 
-\emph on 
-_ctx_t
-\emph default 
- structure should be defined by the CPU-specific support headerfile and
- should be used as an abstract type representing all required information
- to save or restore a context, thus all registers, status register (SR),
- stack pointer (SP), and program counter (PC).
- The load and save context code sections are generally port-specific are
- called from an interrupt, and as needed some care will be taken to save
- the user stack pointer (USP) rather than the supervisor stack pointer (SSP),
- as their purpose consist of task switching.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_ctx_init(_ctx_t\SpecialChar ~
-*context,\SpecialChar ~
-u_int32_t\SpecialChar ~
-*stack,\SpecialChar ~
-size_t\SpecialChar ~
-stacksize,\SpecialChar ~
-void\SpecialChar ~
-*start)
-\emph default 
- Allows to create a new CPU context.
- On some systems the stack grows downwards while upwards on others.
- For this reason, the 
-\emph on 
-stacksize
-\emph default 
- argument is used which permits to set the stack pointer as required, because
-\emph on 
-stack
-\emph default 
- should be a pointer to the top of the stack.
-\emph on 
-start
-\emph default 
- is a function pointer to the code to execute (stack startup address).
- Usually, SP and PC are set accordingly in 
-\emph on 
-context
-\emph default 
-, SR set to the current one, and other registers zeroed.
- In some cases it may be good to also ensure to turn off the supervisor
- bit from SR in the context, because user tasks are expected to run in userstate
- processor mode.
-\layout Paragraph
-
-Simple lock support
-\layout Standard
-
-
-\emph on 
-_lock_t
-\emph default 
- should also be defined for abstraction, and help to perform various synchroniza
-tion tasks.
- These need not be symetric multiprocessor (SMP) safe, but they should at
- least be atomic for the current processor.
- Atomic in the sense that test-and-set must be performed at once to acquire
- a lock.
- If a processor does not allow to make this atomic, it is possible to provide
- these by the port-specific code, in which case it could disable interrupts
- (at least the scheduler interrupt) before performing it's tasks, so that
- operations seem atomic in a multitasking environment.
- These lock primitives should not be nestled or recursive, they are intended
- for exclusive access.
-\layout Standard
-
-In any case, all following lock primitives should be callable by normal
- user tasks, which means that when required a trap can be used internally
- to swich to supervisor mode if the processor requires to perform privileged
- instructions to achieve the expected atomic behavior, both for 
-\emph on 
-_lock_t
-\emph default 
- and 
-\emph on 
-_rlock_t
-\emph default 
- primitives.
- Fortunately, they can usually be implemented properly using normal instructions.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_init(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Permits to initialize a 
-\emph on 
-_lock_t
-\emph default 
- entity as required for future operations on this 
-\emph on 
-lock
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_acquire(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Allows to obtain exclusive access on the supplied 
-\emph on 
-lock
-\emph default 
-, or wait looping indefinitely until the lock could be obtained, in order
- to obtain it as fast as possible.
- It is important that this operation be atomic so that in the event of scheduled
- context switching race conditions do not occur.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_lock_release(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Should free the specified 
-\emph on 
-lock
-\emph default 
-, which will enable any other requester to acquire the lock to obtain it.
- This operation also should be atomic.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_lock_try(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Attempts to obtain exclusive access to 
-\emph on 
-lock
-\emph default 
-, returning TRUE/1 if it could obtain it immediately, or FALSE/0 if the
- lock is already being held, in which case it also returns immediately.
- It is important that this be implemented atomically, in a single test-and-set
- instruction.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-bool\SpecialChar ~
-_lock_available(_lock_t\SpecialChar ~
-*lock)
-\emph default 
- Verifies if 
-\emph on 
-lock
-\emph default 
- is available.
- This is not to be used to implement 
-\emph on 
-_lock_try()
-\emph default 
-, it is used in situations where we only want to make sure that no lockers
- currently own the lock, but that we still do not want to obtain it ourselves.
- An example of this is where a lock is used as an ON/OFF switch, which can
- be implemented using this mechanism, without disabling the event which
- needs to access a resource, which may serve other functions but will skip
- executing the critical code if the scheduler lock is held.
- This is usually best implemented using recursive 
-\emph on 
-_rlock_t
-\emph default 
- however, which will be described below.
-\layout Standard
-
-The following locking primitives are different in that a lock may be locked
- by any number of lockers, but has to be unlocked the same number of times
- for the lock to become free again.
- These are called recursive locks.
- A useful example consists of the scheduler which wants to ensure that no
- task disabled the scheduler temporarily before performing a context switch.
- It then evaluates the lock using 
-\emph on 
-_rlock_available()
-\emph default 
-, or 
-\emph on 
-_rlock_try()
-\emph default 
- if it needs to prevent recursion, and only performs the switch if it is
- (and hence the lock counter equals to 0, or 1).
- It is recommended that the 
-\emph on 
-_rlock_t
-\emph default 
- type consist of an 
-\emph on 
-int32_t
-\emph default 
- (signed), but the processor-specific code is left to define it differently
- if need be.
-\layout Standard
-
-Although for several architectures C code can also be used to implement
- these, it is a good idea to implement them in assembly because there is
- no guarantee that the compiler will always use atomic increase and decrease
- operations (GCC 2.95.3 at least seems to not always do so for m68k with C
- macros, it often loads the value from the lock counter, increase it during
- other processing and posts back the new value over the counter, instead
- of always generating an atomic increment instruction which m68k is well
- capable of).
- Moreover, for some other architectures the use of an internal 
-\emph on 
-_lock_t
-\emph default 
- or 
-\emph on 
-_splhigh()
-\emph default 
- may be required to implement these properly, and if there are privileged
- instructions required to implement these, a trap may be needed.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_init(_rlock_t\SpecialChar ~
-*rlock)
-\emph default 
- Initializes 
-\emph on 
-rlock
-\emph default 
- to 0.
- This normally is rarely done except at system initialization, or lock creation.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_acquire(_rlock_t\SpecialChar ~
-*rlock)
-\emph default 
- Atomically increases the 
-\emph on 
-rlock
-\emph default 
- counter by one.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_release(_rlock_t\SpecialChar ~
-*rlock)
-\emph default 
- Atomically decreases the 
-\emph on 
-rlock
-\emph default 
- counter by one.
- There is no need to perform any check against 0 in this function.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_try(_rlock_t\SpecialChar ~
-*rlock)
-\emph default 
- Permits to atomically increase the 
-\emph on 
-rlock
-\emph default 
- counter by one, and returns TRUE if the caller consists of the only locker
- (in which case the lock counter should now be 1).
- If the counter is higher, it means that more than one locker exists and
- the function is then expected to decrease the counter atomically again,
- and return FALSE.
- This allows exclusive access to a recursive lock.
- This function is both used by the scheduler and public interrupt facility
- systems.
- Because they want to make sure that noone holds the lock when they execute
- their critical tasks, and that they also need to lock it to prevent potential
- self-recursion, this call is a great facility to use.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_rlock_available(_rlock_t\SpecialChar ~
-*rlock)
-\emph default 
- Returns TRUE if the 
-\emph on 
-rlock
-\emph default 
- counter equals to 0, or FALSE otherwise (in which case there at least remains
- one current locker).
- This function is provided for callers which do not need to prevent possible
- recursion, but only need to make sure that the lock is currently free.
- Following 
-\emph on 
-_rlock_available()
-\emph default 
- with 
-\emph on 
-_rlock_acquire()
-\emph default 
- is not safe, and 
-\emph on 
-_rlock_try()
-\emph default 
- should be used instead when this is desired.
-\layout Paragraph
-
-Byte order conversion support
-\layout Standard
-
-The processor-specific code needs to #define 
-\emph on 
-_ARCH_BIG_ENDIAN
-\emph default 
- or 
-\emph on 
-_ARCH_LITTLE_ENDIAN
-\emph default 
- in their 
-\emph on 
-support.h
-\emph default 
- depending on their native byte order.
- These will be used at a higher level in the libraries for the endian-conversion
- functions between network (big endian) and host order (big or little endian).
- These are most useful when saving a binary file format which needs to be
- loadable by another processor of another endian order as well as in the
- implementation of networking based Remote Procedure Calls, etc.
- Moreover, the two following functions should be provided:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int16_t\SpecialChar ~
-_bswap16(u_int16_t)
-\emph default 
- Swaps the order of the two bytes held in the supplied 16-bit word and returns
- the result.
- For instance, 0x1234 becomes 0x3412.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-u_int32_t\SpecialChar ~
-_bswap32(u_int32_t)
-\emph default 
- Reverses the order of the four bytes held in the supplied 32-bit word and
- returns the result.
- For instance, 0x12345678 becomes 0x78563412.
-\layout Paragraph
-
-String library optimizations support
-\layout Standard
-
-Note that the following are not necessary to consider if a specially optimized
- library functions for string and memory are implemented in assembly for
- the architecture.
-\layout Standard
-
-Every other architecture should 
-\emph on 
-#define
-\emph default 
- the architecture-specific 
-\emph on 
-__ARCH_INT_BITS
-\emph default 
- macro, which should be set to the native word size used by the particular
- processor for int, using the compiler.
- This should be expressed in bits, not in bytes.
- The most common value is 32, but it can vary.
-\layout Standard
-
-It is also important to 
-\emph on 
-#define
-\emph default 
- the 
-\emph on 
-_ARCH_LOWCACHE
-\emph default 
- macro (with no value), if it is beleived that loop unrolling is of no benefit.
- This can be the case on architectures with very low instruction caches,
- or ones which are using none.
- If loop unrolling is wanted, this should not be defined.
-\layout Standard
-
-The 
-\emph on 
-_ARCH_USEINDEXING
-\emph default 
- macro also should be 
-\emph on 
-#defined
-\emph default 
- with no value if it is beleived that the compiler generates better code
- for this particular processor when using indexed instructions rather than
- many post-increment/pre-decrement pointer based instructions.
- For instance, the i386 processor has no such special support, and using
- indexing can generate better code using GCC2.
- For m68k, it is usually better not to use indexing.
- Note that this is only taken in consideration if 
-\emph on 
-_ARCH_LOWCACHE
-\emph default 
- is not defined, as it only affects loop unrolling of the C string and memory
- library.
-\layout Standard
-
-These definitions are expected to be found in the 
-\emph on 
-support.h
-\emph default 
- file for every particular processor.
-\layout Paragraph
-
-CPU-saving
-\layout Standard
-
-On CPUs which support this, it is very useful to not hug the processor constantl
-y in a loop where the only event that is awaited for consists of an interrupt.
- On microprocessors which do not provide such a feature, it is safe to just
- make this function do nothing.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_idle(void)
-\emph default 
- Suspends execution of instructions by the current processor until the next
- interrupt, trap or exception occurs.
-\layout Paragraph
-
-Interrupt level control
-\layout Standard
-
-Most microprocessors support several interrupt levels, where the higher
- the level the better precedence of execution over others.
- Manipulating the interrupt priority level (IPL) using Set Priority Level
- functions becomes useful for critical code sections which need to disable
- all interrupts at the specified level and under.
- Although port-specific code attempts to provide it's own finer grained
- interrupt control code when considered required, these should be available.
- The 
-\emph on 
-_ipl_t
-\emph default 
- type itself is left to be defined with 
-\emph on 
-typedef
-\emph default 
- by the processor-specific code to the best variable type to hold the processor
- IPL state.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_ipl_t\SpecialChar ~
-_spl
-\emph default 
-n
-\emph on 
-(void)
-\emph default 
- Immediately sets the current priority level to the one specified by 
-\emph on 
-n
-\emph default 
-.
- Thus, functions such as 
-\emph on 
-_spl0()
-\emph default 
-, 
-\emph on 
-_spl1()
-\emph default 
-, 
-\emph on 
-_spl2()
-\emph default 
-, etc should be provided, for each interrupt level.
-\emph on 
-_spl0()
-\emph default 
- should enable all interrupt levels to occur.
- The returned value serves to eventually restore the previous interrupt
- level using 
-\emph on 
-_splx()
-\emph default 
-, and is an abstract type defined by the processor-specific code.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_ipl_t\SpecialChar ~
-_splhigh(void)
-\emph default 
- Usually a macro to the highest 
-\emph on 
-_spl
-\emph default 
-n
-\emph on 
-()
-\emph default 
- function, it disables all interrupts by setting the highest priority level,
- thus masking all interrupts.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_splx(_ipl_t\SpecialChar ~
-state)
-\emph default 
- Permits to restore the previous interrupt priority level which was active
- before a call to an 
-\emph on 
-_spl
-\emph default 
-*
-\emph on 
-()
-\emph default 
- function was made, using the state value which was supplied by them.
-\layout Subsubsection
-
-m68k
-\layout Standard
-
-The Motorola MC68000L8 and MC68000L10 processors were the first to run Xisop.
- No support for MMU is present, such memory management units usually come
- on other external circuits for this processor, and there are various types.
- As Xisop does not need MMU, those processors were an ideal target.
- Although internally built as 16-bit processors, these processors behave
- as 32-bit ones from the programming point of view.
- It is also expected to run the same (or with minor modifications to disable
- their MMU) on the other processors of the 680x0 family, which are fully
- 32-bit.
- The assembly code observes the following rules to properly work with GCC
- compiled C modules:
-\layout Itemize
-
-Stack pointer consists of A7/SP and frame pointer of A6/FP.
- In supervisor mode, the user stack pointer consists of USP and specialized
- instructions need to be used to access and manipulate it.
-\layout Itemize
-
-Registers A0 and D0 serve the special purpose of return code for functions.
- Where the C code expects A0 or D0 to be used depends on the function prototype
- as seen from C.
- Functions expected to return a pointer should do so in A0, and D0 is used
- for other integer values.
- Assembly functions expected to be called from C must have a C function
- prototype defined in a headerfile which the C code must include.
-\layout Itemize
-
-Assembly functions save all the registers they modify, and restore them
- before returning.
- As such, functions returning nothing (void) are expected to never return
- with a different register state.
- However, this is not always true of GCC generated code.
- Of course, the D0 register in the case of integer returning functions,
- and A0 for pointer returning ones should as expected modify the corresponding
- register as well.
- Registers to be saved are pushed on the stack, which grows upwards.
-\layout Itemize
-
-Because there are various registers which GCC generated code modifies without
- always saving, exception handlers save all general purpose registers A0-A6
- and D0-D7 registers, and restore them before returning with RTE.
- It was a false assumption to previously only backup A0 and D0 which are
- used as function return codes, and many problems occurred back then with
- this attempt.
-\layout Itemize
-
-When an assembly function calls a C function, it needs to push the arguments
- in the stack, growing upwards, in reverse order, before calling it.
- After the C function returned, the stack pointer should be updated by additioni
-ng the number of bytes that were pushed.
- In the case where 16-bit or 8-bit values are passed as arguments, GCC still
- expects a stack entry of 32-bit size.
-\layout Itemize
-
-An assembly function expected to be called from C must obtain the arguments
- (if any) from the stack.
- These are ordered growing downwards, as they were inserted in reverse order
- in the stack, growing upwards.
- Obviously, when registers are temporarily saved on the stack to preserve
- their state and restore them before returning, the offset at which these
- parameters are found on the stack changes, and the code has to account
- for this.
-\layout Itemize
-
-The 
-\emph on 
-_ctx_t
-\emph default 
- manipulation functions had to be implemented as follows: 
-\emph on 
-_ctx_init()
-\emph default 
- can be called from usermode and only creates a context with zero registers,
- etc.
- However, 
-\emph on 
-_yield()
-\emph default 
- had to be implemented using a trap to execute in supervisor mode, and the
- scheduler preemptive interrupt also executes in supervisor mode.
- Both save the current context to 
-\emph on 
-root->curctx
-\emph default 
-, call 
-\emph on 
-schedule()
-\emph default 
- and load back the context from
-\emph on 
- root->curctx
-\emph default 
-, as expected.
- They need to use privileged instructions to change SR (status register)
- and USP (user stack pointer), because SR/A7 becomes the SSP (supervisor
- stack pointer) when in supervisor mode.
- To make sure to respect the PC (program counter) address of the contexts,
- they are manipulated on the supervisor stack (SSP), where the m68k saves
- them when jumping to the exception handler.
- As such, RTE (return from exception) automatically jumps where it should
- for the current context.
- The offset to the SR 16-bit register is usually %sp@ and the one for PC
- 32-bit one in %sp@(2) when initially intering the trap or interrupt exception.
- This offset has to be recalculated as registers are being saved on the
- stack, of course.
-\layout Standard
-
-Other m68k specific notes about aspects which had to be taken in consideration:
-\layout Itemize
-
-At kernel initialization, room for the supervisor stack pointer needs to
- be setup, and the Supervisor Stack Pointer (SSP/A7) should be set properly.
- To do this it is necessary to go in supervisor mode, and then set the A7
- register to the right address.
- The way this must be done depends on the architecture.
- Because at bootup ROM code may have taken control already and one must
- use it's own facilities to obtain supervisor privileges.
-\layout Itemize
-
-Dropping to user state from supervisor state to call Xisop 
-\emph on 
-main()
-\emph default 
- is rather simple.
- 1024 bytes are taken from the current SSP (A7), and assigned to the USP.
- The supervisor bit in SR is then unset, and a jump to 
-\emph on 
-main()
-\emph default 
- is made.
- The function is very tiny and only ensures to launch the various initial
- tasks, then waits forever in a loop using 
-\emph on 
-_idle()
-\emph default 
- calls via 
-\emph on 
-sys_idle()
-\emph default 
-.
- It corresponds to the 
-\emph on 
-_scontext
-\emph default 
-\emph on 
-_ctx_t
-\emph default 
- in 
-\emph on 
-root->curctx
-\emph default 
- when no tasks are on the ready queue.
- Such a small stack buffer is then safe.
-\layout Itemize
-
-Using GCC 2.95.3, -O2 and -fomit-frame-pointer compilation directives seem
- to generate both well optimized and small m68k code.
- I however noted that using -fno-function-cse was also required with -O2,
- without which the resulting code crashed.
- -m68000 was used to generate true MC68000 code (no support for 020+ specific
- instructions which wouldn't run on a plain 68000).
-\layout Itemize
-
-Although m68k is very good to produce position-independent code, the default
- output GCC produces still comports instructions using direct addressing,
- except when -fpic is used, in which case additional symbols, with a .got
- table need to also be in the code, even if m68k generally doesn't require
- these for position-independent code (it has all the relative addressing
- instructions required for large memory model).
- As the only solution I found to properly relocate the code upon loading
- would be to write an ELF or a.out loader, which isn't done yet, the kernel
- code is loaded at a specific location, defined before compilation.
- A GCC ld BFD backend will need to be written, or an ELF loader, to allow
- to relocate the kernel, as well as file executable binaries.
-\layout Itemize
-
-The 
-\emph on 
-_spl
-\emph default 
-n
-\emph on 
-()
-\emph default 
- and 
-\emph on 
-_splhigh()
-\emph default 
- functions were implemented as macros, calling the assembly 
-\emph on 
-_spl()
-\emph default 
- function which takes a 16-bit argument (the new SR to apply).
-\emph on 
-_splx()
-\emph default 
- assembly functions restores the previous SR.
- As SR is 16-bit, the 
-\emph on 
-_ipl_t
-\emph default 
- type was defined as an 
-\emph on 
-u_int16_t
-\emph default 
- internally.
- This allowed to generate very compact code for the eight interrupt priority
- level control functions which m68k required.
-\layout Itemize
-
-The 
-\emph on 
-_lock_
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions were implemented using the TAS instruction for atomicity, and
- the 
-\emph on 
-_lock_t
-\emph default 
- data type was internally defined as an 
-\emph on 
-u_int8_t
-\emph default 
-.
-\layout Itemize
-
-The 
-\emph on 
-_rlock
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions could be implemented without the use of an internal 
-\emph on 
-_lock_t
-\emph default 
- to guarrantee atomicity, because the m68k processor is capable of addition
- and substraction on a 32-bit value in a single instruction.
- An 
-\emph on 
-_rlock_t
-\emph default 
- consists of a 
-\emph on 
-int32_t
-\emph default 
- for this architecture.
-\layout Itemize
-
-Before the port-specific code calls Xisop 
-\emph on 
-main()
-\emph default 
-, it is necessary to switch back to user processor mode.
- The 
-\emph on 
-_usermode()
-\emph default 
- function was implemented for this and added to the m68k set of processor-specif
-ic functions, which allows to create a 1024 bytes user stack from the current
- supervisor stack, switches to usermode, and jumps to the specified function.
-\layout Subsection
-
-Port specific notes
-\layout Subsubsection
-
-Required backend and support functions
-\layout Standard
-
-Each architecture needs a specific initialization section, such as setting
- up exceptions, interrupts and memory.
- Although this can also be CPU-specific, the various architectures using
- the same processor would most likely still need these to be different.
- They are thus considered as port-specific low-level backend support.
- Similarly to the processor-specific support code, 
-\emph on 
-support.h
-\emph default 
- and 
-\emph on 
-ar/*.a
-\emph default 
- are the main targets that should be provided to allow the rest of the kernel
- to use it, as it will include 
-\emph on 
-port/support.h
-\emph default 
- and will link in 
-\emph on 
-port/ar/
-\emph default 
-*.
-\emph on 
-a
-\emph default 
-, where 
-\emph on 
-port
-\emph default 
- consists of a symbolic link to the actual 
-\emph on 
-ports/<name>
-\emph default 
- directory.
-\layout Standard
-
-It is allowed if desired to also supply port specific functions to replace
- some of the common machine-independent ones, which may be desired for speed
- at occasions.
- When this is done, the functions should behave identically as expected,
- should bear the same names, and no prototypes should be provided for them
- in 
-\emph on 
-support.h
-\emph default 
-.
- The port-specific 
-\emph on 
-ar/*.a 
-\emph default 
-modules will be linked before the processor-specific and Xisop common libraries
- and those functions will replace them if they are supplied.
- These functions could be for instance: 
-\emph on 
-memcmp()
-\emph default 
-,
-\emph on 
- memcpy()
-\emph default 
-, 
-\emph on 
-memset()
-\emph default 
-, etc.
-\layout Standard
-
-After the kernel was built, using both common, processor and port code,
- control is left again to the port specific code which should handle boot
- support; This can be creating a floppy image, etc.
- See the section on the building process for more information.
-\layout Standard
-
-It is important that the port-specific code provides the 
-\emph on 
-_start
-\emph default 
- entry point.
- This code should then set the processor in supervisor mode where required,
- setup the supervisor mode stack pointer, disable interrupts and perform
- initialization of the various systems described below.
- Afterwards, it should switch back to userstate processor mode, and leave
- control to the Xisop 
-\emph on 
-main()
-\emph default 
- function, which will not return.
- That 
-\emph on 
-_start
-\emph default 
- entry point is where the boot kernel loader needs to jump to.
-\layout Paragraph
-
-Memory initialization and requirements
-\layout Standard
-
-The port-specific 
-\emph on 
-support.h
-\emph default 
- should define C enumerators (enum) and definitions (#define) for the machine-in
-dependent Xisop memory code.
- It is recommended to also read the section on Xisop memory management for
- more information.
- The port-specific requirements are explained as follows:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-#define\SpecialChar ~
-_PAGE_SIZE\SpecialChar ~
-<value>
-\emph default 
- The memory management system needs to know the amount of bytes in which
- to split pages.
- On operating systems which support Memory Management Units (MMU), this
- is required to match the page size which the hardware requires.
- In the case of Xisop, it is safe to use any reasonable multiple of 16 bytes
- here.
- A common 
-\emph on 
-_PAGE_SIZE
-\emph default 
- is 4096 bytes.
- On systems with very low memory it may be useful to use 1024, or even 256.
- This value is used by the page memory allocation primitives.
-\layout Standard
-
-The 
-\emph on 
-mpool_t
-\emph default 
-, a multi-purpose memory pool which allows management primitives such as
-\emph on 
-_malloc()
-\emph default 
- and 
-\emph on 
-_free()
-\emph default 
-, requires specific definitions:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-#define\SpecialChar ~
-_MPOOLS\SpecialChar ~
-<value>
-\emph default 
- This is the number of internal 
-\emph on 
-pool_t
-\emph default 
- which are necessary to initialize for an 
-\emph on 
-mpool_t
-\emph default 
-, to be able to use these efficient pools when dealing with byte requirements
- which are too small to be rounded at page boundaries.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-#define\SpecialChar ~
-_MPOOLSTART\SpecialChar ~
-<value>
-\emph default 
- The smallest amount of bytes which an 
-\emph on 
-mpool_t
-\emph default 
- can allocate, which is multiplied by two for each consecutive 
-\emph on 
-pool_t
-\emph default 
- initialized for the 
-\emph on 
-mpool_t
-\emph default 
- at 
-\emph on 
-mpool_init()
-\emph default 
-.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-#define\SpecialChar ~
-_MPOOLSTEP\SpecialChar ~
-<value>
-\emph default 
- The number of physical 
-\emph on 
-_PAGE_SIZE
-\emph default 
- bytes pages into a 
-\emph on 
-page_t
-\emph default 
- for every 
-\emph on 
-pool_t
-\emph default 
- of an 
-\emph on 
-mpool_t
-\emph default 
-.
-\layout Standard
-
-To explain better the previous definitions, what the 
-\emph on 
-mpool_init()
-\emph default 
- function actually does is iterate 
-\emph on 
-_MPOOLS
-\emph default 
- times to initialize the 
-\emph on 
-pool_t
-\emph default 
- objects, setting the first 
-\emph on 
-pool_t
-\emph default 
- to allocate units of 
-\emph on 
-_MPOOLSTART
-\emph default 
- bytes, the second 
-\emph on 
-_MPOOLSTART
-\emph default 
- * 2, and continueing to iterate multiplying the unit size by two until
-\emph on 
-_MPOOLS
-\emph default 
- number of 
-\emph on 
-pool_t
-\emph default 
- were initialized.
- Larger unit sizes which cannot be handled by the 
-\emph on 
-pool_t
-\emph default 
- will be rounded at page boundaries.
-\emph on 
-_MPOOLSTEP
-\emph default 
- simply consists of the 
-\emph on 
-stepp
-\emph default 
- argument to 
-\emph on 
-pool_init()
-\emph default 
-.
- As such, all the definitions above intimately correlate to eachother, and
- are quite versatile to match various requirements an architecture may need.
-\layout Standard
-
-For a system with a 
-\emph on 
-_PAGE_SIZE
-\emph default 
- of 4096 bytes, an 
-\emph on 
-_MPOOLSTART
-\emph default 
- of 16 and 
-\emph on 
-_MPOOLSTEP
-\emph default 
- of 1, 7 consists of an ideal value for 
-\emph on 
-_MPOOLS
-\emph default 
-.
- On a system with a fair amount of memory, if it is wanted to minimize calls
- to the page management primitives even more, it is possible to set a larger
-\emph on 
-_MPOOLSTEP
-\emph default 
- and raise 
-\emph on 
-_MPOOLS
-\emph default 
- accordingly, while keeping the same underlaying 
-\emph on 
-_PAGE_SIZE
-\emph default 
-.
- Basically 
-\emph on 
-_MPOOLS
-\emph default 
- should be set just below the 
-\emph on 
-pool_init()
-\emph default 
- breaking point, where it returns FALSE because 
-\emph on 
-sizeof(mnode_t)
-\emph default 
- plus the current 
-\emph on 
-_MPOOLSTART
-\emph default 
- multiple consist of too large objects to fit into a 
-\emph on 
-pool_t
-\emph default 
- page (which in turn depends on 
-\emph on 
-_MPOOLSTEP
-\emph default 
- which changes the 
-\emph on 
-page_t
-\emph default 
- size for a 
-\emph on 
-pool_t
-\emph default 
-).
-\layout Standard
-
-It is recommended to read the source for 
-\emph on 
-mpool_init()
-\emph default 
- which is located in 
-\emph on 
-src/common/kernel/memory.c
-\emph default 
- for a better understanding, as well as the documentation on Xisop memory
- management primitives.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-enum\SpecialChar ~
-_memtypes
-\emph default 
- This enumeration should define the various memory types the architecture
- provides, in preference order when 
-\emph on 
-_MEM_ANY
-\emph default 
- is used (-1) when calling the allocation primitives.
- The enumeration should set 
-\emph on 
-_MEM_
-\emph default 
-* names, the first one corresponding to 0, and the last element should consist
- of 
-\emph on 
-_MEM_MAX
-\emph default 
-, corresponding to the number of memory types the system provides.
- Not all architectures provide more than a single memory type, under which
- case 
-\emph on 
-_MEM_ALL
-\emph default 
- will correspond to 0 and 
-\emph on 
-_MEM_MAX
-\emph default 
- to 1, respectively.
-\layout Standard
-
-Other than defining these requirements in it's 
-\emph on 
-support.h
-\emph default 
- headerfile, the port-specific initialization code is responsible for attaching
- the available physical memory pages to the system pools, before initializing
- the public interrupt facilities.
- This is done by first calling the 
-\emph on 
-memory_init()
-\emph default 
- machine-independent function.
- Then, the
-\emph on 
- mchunk_init()
-\emph default 
- and 
-\emph on 
-mchunk_attach()
-\emph default 
- functions which are documented in the Xisop memory management section are
- normally called once for each contiguous memory area which is to be used
- as general purpose memory.
- The video memory, or other special memory sections should not be included
- in the system memory pools.
- It is important to perform this step before continuing on with the next
- initialization sections.
- The 
-\emph on 
-mchunk_init()
-\emph default 
- and 
-\emph on 
-mchunk_attach()
-\emph default 
- functions are described in detail in the Xisop memory management section.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-memory_init(void
-\emph default 
-) This function is only called once by the port-specific initialization
- code before starting to attach memory chunks to the system pools.
- After this function executes, it becomes possible to use the 
-\emph on 
-mchunk_init()
-\emph default 
- and 
-\emph on 
-mchunk_attach()
-\emph default 
- functions to attach contiguous memory regions to the system page pools.
-\layout Paragraph
-
-Exceptions initialization and public interrupt facilities
-\layout Standard
-
-It is recommended to maintain an 
-\emph on 
-_interrupt_depth
-\emph default 
- variable or recursive lock, which each trap or interrupt handler should
- increase at startup and decrease before returning, which can be used for
- the scheduler interrupt to determine if it should call 
-\emph on 
-schedule()
-\emph default 
- or not.
- As the scheduler timer interrupt would also raise it at startup, it can
- then mask interrupts and evaluate if it equals 1 afterwards, in which case
- it is sure to have the right to perform a context switch.
- This permits to make system calls uninterruptible for the time of their
- execution and to protect the scheduler from performing context switches
- while an interrupt handler is executing, which at occasions could result
- in recursivity and context corruption.
- As an effort is made to minimize the number of system call traps required
- during normal Xisop function, the preemptive nature of the scheduler is
- not bothered by having uninterruptible system calls, unless a task voluntarily
- abuses 
-\emph on 
-sys_custom()
-\emph default 
-, which is by all meals legal if one wants to.
-\layout Standard
-
-Obviously, most exception handlers are responsible to return with the registers
- unchanged, and as such should normally save all general-purpose registers
- on the stack at startup, and return them before returning.
- This is especially true if C functions are to be called from the interrupt
- handler, where unexpected registers may be tempered with.
-\layout Standard
-
-After setting up the memory, the public interrupt facilities can be defined
- to the system and their internal handler vectors setup.
- Usually, 
-\emph on 
-facilities_init()
-\emph default 
- will be called before vectors are initialized, or if not possible, dummy
- do-nothing vectors can be installed, and can then be setup definitely after
- calling f
-\emph on 
-acilities_init()
-\emph default 
-, when it becomes safe.
-\layout Standard
-
-This function call depends on the 
-\emph on 
-enum _facilities
-\emph default 
- C enumerator which should be defined in the port specific 
-\emph on 
-support.h
-\emph default 
- headerfile.
- This enumerator defines each facility in the form of 
-\emph on 
-_FACILITY_
-\emph default 
-*, where * consists of the name of the facility.
- The first entry should evaluate to 0, and the last one to the total number
- of facilities (
-\emph on 
-_FACILITY_MAX
-\emph default 
-).
- The various interrupt handlers need to internally call 
-\emph on 
-facility_exechooks()
-\emph default 
- on the facility they are serving for the public facilities to become alive.
- At it's discretion, the handler may temporarily disable the interrupt source
- when calling the function, but 
-\emph on 
-facility_exechooks()
-\emph default 
- internally performs recursion prevention and makes sure to not execute
- the hooks if a hook is currently being inserted or removed, using an 
-\emph on 
-_rlock_t
-\emph default 
- for each facility internally.
-\layout Standard
-
-There only is at least one facility which is required for all ports to provide.
- This facility should be named 
-\emph on 
-_FACILITY_SCHEDTIMER
-\emph default 
-, and should call the hooks at 
-\emph on 
-_SCHEDTIMER_HZ
-\emph default 
- frequency, which should also be defined by the port-specific 
-\emph on 
-support.h
-\emph default 
-.
- This way, simple time-based Xisop applications can work portably on all
- ports.
- This facility should correspond to the timer interrupt which the port chose
- to use for the preemptive scheduler timer.
- This facility does not interfere with the scheduler activities; it is called
- when the interrupt occurs even if the scheduler 
-\emph on 
-rlock_t
-\emph default 
- is set (
-\emph on 
-schedule()
-\emph default 
- handles the scheduler locked/disabled case already).
- Generally, the scheduler interrupt handler works as follows:
-\layout Itemize
-
-Increase the global 
-\emph on 
-_interrupt_depth
-\emph default 
- variable like for all handlers
-\layout Itemize
-
-Temporarily disable the interrupt source (by raising the IPL using 
-\emph on 
-_spl
-\emph default 
-*
-\emph on 
-()
-\emph default 
- or otherwise) to prevent any possible recursion or other interruption.
-\layout Itemize
-
-Save the current user CPU context to the 
-\emph on 
-root->curctx _ctx_t
-\layout Itemize
-
-Execute the facility hooks using 
-\emph on 
-facility_exechooks(_FACILITY_SCHEDTIMER)
-\layout Itemize
-
-Verify if the 
-\emph on 
-_interrupt_depth
-\emph default 
- variable equals to 1.
- If so, call 
-\emph on 
-schedule(NULL)
-\emph default 
-, which may or may not change the 
-\emph on 
-root->curctx
-\emph default 
- backed up context pointer and 
-\emph on 
-root->curtask
-\layout Itemize
-
-Load back the CPU context from the new 
-\emph on 
-root->curctx
-\emph default 
- (which possibly can be the same, but this must not be assumed)
-\layout Itemize
-
-Re-enable the scheduler interrupt source
-\layout Itemize
-
-Decrease the global 
-\emph on 
-_interrupt_depth
-\emph default 
- variable like for other handlers
-\layout Itemize
-
-Return from interrupt handler while ensuring to jump to the PC of the new
- context.
- Generally, the address to return to is backed up into the supervisor stack,
- which needs to be modified for this.
- That address within the supervisor stack pointer is where context save
- and load operations obtain and set the Program Counter address.
-\layout Standard
-
-Because of the context load/save operations, and return address hack, the
- scheduler interrupt handler is usually implemented entirely in assembly
- (although it calls the 
-\emph on 
-schedule()
-\emph default 
- and 
-\emph on 
-facility_exechooks()
-\emph default 
- C functions).
-\layout Standard
-
-The other facilities, which are optional and can be provided by the port-specifi
-c code will often be implemented as a mix of assembly and C code and will
- similarily at least:
-\layout Itemize
-
-increase global 
-\emph on 
-_interrupt_depth
-\emph default 
- and optionally disable interrupt source
-\layout Itemize
-
-save registers
-\layout Itemize
-
-perform any additional wanted operation
-\layout Itemize
-
-call 
-\emph on 
-facility_exechooks()
-\emph default 
- on their facility
-\layout Itemize
-
-restore registers
-\layout Itemize
-
-re-enable the interrupt source if it was temporarily disabled, and decrease
- global 
-\emph on 
-_interrupt_depth
-\layout Itemize
-
-return
-\layout Standard
-
-The facility public interface and 
-\emph on 
-facility_exechooks()
-\emph default 
- are described in more details in the Xisop public facilities section.
-\layout Paragraph
-
-System trap triggers and handlers initialization
-\layout Standard
-
-It is important for the port-specific code to define the 
-\emph on 
-_syscall()
-\emph default 
- and 
-\emph on 
-_yield()
-\emph default 
- functions.
- The role of the system call trap handler is to serve system call functions
- uninterruptibly, internally calling 
-\emph on 
-_scatch()
-\emph default 
- Xisop common function with the requested arguments.
- Here is described the trigger, which function should be supplied by the
- port-dependent code:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_syscall(u_int32_t\SpecialChar ~
-function,\SpecialChar ~
-void\SpecialChar ~
-*res,\SpecialChar ~
-void\SpecialChar ~
-*args)
-\emph default 
- Internally places the supplied parameters into a static buffer or in registers,
- and generate a processor trap interrupt.
- It is safe to save the registers we modify on the stack, and restore them
- from the stack after the trap returns, and then return ourselves, because
- nor 
-\emph on 
-_yield()
-\emph default 
- nor context switching are implemented via syscalls.
- Although the understanding of the arguments is not necessary at this point,
-\emph on 
-function
-\emph default 
- specifies the syscall number which is to be performed, 
-\emph on 
-res
-\emph default 
- a pointer to eventual results expected from that system call (or NULL),
- and 
-\emph on 
-args
-\emph default 
- optional arguments which need to be passed to the system call (or NULL).
- Although this function is also highly processor-specific, the choice of
- the trap vector to implement system calls is left to the port writer, and
- as such this function as well.
-\layout Standard
-
-The other end, consisting of the system call trap handler, is responsible
- for the following:
-\layout Itemize
-
-Increment 
-\emph on 
-_interrupt_depth
-\emph default 
- global variable
-\layout Itemize
-
-Save all general purpose registers
-\layout Itemize
-
-Read arguments supplied by 
-\emph on 
-_syscall()
-\emph default 
- from the static buffer or registers, and insert them on the stack as C
- arguments, then call 
-\emph on 
-_scatch()
-\emph default 
- C function.
- Fix the stack pointer to forget the pushed stack arguments.
-\layout Itemize
-
-Restore general purpose registers we saved
-\layout Itemize
-
-Decrement 
-\emph on 
-_interrupt_depth
-\emph default 
- global variable
-\layout Itemize
-
-Return
-\layout Standard
-
-The 
-\emph on 
-_scatch()
-\emph default 
- function (which is defined in 
-\emph on 
-src/common/kernel/syscall.c
-\emph default 
-) is responsible for performing the necessary sanity checking on the arguments,
- and does not need to be provided by the machine-specific code:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_scatch(u_int32_t\SpecialChar ~
-function,\SpecialChar ~
-void\SpecialChar ~
-*results,\SpecialChar ~
-void\SpecialChar ~
-*arguments)
-\emph default 
- Consists of the heart of the syscall trap.
-\emph on 
-function
-\emph default 
- specifies the requested syscall function number which was called.
- These are standard and are described in the 
-\begin_inset Quotes eld
-\end_inset 
-
-System Calls
-\begin_inset Quotes erd
-\end_inset 
-
- section.
-\emph on 
-results
-\emph default 
- consists of a pointer to the block of memory which will be modified to
- store the syscall results by this 
-\emph on 
-function
-\emph default 
-.
- It can be NULL.
-\emph on 
-arguments
-\emph default 
- similarly specifies the location of the arguments expected for this 
-\emph on 
-function
-\emph default 
-, or NULL.
- This function refuses to perform any call if the supplied 
-\emph on 
-function
-\emph default 
- is invalid (out of bounds).
-\layout Standard
-
-After setting up the 
-\emph on 
-_syscall()
-\emph default 
- trap vector, the interrupts can remain disabled/masked still, like since
- the beginning.
- More information on the generic user system calls interface is provided
- in the Xisop system calls section.
-\layout Standard
-
-Another requirement that the port-specific code must satisfy consists of
- the 
-\emph on 
-_yield()
-\emph default 
- internal function:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-_yield(task_t\SpecialChar ~
-*task)
-\emph default 
- permits the current task to immediately perform a context switch to another
- task, in fact preempting itself.
-\emph on 
-task
-\emph default 
- is an optional preference of which task to switch to, or NULL, which parameter
- should be passed when the trap handler internally calls 
-\emph on 
-schedule()
-\emph default 
-.
- This is usually implemented in the form of a trap like for 
-\emph on 
-_syscall()
-\emph default 
-, which sets the supplied argument in a static buffer to prevent modifying
- a register (it is unsafe to save registers on the stack as we most likely
- won't be the next task to return from the trap).
- The backend trap handler acts as follows:
-\layout Itemize
-
-Increase the global 
-\emph on 
-_interrupt_depth
-\emph default 
- variable like for all handlers
-\layout Itemize
-
-Temporarily disable all interrupt sources (by raising the IPL using 
-\emph on 
-_splhigh()
-\emph default 
- or equivalent to prevent any possible interruption, but without modifying
- registers, which can be saved and restored safely before performing the
- next steps
-\layout Itemize
-
-Save the current user CPU context to the 
-\emph on 
-root->curctx _ctx_t
-\layout Itemize
-
-Insert the supplied argument from the static buffer in the stack as a C
- argument
-\layout Itemize
-
-Call 
-\emph on 
-schedule()
-\emph default 
-, which may or may not change the 
-\emph on 
-root->curctx
-\emph default 
- backed up context pointer and 
-\emph on 
-root->curtask
-\layout Itemize
-
-Adjust stack pointer to forget the passed argument
-\layout Itemize
-
-Load back the CPU context from the new 
-\emph on 
-root->curctx
-\emph default 
- (which possibly can be the same, but this must not be assumed)
-\layout Itemize
-
-Re-enable interrupts calling 
-\emph on 
-_spl0()
-\emph default 
- or performing equivalent taking care not to modify registers.
- Using the stack is now safe.
- (remember that the old level obtained from 
-\emph on 
-_splhigh()
-\emph default 
- cannot be obtained back unless saved to a static buffer, in which case
- it can be restored properly.
- Saving it on the stack is also safe if the context switching function only
- modified the user stack pointer and the supervisor stack pointer consists
- of the active stack during the trap).
-\layout Itemize
-
-Decrease the global 
-\emph on 
-_interrupt_depth
-\emph default 
- variable like for other handlers
-\layout Itemize
-
-Return from interrupt handler while ensuring to jump to the PC of the new
- context.
- Generally, the address to return to is backed up into the supervisor stack,
- which needs to be modified for this.
- That address within the supervisor stack pointer is where context save
- and load operations obtain and set the Program Counter address.
-\layout Paragraph
-
-Suggestions
-\layout Standard
-
-The rest of the port-specific code internals which it needs to perform are
- left to the implementor, as long as they suit well the purpose.
- However, a few suggestions are made which can help to keep some consistency
- among the various ports, in their choice of function names for instance.
- This example attempts to restrict the assembly code to the minimum, while
- calling C functions as much as possible to handle most exception code.
-\layout Standard
-
-It is generally a good idea for hardware interrupts to provide one separate
- assembly handler per interrupt level, to prevent the C code from having
- to perform unnecessary additional conditional instructions to evaluate
- the level, as it already usually needs to detect the source.
- For other general-purpose trap vectors, it is allowed to provide support
- to execute a single C function for all of them, passing in an argument
- the required information on the trap vector number.
- This however would be less desireable than having a different facility
- for each, if their frequency was high and a large number of hooks were
- attached, because they then would obviously all run often, evaluating one
- by one if they are interested in the trap.
- Suggestion names for various common facility types are shown in the Xisop
- public interrupt facilities section.
-\layout Standard
-
-It is to be noted that the timer interrupt chosen to be used as the preemptive
- scheduler one is special as it needs to perform context switching, often
- also implying stack pointer access and modifications.
- This handler is therefore usually fully written in assembly, as previously
- demonstrated.
- As a general rule, the role of the exception vectors is to call a C function
- which can then handle the event.
-\layout Standard
-
-Here are various C functions which can be called by the machine language
- backend to exceptions, traps and interrupts:
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_icatch
-\emph default 
-n
-\emph on 
-(void)
-\emph default 
- For every hardware interrupt level, une such C function can be called.
- For interrupt level 3, 
-\emph on 
-icatch3()
-\emph default 
- would be called, for instance.
- It is possible to pass parameters if required to detect the interrupt source
- in the C functions.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_tcatch(int\SpecialChar ~
-vector)
-\emph default 
- This C function can be called for all software traps which occur that do
- not correspond to the syscall or yield trap vectors.
-\emph on 
-vector
-\emph default 
- argument specifies the number of the trap vector.
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_ecatch(int\SpecialChar ~
-vector)
-\emph default 
- A C function called when an hardware exception is generated, such as bus
- error, division by zero, etc.
- It is recommended that the code processing these do not hang or crash the
- system permanently if high-reliability is required.
-\emph on 
-vector
-\emph default 
- consists of the exception vector, or reason which caused it, and 
-\emph on 
-stack
-\emph default 
- points as usual to the retrurn from exception address on the stack.
- Although this is CPU-specific, port-specific exception handling code may
- be provided.
-\layout Paragraph
-
-Port-specific system shared libraries to attach and system tasks to launch
-\layout Standard
-
-Although Xisop has a few common portable system libraries and tasks which
- it initializes at startup, it is ideal for the port-specific section to
- be able to describe which other tasks should be launched, and their parameters
- such as priority level, stack size, etc.
- To do this the port-specific code needs to provide the 
-\emph on 
-_port_init()
-\emph default 
- function which the Xisop init task will invoke and which then can use the
- required flexibility.
- It should be noted that as the init task only has a 4096 bytes stack, this
- function is expected to at least create a task with a larger stack if it
- needs to before performing it's own initialization if it overuses the stack.
- The kernel expects the current state to remain the same when the function
- returns (apart of course from the new libraries and tasks which may now
- exist and be resident).
-\layout List
-\labelwidthstring 00.00.0000
-
-
-\emph on 
-void\SpecialChar ~
-_port_init(void)
-\emph default 
- Port-specific function who's purpose is to attach the wanted port-specific
- libraries, and to launch the wanted port-specific tasks.
- This function is called by the Xisop 
-\emph on 
-init
-\emph default 
- task which runs with a stack of 4096 bytes, and runs in userstate mode
- like normal tasks.
-\layout Paragraph
-
-Last steps of the port-specific initialization code
-\layout Standard
-
-After switching to supervisor mode, setting up memory, system call and yield
- traps, as well as scheduler timer interrupt, and initializing the public
- interrupt facilities, port-specific initialization code is then complete,
- and it now should execute the following steps:
-\layout Itemize
-
-Call the machine-independent 
-\emph on 
-xisop_init()
-\emph default 
- function, which sets up various internal structures and disables the scheduler,
- and then internally calls
-\emph on 
- _spl0()
-\emph default 
- as interrupts finally become safe to enable.
-\layout Itemize
-
-Call the famous Xisop machine-independent 
-\emph on 
-main()
-\emph default 
- function which is expected to never return.
- If the processor currently runs into supervisor mode, it is necessary to
- drop to usermode before calling 
-\emph on 
-main()
-\emph default 
-.
- The role of this function is to enable the scheduler, launch the Xisop
-\emph on 
-init
-\emph default 
- task, which in turn will make sure to launch the 
-\emph on 
-task reaper
-\emph default 
- task, and call the port-dependent 
-\emph on 
-_port_init()
-\emph default 
- function which then can also attach and launch the wanted resources.
-\newline 
-Note that the 
-\emph on 
-main()
-\emph default 
- function with it's current stack becomes the initial context that the scheduler
- always switches to when there remains no tasks in the ready queue to run.
- As such, after launching the init task, it loops forever calling 
-\emph on 
-sys_idle()
-\emph default 
- system call which internall calls processor-specific 
-\emph on 
-_idle()
-\emph default 
-, which permits the processor to stop spinning until the next interrupt
- or trap event occurs.
-\layout Subsubsection
-
-Amiga
-\layout Itemize
-
-The Amiga port uses the 
-\emph on 
-processors/m68k
-\emph default 
- processor-specific code.
-\layout Itemize
-
-In addition to the m68k 
-\emph on 
-_spl
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions, the amiga low level library also supplies 
-\emph on 
-aspl
-\emph default 
-*
-\emph on 
-()
-\emph default 
- functions using INTENA control register for finer grained control to disable
- certain interrupts for a period of time.
- For instance, 
-\emph on 
-asplvblank()
-\emph default 
- disables the vertical blank interrupt, 
-\emph on 
-asplsched()
-\emph default 
- disables the scheduler, etc.
-\emph on 
-asplx()
-\emph default 
- is used to restore the previous state, as usual.
- For 
-\emph on 
-asplsched()
-\emph default 
-, a 
-\emph on 
-_lock_t
-\emph default 
- is used to turn the scheduler ON/OFF, so that the timer interrupt it ties
- to still can execute other code if required.
-\emph on 
-XXX
-\layout Itemize
-
-The chosen 
-\emph on 
-_syscall()
-\emph default 
- trap vector was 0.
-\layout Itemize
-
-The chosen 
-\emph on 
-_yield()
-\emph default 
- trap vector was 1.
-\layout Itemize
-
-The Amiga has four multi-purpose timers in it's two CIA chips.
- The use Xisop currently makes of them is as follows: CIA-A TimerA is reserved
- for keyboard timing, which is a hardware requirement.
- CIA-B Timer A is used by the Xisop scheduler, which generates high-level
- hardware interrupts of high priority (IPL 6).
- The B timers and TOD counters are unused and remain available for devices
- and user code for each CIA.
-\layout Itemize
-
-The two memory page pools (
-\emph on 
-ppool_t
-\emph default 
-) initialized at startup by 
-\emph on 
-_init_memory()
-\emph default 
- consist of one for CHIP RAM, and another one for FAST RAM.
- The 
-\emph on 
-enum _memtypes
-\emph default 
- as such set 
-\emph on 
-_MEM_FAST
-\emph default 
- to 0 and 
-\emph on 
-_MEM_CHIP
-\emph default 
- to 1, FAST memory being the prefered if 
-\emph on 
-_MEM_ANY
-\emph default 
- is used.
- Currently, the addresses mapped in the standard distribution are 0x - 0x
- for CHIP (enhanced 2 megabytes agnus chip (fatter)), and 0x00200000-0x00600000
- for FAST (usual 4 first megabytes of ZorroII memory found on A2000).
- This currently needs to be modified in the code itself as the booting process
- currently does not detect the available RAM amounts.
- The provided UAE Amiga Emulator configuration file which is configured
- as such can be located in the 
-\emph on 
-src/ports/amiga/boot
-\emph default 
- directory.
-\emph on 
-XXX
-\layout Itemize
-
-To setup the initial supervisor stack, the AmigaOS SuperState() exec.library
- call must be used to gain supervisor privileges.
- The SSP/A7 register can then be set to the proper location.
- To do this a special function is provided in assembly by the Amiga support
- library, 
-\emph on 
-void\SpecialChar ~
-_supervisor(u_int32_t\SpecialChar ~
-*sp,\SpecialChar ~
-size_t\SpecialChar ~
-ssize\SpecialChar ~
-void (*func)(void))
-\emph default 
- which allows to set the new entry point function and stack.
- To the provided 
-\emph on 
-stack
-\emph default 
- pointer will be additionned the supplied stack size 
-\emph on 
-ssize
-\emph default 
- automatically because of the stack which grows upwards.
- The supplied function 
-\emph on 
-func
-\emph default 
- is then given control to.
- This function is expected to never return.
-\the_end
diff --git a/Xisop/src/clean.sh b/Xisop/src/clean.sh
deleted file mode 100755 (executable)
index 2576fa9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ./generic_makedefs.sh
-
-show cd processors/m68k
-./clean.sh
-show cd ../../ports/amiga
-./clean.sh
-show cd boot
-./clean.sh
-show cd ../../../common
-./clean.sh
-show cd ..
-show $L_RM processor port makedefs.sh
diff --git a/Xisop/src/common/clean.sh b/Xisop/src/common/clean.sh
deleted file mode 100755 (executable)
index 76a9ead..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../generic_makedefs.sh
-
-show cd kernlib
-./clean.sh
-show cd ../kernel
-./clean.sh
-show cd ..
diff --git a/Xisop/src/common/kernel/clean.sh b/Xisop/src/common/kernel/clean.sh
deleted file mode 100755 (executable)
index d386a45..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../generic_makedefs.sh
-
-cleanlib .
-show $L_RM ar/*.a
diff --git a/Xisop/src/common/kernel/debug.c b/Xisop/src/common/kernel/debug.c
deleted file mode 100644 (file)
index 976e387..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/* $Id: debug.c,v 1.3 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/debug.h>
-#include <common/kernel/main.h>
-#include <common/kernlib/fifo.h>
-#include <common/kernlib/string.h>
-#include <config.h>
-
-
-
-#ifdef DEBUG
-
-
-
-static fifo8_t fifo;
-static u_int8_t *fifobuf;
-
-
-
-static size_t btoa(char *, u_int32_t);
-static size_t dtoa(char *, int32_t);
-static size_t utoa(char *, u_int32_t);
-static size_t xtoa(char *, u_int32_t);
-static void fifowrite(const char *, size_t);
-
-
-
-static const char ddigits[] = "0123456789";
-static const char xdigits[] = "0123456789ABCDEF";
-
-
-
-void debug_init(void)
-{
-    fifobuf = MALLOC(DEBUG);
-    FIFO_INIT(&fifo, fifobuf, DEBUG);
-    root->debugfifo = &fifo;
-    _lock_init(&root->debuglock);
-    /* Not ideal but considerably reduces kernel size compared to a static
-     * array buffer. Has the disadventage that debugging is only available
-     * after memory initialization.
-     */
-    debug_printf("Xisop debugging enabled\n");
-}
-
-
-void debug_printf(const char *fmt, ...)
-{
-    debug_va_list ap;
-    register char c;
-    register const char *ptr = fmt, *optr;
-
-    if (ptr == NULL)
-       return;
-
-    lock_acquire(&root->debuglock);
-
-    debug_va_start(ap, fmt);
-    optr = ptr;
-    while ((c = *ptr++) != '\0') {
-       if (c == '%') {
-           ptr--;
-           /* Output pending chars */
-           if (optr < ptr)
-               fifowrite(optr, ptr - optr);
-           ptr++;
-           /* "%\0" ! */
-           if ((c = *ptr++) == '\0') {
-               ptr--;
-               break;
-           }
-
-           /* Process debug_va_arg */
-           switch (c) {
-           case '%':
-               ptr--;
-               break;
-           case 'B':   /* Boolean */
-               {
-                   register bool t = debug_va_arg(ap, bool);
-
-                   if (t)
-                       fifowrite("TRUE", 4);
-                   else
-                       fifowrite("FALSE", 5);
-               }
-               break;
-           case 'b':   /* Binary 32-bit */
-               {
-                   char buf[34];
-
-                   btoa(buf, debug_va_arg(ap, u_int32_t));
-                   fifowrite(buf, 33);
-               }
-               break;
-           case 'c':   /* Character */
-               {
-                   char ch = debug_va_arg(ap, char);
-
-                   fifowrite(&ch, 1);
-               }
-               break;
-           case 'd':   /* 32-bit decimal */
-               {
-                   char buf[12];
-                   size_t len;
-
-                   len = dtoa(buf, debug_va_arg(ap, int32_t));
-                   fifowrite(buf, len);
-               }
-               break;
-           case 'p':   /* 32-bit pointer */
-               {
-                   char buf[11];
-                   register void *p = debug_va_arg(ap, void *);
-
-                   if (p != NULL) {
-                       xtoa(buf, (u_int32_t)p);
-                       fifowrite(buf, 10);
-                   } else
-                       fifowrite("NULL", 4);
-               }
-               break;
-           case 's':   /* String */
-               {
-                   register const char *s = debug_va_arg(ap, char *);
-
-                   if (s != NULL)
-                       fifowrite(s, strlen(s));
-                   else
-                       fifowrite("<NULL>", 6);
-               }
-               break;
-           case 'T':   /* Current task and PC address, no va_arg() */
-               {
-                   register task_t *t = CURTASK();
-                   register void *pc = root->curctx->pc;
-                   char str[24];
-                   register char *ptr = str;
-
-                   *ptr++ = '[';
-                   xtoa(ptr, (u_int32_t)t);
-                   ptr += 10;
-                   *ptr++ = '.';
-                   xtoa(ptr, (u_int32_t)pc);
-                   ptr += 10;
-                   *ptr++ = ']';
-                   *ptr = '\0';
-                   fifowrite(str, 23);
-               }
-           case 'u':   /* 32-bit unsigned decimal */
-               {
-                   char buf[11];
-                   size_t len;
-
-                   len = utoa(buf, debug_va_arg(ap, u_int32_t));
-                   fifowrite(buf, len);
-               }
-               break;
-           case 'x':   /* 32-bit hexadecimal */
-               {
-                   char buf[11];
-
-                   xtoa(buf, debug_va_arg(ap, u_int32_t));
-                   fifowrite(buf, 10);
-               }
-               break;
-           default:    /* Display %<c>, it's a bug, and we debug! */
-               {
-                   char s[2];
-
-                   s[0] = '%';
-                   s[1] = c;
-                   fifowrite(s, 2);
-               }
-               break;
-           }
-           /* Adjust optr for our pending chars record */
-           optr = ptr;
-       }
-    }
-    debug_va_end(ap);
-
-    /* Any pending chars remaining? */
-    if (optr < ptr)
-       fifowrite(optr, ptr - optr);
-
-    _lock_release(&root->debuglock);
-}
-
-
-/* XXX Need to work on stdarg-like system and vsnprintf() instead of everything
- * in debug_printf().
-void dprintf2(const char *file, const char *function, u_int32_t line,
-       const char *fmt, ...)
-{
-    debug_printf("%s:%s():%d - %s", file, func, line);
-}
-*/
-
-
-
-/* This function writes into the debug FIFO buffer in a way to cause automatic
- * recycling so that the last DEBUG bytes will always be available in the
- * history until read. We do not use the lock here, because we only want
- * full lines to be recorded, we let debug_printf() do it.
- */
-static void fifowrite(const char *buf, size_t len)
-{
-    register fifo8_t *f = &fifo;
-
-    while (len > 0) {
-       FIFO_PUT(f, buf);
-       buf++;
-       len--;
-    }
-
-    /* XXX This would be more efficient if it worked :) I need to debug this.
-    if (len == 1)
-       FIFO_PUT(f, buf);
-    else {
-       u_int8_t *ptr;
-       size_t size;
-       register size_t l = len;
-
-       if ((size = FIFO_AVAIL(f)) < l) {
-           l -= size;
-
-           while (size ) XXX;
-           size = l;
-           FIFO_FREE(f, &ptr, &size, l);
-       }
-
-       while (l > 0) {
-           FIFO_ALLOC(f, &ptr, &size, l);
-           memcpy(ptr, buf, size);
-           buf += size;
-           l -= size;
-       }
-    }
-    */
-}
-
-
-/* Allows to read data from the FIFO buffer. The bytes are unlinked from the
- * buffer dynamically when they are read.
- */
-size_t dread(char *buf, size_t len)
-{
-    register fifo8_t *f = &fifo;
-    register size_t l = len;
-
-    if (buf == NULL || len == 0)
-       return 0;
-
-    lock_acquire(&root->debuglock);
-
-    while (l > 0) {
-       if (FIFO_EMPTY(f))
-           break;
-       FIFO_GET(f, buf);
-       buf++;
-       l--;
-    }
-    len = len - l;
-
-    /* XXX Debug this more efficient alternative
-    if (len == 1) {
-       if (!FIFO_EMPTY(f))
-           FIFO_GET(f, buf);
-       else
-           len = 0;
-    } else {
-       u_int8_t *ptr;
-       int size;
-       register int l = len, i;
-
-       len = 0;
-       for (i = 0; i < 2 && l > 0; i++) {
-           FIFO_FREE(f, &ptr, &size, l);
-           if (size == 0)
-               break;
-           memcpy(buf, ptr, size);
-           buf += size;
-           len += size;
-           l -= size;
-       }
-    }
-    */
-
-    _lock_release(&root->debuglock);
-
-    return len;
-}
-
-
-/* Buffer should at least be 34 bytes. Performs 32-bit value to ASCII binary
- * convertion. Returns length of string.
- */
-static size_t btoa(char *buf, u_int32_t val)
-{
-    register int i;
-    register char *ptr = buf;
-
-    *ptr++ = '%';
-    for (i = 31; i > -1; i--)
-       *ptr++ = (val & (1L << i)) ? '1' : '0';
-    *ptr = '\0';
-
-    return (ptr - buf);
-}
-
-
-/* Buffer should be at least 12 bytes. Converts signed 32-bit value to decimal
- * ASCII representation. Returns length of string.
- */
-static size_t dtoa(char *buf, int32_t val)
-{
-    register int32_t v = val;
-    register char *ptr = buf;
-    register const char *d = ddigits;
-
-    if (v < 0) {
-       *ptr++ = '-';
-       v = -v;
-    }
-    for (; v > 9; v /= 10)
-       *ptr++ = d[v % 10];
-    *ptr++ = d[v];
-    *ptr = '\0';
-
-    return (ptr - buf);
-}
-
-
-/* Buffer should be at least 11 bytes. Unsigned 32-bit value to decimal ASCII
- * convertion. Returns length of string.
- */
-static size_t utoa(char *buf, u_int32_t val)
-{
-    register u_int32_t v = val;
-    register char *ptr = buf;
-    register const char *d = ddigits;
-
-    for (; v > 9; v /= 10)
-       *ptr++ = d[v % 10];
-    *ptr++ = d[v];
-    *ptr = '\0';
-
-    return (ptr - buf);
-}
-
-
-/* Buffer should be at least 11 bytes. Converts 32-bit value to hexadecimal
- * ASCII representation. Returns length of string.
- */
-static size_t xtoa(char *buf, u_int32_t val)
-{
-    register u_int32_t v = val;
-    register char *ptr = buf;
-    register const char *d = xdigits;
-    register int i;
-
-    *ptr++ = '0';
-    *ptr++ = 'x';
-    for (i = 32 - 4; i > -1; i -= 4)
-       *ptr++ = d[v >> i & 15];
-    *ptr = '\0';
-
-    return (ptr - buf);
-}
-#endif
diff --git a/Xisop/src/common/kernel/debug.h b/Xisop/src/common/kernel/debug.h
deleted file mode 100644 (file)
index 5f3f113..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* $Id: debug.h,v 1.3 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_DEBUG_H
-#define KERNEL_DEBUG_H
-
-
-
-#include <common/types.h>
-#include <config.h>
-
-
-
-/* This implements various debugging primitives. Macros are defined
- * so that no debugging code be compiled in the kernel if DEBUG
- * is not defined.
- */
-
-
-
-#ifndef DEBUG
-
-/* Debugging disabled, ensure that unnecessary code doesn't get compiled in.
- * if (DEBUG_TRUE(condition)) will always cause the condition to be TRUE, while
- * if (DEBUG_FALSE(condition)) will always cause the condition to be FALSE.
- * DEBUG_PRINTF() will do nothing.
- */
-
-#define DEBUG_PRINTF(s, ...)
-#define DEBUG_READ(b, s)       0
-#define DEBUG_TRUE(c)          /* CONSTCOND */1
-#define DEBUG_FALSE(c)         /* CONSTCOND */0
-
-#else
-
-/* Debugging enabled, macros must now do something */
-
-#define DEBUG_PRINTF           debug_printf
-#define DEBUG_READ(b, s)       debug_read(b, s)
-#define DEBUG_TRUE(c)          (c)
-#define DEBUG_FALSE(c)         (c)
-
-
-
-/* These should eventually be available even if no debugging is wanted.
- * However, these are really simple and are mostly made to serve 32-bit
- * values (although characters also work).
- */
-
-typedef u_int32_t *            debug_va_list;
-
-#define debug_va_start(a, l)   (a) = (u_int32_t *)(&(l) + sizeof(*(l)))
-#define debug_va_arg(a, t)     (t)(*a++)
-#define debug_va_copy(d, s)    (d) = (s)
-#define debug_va_end(a)
-
-
-
-void debug_init(void);
-void debug_printf(const char *, ...);
-/*void dprintf2(const char *, const char *, int, const char *, ...);*/
-size_t debug_read(char *, size_t);
-
-
-
-#endif
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/device.c b/Xisop/src/common/kernel/device.c
deleted file mode 100644 (file)
index c8105e8..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-/* $Id: device.c,v 1.8 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-#include <common/kernel/device.h>
-#include <common/kernel/main.h>
-#include <common/kernel/object.h>
-#include <common/kernel/port.h>
-#include <common/kernel/signal.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/debug.h>
-#include <common/kernlib/string.h>
-#include <common/kernlib/hash.h>
-
-
-
-/* Allows current task to open a devicenode_t, obtaining a device_t handle */
-device_t *device_open(const char *name, u_int32_t ver, u_int32_t unit)
-{
-    device_t *dh = NULL;
-
-    if (name != NULL) {
-       register devicenode_t *dn;
-
-       SYSTABLE_RLOCK(SYSTABLE_DEVICES);
-       dn = (devicenode_t *)hashtable_lookup(SYSTABLE(SYSTABLE_DEVICES),
-                       name, strnlen(name, 32));
-       SYSTABLE_UNLOCK(SYSTABLE_DEVICES);
-       if (dn != NULL && (dn->version == ver || ver == 0)) {
-           if ((dh = (device_t *)spool_alloc(POOL_DEVICEHANDLE)) != NULL) {
-               if (dn->open(&dh->udata, unit)) {
-                   /* Validate object and set dependancy. We also register
-                    * it since iorequest_t depend on device_t.
-                    */
-                   OBJECT_VALIDATE(dh, OBJECT_DEVICEHANDLE);
-                   OBJECT_REGISTER(dh);
-                   OBJECT_SETDEP(dh, dn);
-                   dh->devnode = dn;
-                   dn->usecount++;
-                   /* Initialize other device_t fields */
-                   dh->devport = dn->port;
-                   dh->owner = CURTASK();
-                   dh->unit = unit;
-                   /* Attach to task resources for automatic freeing */
-                   SCHED_DISABLE();
-                   DLIST_APPEND(&CURTASK()->resources.devices, &dh->tasknode);
-                   SCHED_ENABLE();
-               } else {
-                   dh = (device_t *)spool_free(POOL_DEVICEHANDLE,
-                           (pnode_t *)dh);
-                   DEBUG_PRINTF("- %T device_open(%s, %u, %u) - Refused\n",
-                           name, ver, unit);
-               }
-           } else
-               DEBUG_PRINTF("* %T device_open(%s, %u, %u) - Out of memory\n",
-                       name, ver, unit);
-       } else
-           DEBUG_PRINTF("- %T device_open(%s, %u, %u) - Unknown device\n",
-                   name, ver, unit);
-    } else
-       DEBUG_PRINTF("* %T device_open(%s, %u, %u) - Illegal parameters\n",
-               name, ver, unit);
-
-    return dh;
-}
-
-
-/* Closes and frees a device_t from the task it belongs to */
-device_t *device_close(device_t *dh)
-{
-    if (OBJECT_VALID(dh, OBJECT_DEVICEHANDLE)) {
-       if (OBJECT_DEPENDS(dh, dh->devnode)) {
-           register devicenode_t *dn = dh->devnode;
-
-           SYSTABLE_RLOCK(SYSTABLE_DEVICES);
-           /* devicenode_t for this device_t still exists */
-           dn->close(dh->udata, dh->unit);
-           if ((--(dn->usecount)) == 0 && (dn->flags & DNF_RESIDENT) == 0) {
-               if (OBJECT_VALID(dn->task, OBJECT_TASK))
-                   signal_send(dn->task, SIGMASK(SIGTERM));
-           }
-           SYSTABLE_UNLOCK(SYSTABLE_DEVICES);
-       } else
-           DEBUG_PRINTF("* %T device_close(%p) - Device has died\n", dh);
-       /* Unlink task resource and free handle */
-       SCHED_DISABLE();
-       DLIST_UNLINK(&(dh->owner->resources.devices), &dh->tasknode);
-       SCHED_ENABLE();
-       OBJECT_INVALIDATE(dh);
-       spool_free(POOL_DEVICEHANDLE, (pnode_t *)dh);
-    } else
-       DEBUG_PRINTF("* %T device_close(%p) - Invalid device_t pointer\n",
-               dh);
-
-    return NULL;
-}
-
-
-/* Initializes an iorequest_t for use with specified device_t, necessary
- * before using it to send device requests.
- */
-bool iorequest_init(iorequest_t *req, device_t *dh, port_t *rport)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(dh, OBJECT_DEVICEHANDLE) &&
-           OBJECT_DEPENDS(dh, dh->devnode) &&
-           OBJECT_VALID(rport, OBJECT_PORT)) {
-       req->udata = NULL;
-       if (dh->devnode->iorinit == NULL ||
-               (req->udata = dh->devnode->iorinit()) != NULL) {
-           /* Validate object and register dependancy on device_t */
-           OBJECT_VALIDATE(req, OBJECT_IOREQUEST);
-           OBJECT_SETDEP(req, dh);
-           req->devhandle = dh;
-           /* Initialize other iorequest_t fields */
-           req->devport = dh->devport;
-           req->rport = rport;
-           req->flags = 0;
-           req->success = FALSE;
-           req->result = 0;
-           req->actual = 0;
-           ok = TRUE;
-       } else
-           DEBUG_PRINTF("* %T iorequest_init(%p, %p, %p) - Out of memory\n",
-                   req, dh, rport);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_init(%p, %p, %p) - Invalid device_t pointer\n",
-               req, dh, rport);
-
-    return ok;
-}
-
-
-bool iorequest_destroy(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if (OBJECT_DEPENDS(req, req->devhandle) &&
-               OBJECT_DEPENDS(req->devhandle, req->devhandle->devnode)) {
-           register devicenode_t *dn = req->devhandle->devnode;
-
-           if (dn->iordestroy != NULL && req->udata != NULL)
-               dn->iordestroy(req->udata);
-       }
-       OBJECT_INVALIDATE(req);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_destroy(%p) - Invalid iorequest_t poinder\n",
-               req);
-
-    return ok;
-}
-
-
-/* Sends the iorequest_t message to it's corresponding device, and waits for
- * results to be obtained, then returns. This consists of a synchroneous
- * device request.
- */
-bool iorequest_sync(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) == 0) {
-           if (port_send(req->devport, req->rport, (message_t *)req)) {
-               register sigmask_t sigmport = PORT_SIGMASK(req->devport);
-
-               req->flags = IOF_SYNC | IOF_PENDING;
-               while (((signal_wait(sigmport, NULL)) & sigmport) == 0) ;
-               port_get(req->devport);
-               /* Request satisfied */
-               req->flags &= ~(IOF_SYNC & IOF_PENDING);
-               ok = TRUE;
-           } else
-               DEBUG_PRINTF("* %T iorequest_sync(%p) - port_send()\n", req);
-       } else
-           DEBUG_PRINTF(
-                   "* %T iorequest_sync(%p) - iorequest_t already pending\n",
-                   req);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_sync(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    return ok;
-}
-
-
-/* Sends the iorequest_t message to it's corresponding device, but returns
- * immediately, without waiting for results. This consists of an asynchroneous
- * request. The application is responsible to monitor the reply port status
- * for the request completion, and to unqueue the reply from the reply port
- * before performing another request using this iorequest_t.
- */
-bool iorequest_async(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) == 0) {
-           if (port_send(req->devport, req->rport, (message_t *)req)) {
-               req->flags = IOF_ASYNC | IOF_PENDING;
-               ok = TRUE;
-           } else
-               DEBUG_PRINTF("* %T iorequest_async(%p) - port_send()\n",
-                       req);
-       } else
-           DEBUG_PRINTF(
-                   "* %T iorequest_async(%p) - iorequest_t already pending\n",
-                   req);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_async(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    return ok;
-}
-
-
-/* Aborts a pending asynchroneous request which has not yet completed.
- * This in fact sends back a new request using the same iorequest_t, but
- * does not expect a reply back from the device for the abort request. However,
- * the reply port will be sent the reply as usual when the aborted iorequest_t
- * ends (which always happens even when a request is aborted).
- */
-bool iorequest_abort(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) != 0 && (req->flags & IOF_ASYNC) != 0) {
-           req->function = IO_ABORT;
-           if (port_send(req->devport, req->rport, (message_t *)req)) {
-               req->flags |= IOF_ABORTING;
-               ok = TRUE;
-           } else
-               DEBUG_PRINTF("* %T iorequest_abort(%p) - port_send()\n",
-                       req);
-       } else
-           DEBUG_PRINTF(
-                   "* %T iorequest_abort(%p) - iorequest_t not pending\n",
-                   req);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_abort(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    if (!ok)
-       DEBUG_PRINTF("* %T iorequest_abort(%p)\n", req);
-
-    return ok;
-}
-
-
-/* Waits until the currently pending asynchroneous request completes. The reply
- * message is automatically unqueued from the reply port in this case.
- */
-bool iorequest_wait(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) != 0 && (req->flags & IOF_ASYNC) != 0) {
-           register sigmask_t sigmport = PORT_SIGMASK(req->devport);
-
-           while (((signal_wait(sigmport, NULL)) & sigmport) == 0) ;
-           port_get(req->devport);
-           /* Request satisfied */
-           req->flags &= ~(IOF_ASYNC & IOF_PENDING);
-           ok = TRUE;
-       } else
-           DEBUG_PRINTF(
-                   "* %T iorequest_wait(%p) - iorequest_t not pending\n",
-                   req);
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_wait(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    return ok;
-}
-
-
-/* Returns TRUE if the request is asynchroneous and still pending. */
-bool iorequest_pending(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) != 0 && (req->flags & IOF_ASYNC) != 0)
-           ok = TRUE;
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_pending(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    return ok;
-}
-
-
-/* Returns TRUE if the request last terminated by iorequest_abort(). */
-bool iorequest_aborted(iorequest_t *req)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_ABORTED) != 0)
-           ok = TRUE;
-    } else
-       DEBUG_PRINTF(
-               "* %T iorequest_aborted(%p) - Invalid iorequest_t pointer\n",
-               req);
-
-    return ok;
-}
-
-
-/* Made for devices to satisfy a user iorequest_t, at the same time setting
- * the boolean result code for it.
- */
-bool iorequest_satisfy(iorequest_t *req, bool result)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       if ((req->flags & IOF_PENDING) != 0) {
-           req->flags &= ~(IOF_PENDING | IOF_SYNC | IOF_ASYNC);
-           if ((req->flags & IOF_ABORTING) != 0) {
-               req->flags &= ~IOF_ABORTING;
-               req->flags |= IOF_ABORTED;
-               req->success = result;
-           }
-           if (!(ok = port_reply((message_t *)req)))
-               DEBUG_PRINTF(
-                       "* %T iorequest_satisfy(%p, %B) - port_reply(%p)\n",
-                       req, result, req);
-       }
-    } else
-       DEBUG_PRINTF("* %T iorequest_satisfy(%p, %B) - Invalid iorequest_t\n",
-               req, result);
-
-    return ok;
-}
-
-
-/* Allows a task to attach a new device to the system lists. It then of course
- * should serve requests through it's port. The task may only become one
- * device, that is, it may not attach more than a single device.
- * It however can serve multiple units on that device, of course.
- */
-bool device_attach(const char *name, u_int32_t version, port_t *port,
-       void (*clean)(void), bool (*open)(void **, u_int32_t),
-       void (*close)(void *, u_int32_t), void *(*iorinit)(void),
-       void (*iordestroy)(void *), u_int8_t flags)
-{
-    if (CURTASK()->resources.device == NULL && name != NULL &&
-           OBJECT_VALID(port, OBJECT_PORT) && open != NULL && close != NULL) {
-       register bstr_t *bstr;
-
-       if ((bstr = bstr_new(name, 32, FALSE)) != NULL) {
-           register devicenode_t *dn;
-
-           SYSTABLE_RLOCK(SYSTABLE_DEVICES);
-           if ((dn = (devicenode_t *)hashtable_lookup(
-                           SYSTABLE(SYSTABLE_DEVICES),
-                           bstr->data, bstr->len)) == NULL ||
-                   version != dn->version) {
-               if ((dn = (devicenode_t *)spool_alloc(POOL_DEVICENODE))
-                       != NULL) {
-                   /* Validate and register for dependancies */
-                   OBJECT_VALIDATE(dn, OBJECT_DEVICENODE);
-                   OBJECT_REGISTER(dn);
-                   /* Initialize other devicenode_t fields */
-                   dn->version = version;
-                   dn->name = bstr;
-                   dn->usecount = 0;
-                   dn->flags = flags;
-                   dn->port = port;
-                   dn->task = CURTASK();
-                   dn->clean = clean;
-                   dn->open = open;
-                   dn->close = close;
-                   dn->iorinit = iorinit;
-                   dn->iordestroy = iordestroy;
-                   /* Attach */
-                   SYSTABLE_UPGRADE(SYSTABLE_DEVICES);
-                   (void) hashtable_link(SYSTABLE(SYSTABLE_DEVICES),
-                                         (hashnode_t *)dn, bstr->data,
-                                         bstr->len, FALSE);
-                   SYSTABLE_UNLOCK(SYSTABLE_DEVICES);
-
-                   return TRUE;
-               } else
-                   DEBUG_PRINTF("* %T device_attach() - Out of memory\n");
-           } else
-               DEBUG_PRINTF(
-                       "* %T device_attach() - Device exists already\n");
-
-           SYSTABLE_UNLOCK(SYSTABLE_DEVICES);
-           bstr_free(bstr);
-       } else
-           DEBUG_PRINTF("* %T device_attach() - Out of memory\n");
-    } else
-       DEBUG_PRINTF("* %T device_attach() - Invalid parameters\n");
-
-    DEBUG_PRINTF("* %T device_attach(%s, %u, %p, %p, %p, %p, %p, %p, %x)\n",
-           name, version, port, clean, open, close, iorinit, iordestroy,
-           (u_int32_t)flags);
-
-    return FALSE;
-}
-
-
-bool device_detach(devicenode_t *dn)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(dn, OBJECT_DEVICENODE)) {
-       SYSTABLE_WLOCK(SYSTABLE_DEVICES);
-       hashtable_unlink(SYSTABLE(SYSTABLE_DEVICES), (hashnode_t *)dn);
-       SYSTABLE_UNLOCK(SYSTABLE_DEVICES);
-       if (dn->clean != NULL)
-           dn->clean();
-       OBJECT_INVALIDATE(dn);
-       if (dn->name != NULL)
-           bstr_free(dn->name);
-       spool_free(POOL_DEVICENODE, (pnode_t *)dn);
-    } else
-       DEBUG_PRINTF(
-               "* %T device_detach(%p) - Invalid devicenode_t pointer\n",
-               dn);
-
-    return ok;
-}
-
-
-
-/* Utility functions for very simple synchroneous I/O */
-
-/* Like read(), but on a Xisop device */
-ssize_t device_read(iorequest_t *req, void *buf, size_t size)
-{
-    ssize_t len = -1;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       req->function = IO_READ;
-       req->len = size;
-       req->data = buf;
-       if (iorequest_sync(req)) {
-           if (req->success)
-               len = req->actual;
-       } else
-           DEBUG_PRINTF(
-                   "* %T device_read(%p, %p, %u) - iorequest_sync(%p)\n",
-                   req, buf, size, req);
-    } else
-       DEBUG_PRINTF(
-               "* %T device_read(%p, %p, %u) - Invalid iorequest_t pointer\n",
-               req, buf, size);
-
-    return len;
-}
-
-
-/* Like write(), but on a Xisop device */
-ssize_t device_write(iorequest_t *req, void *buf, size_t size)
-{
-    ssize_t len = -1;
-
-    if (OBJECT_VALID(req, OBJECT_IOREQUEST)) {
-       req->function = IO_WRITE;
-       req->len = size;
-       req->data = buf;
-       if (iorequest_sync(req)) {
-           if (req->success)
-               len = req->actual;
-       } else
-           DEBUG_PRINTF(
-                   "* %T device_read(%p, %p, %u) - iorequest_sync(%p)\n",
-                   req, buf, size, req);
-    } else
-       DEBUG_PRINTF(
-               "* %T device_write(%p, %p, %u) - Invalid iorequest_t ptr\n",
-               req, buf, size);
-
-    return len;
-}
diff --git a/Xisop/src/common/kernel/device.h b/Xisop/src/common/kernel/device.h
deleted file mode 100644 (file)
index 7276d3a..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* $Id: device.h,v 1.2 2004/01/18 17:42:59 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_DEVICE_H
-#define KERNEL_DEVICE_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/port.h>
-#include <common/kernel/task.h>
-#include <common/kernel/memory.h>
-#include <common/kernlib/list.h>
-#include <common/kernlib/hash.h>
-#include <common/kernlib/string.h>
-
-
-
-/* devicenode/device_t flags */
-#define DNF_RESIDENT           (1 << 0)
-
-/* iorequest_t flags */
-#define IOF_SYNC               (1 << 0)
-#define IOF_ASYNC              (1 << 1)
-#define IOF_PENDING            (1 << 2)
-#define IOF_ABORTING           (1 << 3)
-#define IOF_ABORTED            (1 << 4)
-
-/* Standard device commands */
-enum _devicecommands {
-    IO_ABORT = 0,
-    IO_READ,
-    IO_WRITE,
-    IO_CONTROL         /* General purpose like unix ioctl() */
-};
-
-
-
-/* For device task functions to access user data they associated with
- * device_t and iorequest_t handles (if any, or NULL).
- */
-#define DEVICEHANDLE_UDATA(d)  (d)->udata
-#define IOREQUEST_UDATA(r)     (r)->udata
-
-
-
-/* This structure holds the only necessary information which Xisop needs to
- * know. A device has to internally handle other information but which is of
- * no use to Xisop itself.
- */
-struct devicenode {
-    /* System link and information, for devices system list */
-    hashnode_t node;
-    u_int32_t version;
-    bstr_t *name;
-    u_int32_t usecount;
-    u_int8_t flags;
-    /* Validity sceal. device_t objects depend on us */
-    u_int32_t object_magic, object_id;
-
-    /* Port used to send device requests to */
-    port_t *port;
-    /* Task associated with device */
-    task_t *task;
-
-    /* Functions provided by device, described in Xisop documentation. */
-    void (*clean)(void);
-    bool (*open)(void **, u_int32_t);
-    void (*close)(void *, u_int32_t);
-    void *(*iorinit)(void);
-    void (*iordestroy)(void *);
-};
-
-/* Consists of a device handle, returned to tasks when opening a device */
-struct devicehandle {
-    pnode_t usernode;          /* Used by device for optional queuing */
-    node_t tasknode;           /* Used to remember task resource */
-    /* Validity and dependancy sceal, we depend on devicenode_t */
-    u_int32_t object_magic, object_id, objdep_magic, objdep_id;
-    devicenode_t *devnode;
-    /* Other fields */
-    task_t *owner;             /* Owner task of this handle */
-    port_t *devport;           /* Device port to use */
-    u_int32_t devnodeid;       /* Id of devnode */
-    u_int32_t unit;            /* Unit opened on device */
-    void *udata;               /* Device may link custom data here */
-};
-
-/* An iorequest_t consists of a message. This also means that the device task
- * may queue the message into custom list_t as required after they obtain it,
- * as long as they unlink it before they return it of course.
- */
-struct iorequest {
-    message_t msg;             /* An iorequest_t is a message */
-    /* Validity sceal and dependancy link */
-    u_int32_t object_magic, objdep_magic, objdep_id;
-    device_t *devhandle;
-    /* Other */
-    port_t *devport, *rport;
-    void *udata;
-    u_int8_t flags;
-
-    /* The following are the operation request control fields */
-    u_int32_t function, subfunction;
-    size_t len;
-    size_t offset;             /* Useful for block devices */
-    void *data;
-
-    /* And operation results fields */
-    bool success;
-    int result;
-    size_t actual;
-};
-
-
-
-/* User API functions */
-device_t *device_open(const char *, u_int32_t, u_int32_t);
-device_t *device_close(device_t *);
-bool iorequest_init(iorequest_t *, device_t *, port_t *);
-bool iorequest_destroy(iorequest_t *);
-bool iorequest_sync(iorequest_t *);
-bool iorequest_async(iorequest_t *);
-bool iorequest_abort(iorequest_t *);
-bool iorequest_wait(iorequest_t *);
-bool iorequest_pending(iorequest_t *);
-bool iorequest_aborted(iorequest_t *);
-
-/* Device task functions */
-bool iorequest_satisfy(iorequest_t *, bool);
-bool device_attach(const char *, u_int32_t, port_t *, void (*)(void),
-       bool (*)(void **, u_int32_t), void (*)(void *, u_int32_t),
-       void *(*)(void), void (*)(void *), u_int8_t);
-bool device_detach(devicenode_t *);
-
-/* Useful but very simple synchroneous functions */
-ssize_t device_read(iorequest_t *, void *, size_t);
-ssize_t device_write(iorequest_t *, void *, size_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/exception.c b/Xisop/src/common/kernel/exception.c
deleted file mode 100644 (file)
index 5fe0f7f..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $Id: exception.c,v 1.4 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/main.h>
-#include <common/kernel/exception.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernlib/list.h>
-#include <processor/support.h>
-#include <port/support.h>
-
-
-
-/* These are the machine-independant kernel frontend to interrupt hooks
- * facilities. They internally use a recursive _rlock_t which allows to
- * ensure reliability when adding and removing hooks to a facility,
- * while removing the need for system call traps to access the functionality.
- */
-
-hookid_t hook_attach(u_int32_t facility, u_int32_t skipcount,
-       u_int32_t runcount, void (*code)(hookid_t, int, void *), void *data)
-{
-    register hookid_t id = 0;
-
-    if (facility < (enum _facilities)_FACILITY_MAX && code != NULL) {
-       register facility_t *f;
-       register hook_t *hook;
-
-       f = (facility_t *)&root->int_facilities[facility];
-       _rlock_acquire(&f->rlock);
-       if ((hook = (hook_t *)pool_alloc(&f->pool, FALSE)) != NULL) {
-           if (++f->idcnt == 0)
-               f->idcnt++;
-           id = hook->id = f->idcnt;
-           hook->skipcount = skipcount;
-           hook->runcount = runcount;
-           hook->code = code;
-           hook->data = data;
-           DLIST_APPEND(&f->hooks, (node_t *)hook);
-           STAT(STAT_HOOKS_ATTACHED, 1);
-       } else {
-           STAT(STAT_HOOKS_ATTACHED_NOMEM, 1);
-           DEBUG_PRINTF("* %T hook_attach() - Out of memory\n");
-       }
-       _rlock_release(&f->rlock);
-    } else {
-       STAT(STAT_HOOKS_ATTACHED_FAILED, 1);
-       DEBUG_PRINTF("* %T hook_attach(%u, %u, %u, %p, %p)\n",
-               facility, skipcount, runcount, code, data);
-    }
-
-    return id;
-}
-
-
-bool hook_detach(u_int32_t facility, hookid_t id)
-{
-    register bool ok = FALSE;
-
-    if (facility < (enum _facilities)_FACILITY_MAX && id != 0) {
-       register facility_t *f;
-       register hook_t *node, *next;
-
-       f = (facility_t *)&root->int_facilities[facility];
-       _rlock_acquire(&f->rlock);
-
-       for (node = DLIST_TOP(&f->hooks); node != NULL; node = next) {
-           next = DLIST_NEXT(node);
-           if (node->id == id) {
-               DLIST_UNLINK(&f->hooks, (node_t *)node);
-               pool_free((pnode_t *)node);
-               ok = TRUE;
-               STAT(STAT_HOOKS_DETACHED, 1);
-               break;
-           }
-       }
-       if (node == NULL)
-           STAT(STAT_HOOKS_DETACHED_NOEXIST, 1);
-
-       _rlock_release(&f->rlock);
-    } else {
-       STAT(STAT_HOOKS_DETACHED_FAILED, 1);
-       DEBUG_PRINTF("* %T hook_detach(%u, %u)\n", facility, id);
-    }
-
-    return ok;
-}
-
-
-void facility_disable(u_int32_t facility)
-{
-    if (facility < (enum _facilities)_FACILITY_MAX) {
-       _rlock_acquire(&(root->int_facilities[facility].rlock));
-       STAT(STAT_FACILITY_DISABLED, 1);
-    } else {
-       STAT(STAT_FACILITY_DISABLED_FAILED, 1);
-       DEBUG_PRINTF("* %T facility_disable(%u)\n", facility);
-    }
-}
-
-
-void facility_enable(u_int32_t facility)
-{
-    if (facility < (enum _facilities)_FACILITY_MAX) {
-       _rlock_release(&(root->int_facilities[facility].rlock));
-       STAT(STAT_FACILITY_ENABLED, 1);
-    } else {
-       STAT(STAT_FACILITY_ENABLED_FAILED, 1);
-       DEBUG_PRINTF("* %T facility_enable(%u)\n", facility);
-    }
-}
-
-
-/* This is called by the port-specific code to execute the hooks associated
- * with a facility. Note that a recursive lock is internally maintained which
- * ensures to prevent recursion, or to execute the hooks while new ones are
- * being added, or when a hook is being deleted.
- */
-
-
-/* Execute the hooks and transparently delete expired ones */
-void facility_exechooks(u_int32_t facility, int origin)
-{
-    if (facility < (enum _facilities)_FACILITY_MAX) {
-       register facility_t *f = &root->int_facilities[facility];
-
-       if (_rlock_try(&f->rlock)) {
-           register list_t *hooks = &f->hooks;
-           register hook_t *node, *tmp;
-
-           STAT(STAT_FACILITY_EXECUTED, 1);
-           node = DLIST_TOP(hooks);
-           while (node != NULL) {
-               if (node->skipcount > 0) {
-                   node->skipcount--;
-                   STAT(STAT_HOOKS_SKIPPED, 1);
-                   node = DLIST_NEXT(node);
-               } else {
-                   node->code(node->id, origin, node->data);
-                   STAT(STAT_HOOKS_EXECUTED, 1);
-                   if (node->runcount != 0) {
-                       tmp = DLIST_NEXT(node);
-                       if ((--node->runcount) == 0) {
-                           /* This hook is temporary and expired,
-                            * extract it.
-                            */
-                           DLIST_UNLINK(hooks, (node_t *)node);
-                           pool_free((pnode_t *)node);
-                           STAT(STAT_HOOKS_EXPIRED, 1);
-                       }
-                       node = tmp;
-                   } else
-                       node = DLIST_NEXT(node);
-               }
-           }
-           _rlock_release(&f->rlock);
-       } else
-           STAT(STAT_FACILITY_EXECUTED_LOCKED, 1);
-    } else {
-       STAT(STAT_FACILITY_EXECUTED_FAILED, 1);
-       DEBUG_PRINTF("* %T facility_exechooks(%u, %d)\n", facility, origin);
-    }
-}
-
-
-/* Initialize all facility_t */
-void facilities_init(void)
-{
-    register u_int32_t i;
-
-    for (i = 0; i < (enum _facilities)_FACILITY_MAX; i++) {
-       register facility_t *f = &root->int_facilities[i];
-
-       f->idcnt = 0;
-       _spl0();
-       pool_init(&f->pool, 1, 1, 1, sizeof(hook_t), 0);
-       _splhigh();
-       DLIST_INIT(&f->hooks);
-       _rlock_init(&f->rlock);
-       _rlock_acquire(&f->rlock);
-    }
-    for (i = 0; i < (enum _facilities)_FACILITY_MAX; i++) {
-       register facility_t *f = &root->int_facilities[i];
-
-       _rlock_release(&f->rlock);
-    }
-}
diff --git a/Xisop/src/common/kernel/exception.h b/Xisop/src/common/kernel/exception.h
deleted file mode 100644 (file)
index 760bdb6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $Id: exception.h,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_EXCEPTION_H
-#define KERNEL_EXCEPTION_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernlib/list.h>
-#include <processor/support.h>
-#include <port/support.h>
-
-
-
-/* Used to hold user code hooks which should be executed at exceptions
- * depending on the facility they are attached to.
- */
-struct _int_hook {
-    pnode_t node;
-    hookid_t id;
-    u_int32_t skipcount, runcount;
-    void (*code)(hookid_t, int, void *);
-    void *data;
-};
-
-/* There are _FACILITIES_MAX of these in the root->facilities array.
- * The facilities are defined by the port-specific code.
- */
-struct _int_facility {
-    hookid_t idcnt;
-    list_t hooks;
-    pool_t pool;
-    _rlock_t rlock;
-};
-
-
-hookid_t hook_attach(u_int32_t, u_int32_t, u_int32_t,
-       void (*)(hookid_t, int, void *), void *);
-bool hook_detach(u_int32_t, hookid_t);
-void facility_disable(u_int32_t);
-void facility_enable(u_int32_t);
-
-void facilities_init(void);
-void facility_exechooks(u_int32_t, int);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/main.c b/Xisop/src/common/kernel/main.c
deleted file mode 100644 (file)
index 8232cc7..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/* $Id: main.c,v 1.8 2004/06/04 02:25:15 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/main.h>
-#include <common/kernel/syscall.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/task.h>
-#include <common/kernel/port.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernlib/list.h>
-#include <common/kernlib/hash.h>
-#include <common/kernlib/string.h>
-#include <port/support.h>
-#include <processor/support.h>
-#include <config.h>
-
-
-
-COPYRIGHT("\0\nXisop Copyright 2001-2003, Matthew Mondor, \
-All rights reserved.\n");
-
-
-
-/* The famous global structure where all Xisop control information is stored */
-struct xisop_root root[1];
-
-static const char *systables_names[SYSTABLE_MAX] = {
-    "systable_publicports",
-    "systable_libraries",
-    "systable_devices",
-    "systable_handlers",
-    "systable_volumes"
-};
-
-
-
-/* Xisop main code. The port-specific code should switch to supervisor mode,
- * setup kernel stack, disable interrupts and setup it's interrupt handlers,
- * setup the memory ppools, call xisop_init(), switch back to usermode, and
- * jump definitively to this function.
- */
-int main(void)
-{
-    /* And we're Xisop-hosted! */
-
-    /* Setup and launch our main Xisop init task. It's source is in
-     * src/common/kernel/task.c.
-     */
-    {
-       register task_t *task;
-
-       if ((task = task_alloc(task_init, NULL, NULL, 0, 4096, TF_KERNEL))
-               != NULL)
-           task_start(task);
-    }
-
-    /* Here we enable the scheduler, which means that this current context
-     * will soon be the first to be saved in root->curctx, which currently
-     * consists of the _scontext _ctx_t buffer. When no more tasks are
-     * in the ready queue, _scontext will also be the restored context,
-     * in which case we want to avoid wasting power and overheating the
-     * CPU unnecessarily, and are using _idle() in an endless loop to do that.
-     * Because we are in usermode, we use sys_idle().
-     */
-    SCHED_ENABLE();
-
-    for (;;) {
-       /* Just idle processor */
-       /* XXX Amiga-specific, can be taken out, purple color on blitter to
-        * show that the system is all idle
-        */
-       CUSTOM->COLOR[0] = 0x0F0F;
-       sys_idle();
-    }
-
-    /* NOTREACHED */
-    return 0;
-}
-
-
-void xisop_init(void)
-{
-    /* Enable interrupts and therefore syscalls, facilities and scheduler
-     * timer as well. Note that until we SCHED_ENABLE(), the scheduler will
-     * not attempt to perform contex switches, even though the scheduler
-     * timer interrupt is enabled.
-     */
-
-#ifdef STATISTICS
-    statistic_init();
-#endif
-
-    /* Unique number generator */
-    _lock_init(&root->unique_lock);
-    root->unique = 0;
-
-    /* Kernel memory allocators */
-    _lock_init(&root->kernpool_lock);
-    spools_init();                     /* memory.h */
-    if ((root->kernpool = (mpool_t *)spool_alloc(POOL_MPOOL)) == NULL) {
-       /* XXX Panic */
-       CUSTOM->COLOR[0] = 0x0F00;
-    }
-    if (!mpool_init(root->kernpool)) {
-       /* XXX Panic */
-       CUSTOM->COLOR[0] = 0x0F00;
-    }
-
-    /* And task multitasking scheduler */
-    scheduler_init();                  /* scheduler.c */
-
-    /* Syscalls service */
-    syscall_init();
-
-#ifdef DEBUG
-    /* Debugging messages FIFO */
-    debug_init();
-#endif
-
-    /* System hash tables */
-    /* XXX Hmm the following calls kmalloc() which calls _kmalloc() which
-     * in turn calls lock_acquire(&root->kernpool_lock) which finally calls
-     * _yield(NULL) if it cannot immediately obtain the lock. However, _yield()
-     * function requires the scheduler interrupt to be running, and the
-     * scheduler lock to be released, of course. This appears to be the reason
-     * why the system now locks in trap_catch1() which corresponds to the
-     * _yield() handler... But, why can't the lock be obtained immediately?
-     * Since it is properly initialized first...
-     * I tried this in xisop_init(), in start of main() and in main() after
-     * SCHED_ENABLE(), always with the same results. Would it be possible that
-     * something we lock a lock, and are calling something which also attempts
-     * to lock it (and we already hold it)? If so, it would be either
-     * _kmalloc() or pages_alloc(). But they are both using a different lock..
-     * Or, would it be possible that I messed up port.c locking?
-     * XXX Oh! It works fine when I strip out DEBUG and STATISTICS. This
-     * probably means that the problem is the the xisop kernel size and boot
-     * loader which need adjusting.
-     */
-    {
-       register int i;
-
-       for (i = 0; i < (enum systables)SYSTABLE_MAX; i++) {
-           rwlock_init(&root->systables[i].lock);
-           if (!hashtable_init(SYSTABLE(i), systables_names[i],
-                       HT_DEFAULT_CAPACITY, kmalloc, kfree,
-                       memcmp, memhash32, TRUE)) {
-               /* XXX PANIC! */
-               CUSTOM->COLOR[0] = 0x0F00;
-           }
-       }
-    }
-
-    /* Enable interrupts */
-    _spl0();
-}
-
-
-u_int32_t unique_id(void)
-{
-    register u_int32_t id;
-
-    lock_acquire(&root->unique_lock);
-    id = (++root->unique);
-    _lock_release(&root->unique_lock);
-
-    return id;
-}
-
-
-hashtable_t *systable_lock(u_int32_t systable, bool exclusive)
-{
-    hashtable_t *list = NULL;
-
-    if (systable < (enum systables)SYSTABLE_MAX) {
-       if (exclusive)
-           SYSTABLE_WLOCK(systable);
-       else
-           SYSTABLE_RLOCK(systable);
-       list = SYSTABLE(systable);
-    }
-
-    return list;
-}
-
-
-void systable_unlock(u_int32_t systable)
-{
-    if (systable < (enum systables)SYSTABLE_MAX)
-       SYSTABLE_UNLOCK(systable);
-}
-
-
-void systable_upgrade(u_int32_t systable)
-{
-    if (systable < (enum systables)SYSTABLE_MAX)
-       SYSTABLE_UPGRADE(systable);
-}
diff --git a/Xisop/src/common/kernel/main.h b/Xisop/src/common/kernel/main.h
deleted file mode 100644 (file)
index 90dc56a..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $Id: main.h,v 1.5 2004/01/19 18:07:11 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_MAIN_H
-#define KERNEL_MAIN_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/task.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/exception.h>
-#include <common/kernlib/list.h>
-#include <common/kernlib/string.h>
-#include <common/kernlib/fifo.h>
-#include <common/kernlib/hash.h>
-#include <processor/support.h>
-#include <port/support.h>
-#include <config.h>
-
-
-
-/* To access and manipulate system lists */
-#define SYSTABLE(l)    (&(root->systables[(enum systables)(l)].table))
-#define SYSLOCK(l)     (&(root->systables[(enum systables)(l)].lock))
-#define SYSTABLE_RLOCK(l)      rwlock_acquire(SYSLOCK(l), FALSE)
-#define SYSTABLE_WLOCK(l)      rwlock_acquire(SYSLOCK(l), TRUE)
-#define SYSTABLE_UNLOCK(l)     rwlock_release(SYSLOCK(l))
-#define SYSTABLE_UPGRADE(l)    rwlock_upgrade(SYSLOCK(l))
-
-
-/* A system list. The lock allows simultaneous read-only access, or exclusive
- * access when write operations are required.
- */
-struct systable {
-    rwlock_t lock;
-    hashtable_t table;
-};
-
-enum systables {
-    SYSTABLE_PUBLICPORTS = 0,
-    SYSTABLE_LIBRARIES,
-    SYSTABLE_DEVICES,
-    SYSTABLE_HANDLERS,
-    SYSTABLE_VOLUMES,
-    SYSTABLE_MAX
-};
-
-
-/* The Xisop main root structure */
-struct xisop_root {
-
-    /* Do not change the order of the following block fields, as port-specific
-     * assembly code may assume their offsets.
-     */
-
-    /* Scheduling */
-    _rlock_t sched_lock;
-    list_t tasks_ready, tasks_wait, tasks_dead;
-    task_t *curtask;
-    _ctx_t *curctx;
-
-    /* The remaining fields are only accessed by common C code. */
-    task_t *task_init, *task_reaper;
-
-    /* Memory management. First are the system page pools */
-    ppool_t ppools[(enum _memtypes)_MEM_MAX];
-    /* Then the system object pools */
-    _lock_t spools_locks[(enum _syspools)POOL_MAX];
-    pool_t spools[(enum _syspools)POOL_MAX];
-    /* And the kernel general purpose pool */
-    _lock_t kernpool_lock;
-    mpool_t *kernpool;
-
-    /* Interrupts abstraction system */
-    facility_t int_facilities[(enum _facilities)_FACILITY_MAX];
-
-   /* Various important system lists */
-    struct systable systables[(enum systables)SYSTABLE_MAX];
-
-    /* System calls */
-    void (**syscalls)(void *, void *);
-
-    /* Useful counter to create unique IDs for arbitrary objects, like for
-     * ports, using the UNIQUE() macro. Should normally be used when the
-     * scheduler is disabled.
-     */
-    _lock_t unique_lock;
-    u_int32_t unique;
-
-#ifdef STATISTICS
-    /* Statistics support */
-    u_int32_t stats[(enum stat_keys)STAT_MAX];
-#endif
-#ifdef DEBUG
-    /* dprintf() support */
-    _lock_t debuglock;
-    fifo8_t *debugfifo;
-#endif
-};
-
-
-
-/* xisop global data */
-extern struct xisop_root root[1];
-
-
-
-int main(void);
-void xisop_init(void);
-u_int32_t unique_id(void);
-
-hashtable_t *systable_lock(u_int32_t, bool);
-void systable_upgrade(u_int32_t);
-void systable_unlock(u_int32_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/make.sh b/Xisop/src/common/kernel/make.sh
deleted file mode 100755 (executable)
index fbd47d8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../makedefs.sh
-
-buildlib .
-show $C_AR ar/kernel.a *.o
-show $C_RANLIB ar/kernel.a
diff --git a/Xisop/src/common/kernel/memory.c b/Xisop/src/common/kernel/memory.c
deleted file mode 100644 (file)
index 3811e14..0000000
+++ /dev/null
@@ -1,1425 +0,0 @@
-/* $Id: memory.c,v 1.9 2004/06/04 03:09:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Support for multiple memory types and dynamically attaching pages at
- * runtime was implemented the 25 Febuary 2003, when this code was rewritten
- * from scratch.
- *
- * This memory management system works with physical pages. This means that
- * we must provide facilities to work with actual physical contiguous pages
- * when large memory areas are required. Pages only consist of useful units
- * for management; They thus can be of any size (although multiples of 16
- * bytes), and do not need to correspond to the page size required by the
- * MMU system (if any).
- *
- * It may not be the best or most efficient way to deal with this, as I
- * wrote this code from scratch using my own ideas, without reference.
- * But it works well and seems quite fast. Moreover, _PAGE_SIZE, _MEM_MAX
- * and _MPOOLS are provided by the port-specific code, and allows to adapt
- * the system to a variety of situations. It thus well serves it's intended
- * purpose. We provide operations on pages, on basic fixed-sized pools and
- * multiple block size pools for general purpose memory management functions.
- *
- * A previous pool_t implementation attempted to not have to delete all the
- * nodes from a page when moving an unused page to the page cache, and
- * statistics would be kept to know when to free them, at which time their
- * pnode_t nodes were unlinked as well. Some care was taken to append freed
- * nodes of less used pages at the end of the list and insert freed nodes of
- * very used ones at the top of the list, so that over time hopefully
- * the system would stabilize well. It used to result in more fragmentation
- * than the current method which still caches unused pages and uses statistics
- * to free them less often, but immediately removes all nodes of a page from
- * the free nodes list when a page is unused, and has to re-initialize all
- * those nodes for a page when retreiving a page back from the cache.
- * Because Xisop works with actual physical pages and that it requires actual
- * contiguous pages for large data blocks, it is very important to do what is
- * necessary to avoid fragmentation as much as possible, in favor of stability
- * and performance over long uptimes periods, and so I reverted to this method.
- * We favor reuse of recently used nodes and pages as much as possible.
- *
- * It would be nice if the free list consisted of nodes linking to the next
- * contiguous pages block rather than only individual pages. This would speed
- * up multiple page allocations, which currently requires running among free
- * pages to locate contiguous ones. Possibly that freeing could also adapt
- * the pages index dynamically so that nodes could be restored without running
- * among individual pages to know where to insert the node.
- *
- * The system was first tested on NetBSD in userspace, to ensure that
- * everything works as expected before the code was imported in Xisop.
- *
- * Matt
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/main.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/syscall.h>
-#include <common/kernel/task.h>
-#include <common/kernel/object.h>
-#include <common/kernel/port.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/device.h>
-#include <common/kernel/debug.h>
-#include <common/kernlib/list.h>
-#include <common/kernlib/string.h>
-#include <port/support.h>
-#include <processor/support.h>
-#include <config.h>
-
-
-
-/* Used by spools_init() */
-static const struct syspools_params syspools_params
-       [(enum _syspools)POOL_MAX] = {
-    {"tasks_pool", 1, 0, 0, sizeof(task_t)},
-    {"ports_pool", 1, 0, 0, sizeof(port_t)},
-    {"devicenodes_pool", 1, 0, 0, sizeof(devicenode_t)},
-    {"devices_pool", 1, 0, 0, sizeof(device_t)},
-    {"mpools_pool", 1, 0, 0, sizeof(mpool_t)}
-};
-
-
-
-/* This function is required to call once before initializing the memory
- * pages, by the port-specific code.
- */
-void memory_init(void)
-{
-    register u_int32_t i;
-
-    for (i = 0; i < (enum _memtypes)_MEM_MAX; i++) {
-       _lock_init(&root->ppools[i].lock);
-       DLIST_INIT(&root->ppools[i].mchunks);
-    }
-}
-
-
-/* This function is extremely useful to prepare a given contiguous memory area
- * for it to be attached to the system pages using mchunk_attach().
- * Sanity checking is performed to fix page alignment if needed, and the
- * internal control structures are automatically prepared.
- * Returns a pointer to an mchunk_t, or NULL if the supplied memory area is
- * too small (under two valid pages).
- */
-mchunk_t *mchunk_init(void *mem, size_t size)
-{
-    mchunk_t *mchunk = NULL;
-    void *begin, *end;
-    u_int32_t pages;
-
-    /* Page-align pointers, and calculate number of supplied memory pages */
-    end = mem + size;
-    begin = (void *)BALIGN_CEIL(mem, _PAGE_SIZE);
-    end = (void *)BALIGN_FLOOR(end, _PAGE_SIZE);
-    pages = (end - begin) / _PAGE_SIZE;
-
-    if (pages > 1) {
-       void *reserved;
-       page_t **index, *page;
-       u_int32_t extrapages;
-       size_t extrabytes;
-
-       /* Evaluate how many pages are required to be reserved to setup the
-        * mchunk_t and it's components. As we evaluate this on the number of
-        * available pages, which will shrink a bit after we reserve the area,
-        * we will re-evaluate it later, but will still be using the same
-        * reserved area, thus loosing a few bytes. The loss is however quite
-        * negligable.
-        */
-       extrabytes = (size_t)OALIGN_CEIL(sizeof(mchunk_t), u_int32_t);
-       extrabytes += (sizeof(page_t *) + sizeof(page_t)) * pages;
-       extrapages = extrabytes / _PAGE_SIZE;
-       if (extrabytes % _PAGE_SIZE)
-           extrapages++;
-       reserved = begin;
-       begin += extrapages * _PAGE_SIZE;
-       pages -= extrapages;
-
-       /* Now our necessary reserved area is at <reserved>, and has little
-        * more room than required to store all the control data. We have to
-        * setup <pages> pages, starting at <begin> and ending at <end>.
-        * First setup our control structures pointers.
-        */
-       mchunk = (mchunk_t *)reserved;
-       reserved += sizeof(mchunk_t);
-       reserved = (void *)OALIGN_CEIL(reserved, u_int32_t);
-       page = reserved;
-       reserved += sizeof(page_t) * pages;
-       reserved = (void *)OALIGN_CEIL(reserved, u_int32_t);
-       index = reserved;
-
-       /* Run through pages filling the control index and headers, while
-        * linking the page_t nodes into the mchunk_t.
-        */
-       DLIST_INIT(&mchunk->free);
-       mchunk->index = index;
-       mchunk->pages = pages;
-       {
-           register u_int8_t *run = begin;
-           register list_t *l = &mchunk->free;
-           register u_int32_t i;
-
-           for (i = 0; i < pages; i++, run += _PAGE_SIZE) {
-               register page_t *p = &page[i];
-
-               p->mchunk = mchunk;
-               p->address = run;
-               p->last = NULL;
-               p->id = i;
-               p->state = PS_FREE;
-               p->pool = NULL;
-               index[i] = p;
-               DLIST_APPEND(l, (node_t *)p);
-           }
-       }
-    }
-
-    if (mchunk != NULL)
-       OBJECT_VALIDATE(mchunk, OBJECT_MCHUNK);
-
-    return mchunk;
-}
-
-
-/* Allows to dynamically attach new memory at runtime. This can be useful
- * for instance to assign memory for a hotplug device such as PCMCIA RAM.
- * The mchunk_t should be setup using mchunk_init(). It is recommended to
- * read the Xisop documentation for more information. One of the existing
- * memory types supplied by the port-specific code should be chosen to which
- * attach the chunk. mchunk_attach() is also used by the port-specific code
- * to attach the initial memory pages.
- */
-bool mchunk_attach(int memtype, mchunk_t *mchunk)
-{
-    bool ok = FALSE;
-
-    if (memtype < (enum _memtypes)_MEM_MAX && memtype != _MEM_ANY &&
-           OBJECT_VALID(mchunk, OBJECT_MCHUNK)) {
-       register ppool_t *p;
-       register mchunk_t *m;
-
-       p = &root->ppools[memtype];
-       mchunk->ppool = p;
-
-       /* Obtain the system pages protection lock */
-       lock_acquire(&p->lock);
-
-       /* Make sure that this chunk is not already in the pool. We can
-        * afford this as this is a rare call, although dangerous.
-        */
-       DLIST_FOREACH(&p->mchunks, m) {
-           if (m == mchunk)
-               break;
-       }
-       if (m == NULL) {
-           DLIST_APPEND(&p->mchunks, (node_t *)mchunk);
-           ok = TRUE;
-           STAT(STAT_MCHUNKS_ATTACH, 1);
-       }
-
-       _lock_release(&p->lock);
-    }
-
-    if (!ok) {
-       STAT(STAT_MCHUNKS_ATTACH_FAILED, 1);
-       DEBUG_PRINTF("* %T mchunk_attach(%d, %p)\n", memtype, mchunk);
-    }
-
-    return ok;
-}
-
-
-/* Permits to dynamically detach memory at runtime, which was previously
- * attached using mchunk_attach(). Note that this function fails with FALSE
- * if any page of memory currently remains allocated, or if the mchunk_t is
- * not currently attached.
- */
-bool mchunk_detach(int memtype, mchunk_t *mchunk)
-{
-    bool ok = FALSE;
-
-    if (memtype < (enum _memtypes)_MEM_MAX && memtype != _MEM_ANY &&
-           OBJECT_VALID(mchunk, OBJECT_MCHUNK)) {
-       register ppool_t *p;
-       register mchunk_t *m;
-
-       p = &root->ppools[memtype];
-
-       /* Lock system pages safely lock */
-       lock_acquire(&p->lock);
-
-       /* Make sure that this chunk is attached in the expected memory type,
-        * and also make sure that all pages are free (unallocated).
-        */
-       DLIST_FOREACH(&p->mchunks, m) {
-           if (m == mchunk)
-               break;
-       }
-       if (m == mchunk) {
-           if (m->pages == DLIST_NODES(&m->free)) {
-               DLIST_UNLINK(&p->mchunks, (node_t *)m);
-               ok = TRUE;
-               STAT(STAT_MCHUNKS_DETACH, 1);
-           }
-       }
-
-       _lock_release(&p->lock);
-    }
-
-    if (!ok) {
-       STAT(STAT_MCHUNKS_DETACH_FAILED, 1);
-       DEBUG_PRINTF("* %T mchunk_detach(%d, %p)\n", memtype, mchunk);
-    }
-
-    return ok;
-}
-
-
-/* Requests obtention of one or more contiguous physical pages from the system.
- * Returns a pointer to the first page_t on success, or NULL on failure
- * (out of memory). If <zero> is true, the returned memory area will be
- * cleared to 0x00 bytes. To properly be freed, pages_free() is expected to
- * be called on the same supplied pointer, which will free back all pages
- * which were allocated at once with this function. On success,
- * pages_t->address can be used to access our requested memory.
- */
-page_t *pages_alloc(int memtype, u_int32_t many, bool zero)
-{
-    register ppool_t *fp = NULL, *tp = NULL;
-    page_t *pages = NULL;
-    bool ok;
-
-    /* If a memory type was specified, only run through that ppool_t, but
-     * run through each ppool_t in order otherwise until we satisfy the
-     * request. It is safe to do this interruptible as the memory types
-     * pools always remain static.
-     */
-    ok = TRUE;
-    if (many < 1)
-       ok = FALSE;
-    else {
-       if (memtype > -1) {
-           if (memtype < (enum _memtypes)_MEM_MAX) {
-               /* Will only try requested memory type */
-               fp = tp = &root->ppools[memtype];
-               tp++;
-           } else
-               ok = FALSE;
-       } else if (memtype == _MEM_ANY) {
-           /* Will try all memory types sequencially in order */
-           fp = &root->ppools[0];
-           tp = &root->ppools[(enum _memtypes)_MEM_MAX];
-           tp++;
-       } else
-           ok = FALSE;
-    }
-
-    if (ok) {
-       /* Loop through ppool_t types */
-       for (; fp < tp; fp++) {
-           register mchunk_t *m;
-
-           lock_acquire(&fp->lock);
-
-           /* Loop through mchunk_t nodes of the ppool_t */
-           DLIST_FOREACH(&fp->mchunks, m) {
-               /* Skip any mchunk_t which doesn't have enough pages */
-               if (DLIST_NODES(&m->free) >= many) {
-                   if (many == 1) {
-                       register page_t *p;
-
-                       /* No need to look for contiguous pages as only a
-                        * single one was requested. Detach the first page.
-                        */
-                       p = DLIST_TOP(&m->free);
-                       DLIST_UNLINK(&m->free, &p->node);
-                       p->node.next = p->node.prev = NULL;
-                       p->last = p;
-                       p->state = PS_ALLOCATED;
-                       _lock_release(&fp->lock);
-                       if (zero)
-                           pageclr(p->address, 1);
-                       pages = p;
-                       STAT(STAT_PAGES_ALLOC, 1);
-                       goto end;
-                   } else {
-                       register page_t *n, *o;
-                       register u_int32_t c, oid;
-
-                       /* Scan for <many> contiguous pages in this mchunk_t */
-                       c = 1;
-                       o = DLIST_TOP(&m->free);
-                       oid = o->id;
-                       for (n = DLIST_NEXT(o); n != NULL; n = DLIST_NEXT(n)) {
-                           if (++oid == n->id) {
-                               /* Contiguous, count and continue */
-                               c++;
-                               if (c == many)
-                                   break;
-                           } else {
-                               /* Not contiguous, reset and continue */
-                               c = 1;
-                               o = n;
-                           }
-                       }
-                       if (c == many) {
-                           register node_t *next, *prev;
-
-                           /* <many> contiguous pages were found, starting at
-                            * o and ending at n, unlink them all at once
-                            * efficiently and set last pointer.
-                            */
-                           prev = o->node.prev;
-                           next = n->node.next;
-                           if (prev)
-                               prev->next = next;
-                           else
-                               m->free.top = next;
-                           if (next)
-                               next->prev = prev;
-                           else
-                               m->free.bottom = prev;
-                           o->node.prev = n->node.next = NULL;
-                           o->last = n;
-                           m->free.nodes -= c;
-
-                           /* Then initialize the pages. Unfortunately
-                            * we need to perform this with lock held
-                            * because freeing pages runs among pages
-                            * looking for PS_FREE nodes.
-                            */
-                           for (n = o; c > 0;
-                                   n = (page_t *)n->node.next, c--)
-                               n->state = PS_ALLOCATED;
-
-                           /* Finished with system pools, restore level */
-                           _lock_release(&fp->lock);
-
-                           /* It's safe to do the following interruptible */
-                           if (zero)
-                               pageclr(o->address, many);
-                           pages = o;
-                           STAT(STAT_PAGES_ALLOC, many);
-                           goto end;
-                       }
-                   }
-               }
-           }
-
-           _lock_release(&fp->lock);
-       }
-       /* If we reach this point the allocation process desperatly failed */
-    }
-
-end:
-    if (pages == NULL) {
-       STAT(STAT_PAGES_ALLOC_NOMEM, 1);
-       DEBUG_PRINTF("- %T pages_alloc(%d, %u, %B) - Out of memory\n",
-               memtype, many, zero);
-    }
-
-    return pages;
-}
-
-
-/* Frees one or more contiguous pages of physical memory which were obtained
- * using pages_alloc(). It is important to call this function on the same
- * page_t pointer which was obtained from pages_alloc().
- */
-bool pages_free(page_t *pages)
-{
-    bool ok = FALSE;
-
-    if (pages != NULL && pages->last != NULL) {
-       register mchunk_t *m;
-       register page_t **idx, *fp, *lp, *lfp, *llp;
-       register u_int32_t id;
-
-       /* Find mchunk_t we belong to, setup variables */
-       fp = pages;
-       lp = pages->last;
-       m = pages->mchunk;
-       idx = m->index;
-
-       lock_acquire(&m->ppool->lock);
-
-       /* Reset pages fields. Because the freeing process requires running
-        * among pages looking for PS_FREE ones, we need to perform this
-        * while we own the lock.
-        */
-       for (lfp = fp; lfp != NULL; lfp = (page_t *)lfp->node.next)
-           lfp->state = PS_FREE;
-
-       /* Determine where in the free list_t of our mchunk_t should our page_t
-        * nodes be inserted. It is important that the free list always remain
-        * sorted. Using the page index ID of our first and last allocated
-        * pages, we can run up and down among pages to obtain this
-        * information. Another possible method would be to use a minheap
-        * implementation.
-        */
-       for (id = fp->id - 1; id > -1 && idx[id]->state != PS_FREE; id--) ;
-       if (id == -1 || idx[id]->state == PS_ALLOCATED)
-           lfp = NULL;
-       else
-           lfp = idx[id];
-       for (id = lp->id + 1; id < m->pages && idx[id]->state != PS_FREE;
-               id++) ;
-       if (id == m->pages || idx[id]->state == PS_ALLOCATED)
-           llp = NULL;
-       else
-           llp = idx[id];
-
-       /* Now lfp == free page_t to attach first page_t to (or NULL)
-        * and llp == free page_t to attach last page_t to (or NULL).
-        * We also know that within this mchunk_t no pages should exist
-        * between our first and last allocated pages because they are
-        * contiguous; We thus can safely insert our allocated pages in one
-        * efficient step between lfp and llp. We could have done the following
-        * immediately after checking for ID boundaries in the previous loops,
-        * but decide to perform NULL checking instead for code clarity.
-        * Link lfp (or top of list) to fp in both directions, and make sure
-        * to set the list top and bottom pointers when necessary as well.
-        */
-       if (lfp == NULL) {
-           m->free.top = (node_t *)fp;
-           fp->node.prev = NULL;
-       } else {
-           lfp->node.next = (node_t *)fp;
-           fp->node.prev = (node_t *)lfp;
-       }
-       /* Link llp (or bottom of list) to lp in both directions */
-       if (llp == NULL) {
-           m->free.bottom = (node_t *)lp;
-           lp->node.next = NULL;
-       } else {
-           llp->node.prev = (node_t *)lp;
-           lp->node.next = (node_t *)llp;
-       }
-       /* Fix number of free nodes counter */
-       m->free.nodes += (lp->id - fp->id) + 1;
-
-       _lock_release(&m->ppool->lock);
-
-       STAT(STAT_PAGES_FREE, (lp->id - fp->id) + 1);
-
-       /* Make sure to not agree to free these anymore until this page_t *
-        * is obtained again from pages_alloc(). As the page may have been
-        * part of a pool_t, we also must zero the pool pointer.
-        */
-       pages->last = NULL;
-       pages->pool = NULL;
-
-       ok = TRUE;
-    }
-
-    if (!ok) {
-       STAT(STAT_PAGES_FREE_FAILED, 1);
-       DEBUG_PRINTF("* %T pages_free(%p)\n", pages);
-    }
-
-    return ok;
-}
-
-
-/* Initializes a pool_t and allocates the required minimum pages if required.
- * The pages of a pool_t can be virtually sized as large as required by
- * specifying a steppages larger than 1. steppages * _PAGE_SIZE is the
- * actual size of a pool_t page. A pool can then be used to allocate objects
- * exceeding _PAGE_SIZE. No locking or synchronization is used by
- * pool_t functions, those must be provided externally by the caller if
- * needed. Of course internal page allocation/free will be done protected by
- * the system pages pool lock. A pool_t links the pages to it's lists via
- * the pages_t->poolnode node_t. If minpages == 0, no pages are allocated
- * until the first pool_alloc() is called on the pool_t. If maxpages == 0
- * the pool will always attempt to grow dynamically if required (and pnode_t
- * allocations will fail if out of memory). If minpages and maxpages are
- * non-zero and the same, pages are pre-allocated immediately and the pool
- * will never shrink or grow. This can be very useful in the case of critical
- * code sections which need to allocate and free objects in an interrupt
- * context. A pool_t, unlike an mpool_t, will not allow to specify which
- * memory type to allocate at each pnode_t allocation. It is however safe to
- * use _MEM_ANY for memtype here in which case any free memory will be used,
- * requested and freed as necessary.
- */
-bool pool_init(pool_t *pool, u_int32_t steppages, u_int32_t minpages,
-       u_int32_t maxpages, size_t nodesize, int memtype)
-{
-    bool ok = FALSE;
-
-    if (pool != NULL && steppages != 0 && nodesize >= sizeof(pnode_t) &&
-           memtype < (enum _memtypes)_MEM_MAX && memtype > -2) {
-       register size_t psize;
-       register u_int32_t nodesperpage, step = steppages;
-
-       /* Evaluate how many nodes can fit a page, and that it's realistic.
-        * There is no point in using a pool_t if we cannot fit at least two
-        * pnode_t objects per page_t. So we'll automatically increase
-        * steppages if needed here, upto 8 maximum, and return FALSE if
-        * we couln't reach a decent size relatively to the object size.
-        * The reason we're doing this is that Xisop system objects pools
-        * should grow steppages automatically if needed, and are always sure
-        * to be small enough to at least fit into 8 pages (usually 1-2).
-        * We want main.c's spools_init() to always succeed even if
-        * an object was slightly too large for a single page.
-        */
-       OBJECT_INVALIDATE(pool);
-       nodesize = (size_t)OALIGN_CEIL(nodesize, u_int32_t);
-       /* All your optimization are belong to us. */
-       for (psize = _PAGE_SIZE * step;
-               (nodesperpage = psize / nodesize) < 2 && step < 9;
-               psize = _PAGE_SIZE * (++step))
-           STAT(STAT_POOLS_ENLARGED, 1);
-       if (nodesperpage > 1) {
-           pool->nodesperpage = nodesperpage;
-           pool->steppages = step;
-           pool->minpages = minpages;
-           pool->maxpages = maxpages;
-           pool->avgtotal = pool->avgcnt = minpages;
-           pool->nodesize = nodesize;
-           pool->memtype = memtype;
-           DLIST_INIT(&pool->pages);
-           DLIST_INIT(&pool->fpages);
-           DLIST_INIT(&pool->nodes);
-           pool->mpool = NULL;
-           /* Allocate and initialize pages and nodes if needed */
-           for (; minpages > 0; minpages--) {
-               register page_t *p;
-
-               if ((p = pages_alloc(memtype, step, FALSE)) != NULL) {
-                   register u_int8_t *ptr, *toptr;
-
-                   /* pool_t pages are linked via page_t->poolnode */
-                   p->pnodes = nodesperpage;
-                   p->pool = pool;
-                   DLIST_APPEND(&pool->pages, &p->poolnode);
-                   for (ptr = (u_int8_t *)p->address, toptr = ptr + psize;
-                           ptr + nodesize < toptr;
-                           ptr += nodesize) {
-                       ((pnode_t *)ptr)->page = p;
-                       DLIST_APPEND(&pool->nodes, (node_t *)ptr);
-                   }
-               } else
-                   break;
-           }
-           OBJECT_VALIDATE(pool, OBJECT_POOL);
-           if (minpages == 0)
-               ok = TRUE;
-           else if (minpages < pool->minpages) {
-               /* Some of minpages were allocated, we need to free them */
-               pool_destroy(pool);
-               DEBUG_PRINTF(
-                   "* %T pool_init(%p, %u, %u, %u, %u, %d) - Out of memory\n",
-                   pool, steppages, minpages, maxpages, nodesize, memtype);
-           }
-       }
-    }
-
-    if (ok)
-       STAT(STAT_POOLS_CREATED, 1);
-    else {
-       STAT(STAT_POOLS_CREATED_FAILED, 1);
-       DEBUG_PRINTF("* %T pool_init(%p, %u, %u, %u, %u, %d)\n",
-               pool, steppages, minpages, maxpages, nodesize, memtype);
-    }
-
-    return ok;
-}
-
-
-/* Frees all memory allocated by a pool_t, thus rendering any allocated
- * pnode_t objects invalid as well. The pool_t is then marked as invalid,
- * it can only be valid again if initialized using pool_init().
- * FALSE is returned if the pool_t is invalidated already.
- */
-bool pool_destroy(pool_t *pool)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(pool, OBJECT_POOL)) {
-       register node_t *p, *t;
-
-       /* Just free all pages allocated by the pool, and mark the pool
-        * as freed/nonfunctional. All nodes on the list will be reset if
-        * a new pool is initialized using this pool_t *. They become
-        * invalid as soon as pages are freed, since they only consist of
-        * pointers into those pages. Remember that pool pages are tied
-        * up in the list_t via the page_t->poolnode node_t.
-        */
-       for (p = DLIST_TOP(&pool->pages); p != NULL; p = t) {
-           t = DLIST_NEXT(p);
-           pages_free((page_t *)(--p));
-       }
-       for (p = DLIST_TOP(&pool->fpages); p != NULL; p = t) {
-           t = DLIST_NEXT(p);
-           pages_free((page_t *)(--p));
-       }
-       OBJECT_INVALIDATE(pool);
-       ok = TRUE;
-    }
-
-    if (ok)
-       STAT(STAT_POOLS_DESTROYED, 1);
-    else {
-       STAT(STAT_POOLS_DESTROYED_FAILED, 1);
-       DEBUG_PRINTF("* %T pool_destroy(%p)\n", pool);
-    }
-
-    return ok;
-}
-
-
-/* Attempts to allocate a pnode_t from the specified pool_t, and optionally
- * clear the object to 0x00 bytes if zero is TRUE. NULL is returned if
- * no memory was available or if the pool was setup to not be able to hold
- * more objects. The size of the pnode_t prefixed object depends on the
- * attributes which were set forthe pool_t at pool_init(). As each node
- * object should start with a pnode_t structure, we return a pointer to
- * the object structure itself at the same time. The type of memory used
- * can only be the one the pool_t was initialized for. The pnode_t allocation
- * process is efficient, compared to managing page_t. Special care is taken
- * to avoid calling page primitives as much as possible using buffering,
- * while still allowing a pool_t to be dynamically resizing if wanted.
- */
-pnode_t *pool_alloc(pool_t *pool, bool zero)
-{
-    pnode_t *pnode = NULL;
-
-    if (OBJECT_VALID(pool, OBJECT_POOL)) {
-       register pnode_t *pn;
-
-       /* If there are pre-buffered nodes, simply return the first one. */
-       if ((pn = DLIST_TOP(&pool->nodes)) != NULL) {
-           DLIST_UNLINK(&pool->nodes, (node_t *)pn);
-           pn->page->pnodes--;
-           if (zero) {
-               register page_t *p;
-
-               p = pn->page;
-               memclr(pn, pool->nodesize);
-               pn->page = p;
-           }
-           pnode = pn;
-       } else {
-           register page_t *p = NULL;
-           register node_t *n;
-
-           /* No pnode_t left, we need to allocate a new page_t to grow and
-            * initialize the new bnode_t objects. First verify if there is
-            * any available page already in our cache, which pool_free()
-            * maintains using statistics, to minimize calls to page
-            * primitives functions. If there are none, allocate a new page_t.
-            * Remember that we link the pages via the page_t->poolnode node_t.
-            */
-           if (pool->maxpages == 0 ||
-                   DLIST_NODES(&pool->pages) < pool->maxpages) {
-               if ((n = DLIST_TOP(&pool->fpages)) != NULL) {
-                   DLIST_UNLINK(&pool->fpages, n);
-                   p = (page_t *)(--n);
-                   STAT(STAT_PAGES_REUSED, pool->steppages);
-               } else
-                   p = pages_alloc(pool->memtype, pool->steppages, FALSE);
-               if (p != NULL) {
-                   register u_int8_t *ptr, *toptr;
-                   register size_t nodesize = pool->nodesize;
-
-                   p->pnodes = pool->nodesperpage;
-                   p->pool = pool;
-                   DLIST_APPEND(&pool->pages, &p->poolnode);
-                   for (ptr = (u_int8_t *)p->address,
-                           toptr = ptr + _PAGE_SIZE * pool->steppages;
-                           ptr + nodesize < toptr;
-                           ptr += nodesize) {
-                       ((pnode_t *)ptr)->page = p;
-                       DLIST_APPEND(&pool->nodes, (node_t *)ptr);
-                   }
-                   /* Now grab first pnode_t */
-                   pn = DLIST_TOP(&pool->nodes);
-                   DLIST_UNLINK(&pool->nodes, (node_t *)pn);
-                   p->pnodes--;
-                   if (zero)
-                       memclr(pn, nodesize);
-                   pn->page = p;
-                   pnode = pn;
-               }
-           } else {
-               STAT(STAT_POOLS_ALLOC_NOMEM, 1);
-               DEBUG_PRINTF("- %T pool_alloc(%p, %B) - Out of memory\n",
-                       pool, zero);
-           }
-       }
-    } else {
-       STAT(STAT_POOLS_ALLOC_FAILED, 1);
-       DEBUG_PRINTF("* %T pool_alloc(%p, %B)\n", pool, zero);
-    }
-
-    if (pnode != NULL)
-       STAT(STAT_POOLS_ALLOC, 1);
-
-    return pnode;
-}
-
-
-/* Used to free a node previously allocated using pool_alloc().
- * Keeps statistics and a page cache to reduce the frequency at which
- * pages_*() functions need to be called.
- */
-pnode_t *pool_free(pnode_t *pnode)
-{
-    if (pnode != NULL && OBJECT_VALID(pnode->page->pool, OBJECT_POOL)) {
-       register page_t *p = pnode->page;
-       register pool_t *pool = p->pool;
-       register u_int32_t exceeding;
-
-       /* Efficiently return this node in the free list */
-       DLIST_INSERT(&pool->nodes, (node_t *)pnode);
-       p->pnodes++;
-       STAT(STAT_POOLS_FREE, 1);
-       if ((pool->minpages < pool->maxpages) ||
-               (pool->minpages == 0 && pool->maxpages == 0)) {
-           register u_int32_t pages = DLIST_NODES(&pool->pages);
-
-           /* This is a pool_t which can shrink, book-keep statistics on
-            * average pages usage.
-            */
-           pool->avgtotal += pages;
-           pool->avgcnt++;
-           if (pool->avgcnt >
-                   ((pool->steppages * _PAGE_SIZE / pool->nodesize) * 3)) {
-               pool->avgcnt = 1;
-               pool->avgtotal = pages;
-           }
-
-           if (p->pnodes == pool->nodesperpage && pool->minpages < pages) {
-               register u_int8_t *ptr, *toptr;
-               register size_t nodesize;
-
-               /* All pnode_t objects belonging to this page_t were freed.
-                * Swap the page to the cache to be freed. We also need
-                * to sequencially unlink all the pnode_t objects this page
-                * supplied in the free nodes list_t. Remember that pages
-                * are linked via the page_t->poolnode node_t.
-                */
-               for (ptr = (u_int8_t *)p->address,
-                       toptr = ptr + _PAGE_SIZE * pool->steppages,
-                       nodesize = pool->nodesize;
-                       ptr + nodesize < toptr;
-                       ptr += nodesize)
-                   DLIST_UNLINK(&pool->nodes, (node_t *)ptr);
-               /* Insert to preferably reuse recently used pages */
-               DLIST_SWAP(&pool->fpages, &pool->pages, &(p->poolnode), TRUE);
-               STAT(STAT_PAGES_BUFFERED, pool->steppages);
-           }
-
-           /* Do statistics suggest that we should shrink the pool? If so,
-            * free pages from our cache back to the system.
-            */
-           if ((exceeding = (DLIST_NODES(&pool->pages) +
-                           DLIST_NODES(&pool->fpages)) -
-                       (pool->avgtotal / pool->avgcnt)) > 0) {
-               register list_t *fpages = &pool->fpages;
-               register node_t *n;
-
-               /* Preferably free pages which haven't been used recently */
-               for (; exceeding > 0 && (n = fpages->bottom) != NULL;
-                       exceeding--) {
-                   DLIST_UNLINK(fpages, n);
-                   p = (page_t *)(--n);
-                   pages_free(p);
-                   STAT(STAT_PAGES_UNBUFFERED, pool->steppages);
-               }
-           }
-       }
-    } else {
-       STAT(STAT_POOLS_FREE_FAILED, 1);
-       DEBUG_PRINTF("* %T pool_free(%p)\n", pnode);
-    }
-
-    return NULL;
-}
-
-
-/* Finally, the higher-level general purpose allocation system consists of
- * a bunch of pool_t, as well as a page_t list_t for requests which exceed
- * in size and need to be rounded at page boundaries. Memory of all available
- * types may be allocated and freed at will, and of arbitrary sized blocks.
- * The current implementation requires more memory for mpool setup than
- * previously, there however are advantages in versatility, performance
- * and code quality over the latter.
- * We depend on _PAGE_SIZE and _MPOOLS which should be defined by the
- * port-specific code (port/support.h).
- * No special synchronization is performed in these functions, the caller
- * is required to provide it where necessary (i.e. shared mpool_t). However,
- * the underlaying page_t primitives use the system pages pool lock.
- */
-bool mpool_init(mpool_t *mpool)
-{
-    bool ok = FALSE;
-
-    if (mpool != NULL) {
-       register int t, p;
-       register size_t c = _MPOOLSTART;
-
-       DLIST_INIT(&mpool->pages);
-       ok = TRUE;
-       OBJECT_VALIDATE(mpool, OBJECT_MPOOL);
-       for (p = 0; p < _MPOOLS; p++) {
-           for (t = 0; t < (enum _memtypes)_MEM_MAX; t++) {
-               if (!pool_init(&mpool->pools[p][t], _MPOOLSTEP, 0, 0,
-                           sizeof(mnode_t) + c, t))
-                   ok = FALSE;
-               else
-                   mpool->pools[p][t].mpool = mpool;
-           }
-           c *= 2;
-       }
-       if (!ok) {
-           /* Make sure to free everything if part of the system only could be
-            * setup
-            */
-           mpool_destroy(mpool);
-       } else {
-           mpool->shared = FALSE;
-           _lock_init(&mpool->lock);
-           mpool->usecount = 0;
-       }
-    }
-
-    if (ok)
-       STAT(STAT_MPOOLS_CREATED, 1);
-    else {
-       STAT(STAT_MPOOLS_CREATED_FAILED, 1);
-       DEBUG_PRINTF("* %T mpool_init(%p)\n", mpool);
-    }
-
-    return ok;
-}
-
-
-bool mpool_destroy(mpool_t *mpool)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(mpool, OBJECT_MPOOL)) {
-       register int t, p;
-       register node_t *pg, *tmp;
-       register u_int32_t usecount = 0;
-
-       if (mpool->shared) {
-           lock_acquire(&mpool->lock);
-           usecount = --mpool->usecount;
-           _lock_release(&mpool->lock);
-       }
-       if (usecount < 1) {
-           /* All your pool_t are belong to us. */
-           for (p = 0; p < _MPOOLS; p++)
-               for (t = 0; t < (enum _memtypes)_MEM_MAX; t++)
-                   pool_destroy(&mpool->pools[p][t]);
-           /* And rounded page requests too. Remember that they are tied via
-            * the page_t->poolnode node_t in our list_t.
-            */
-           for (pg = DLIST_TOP(&mpool->pages); pg != NULL; pg = tmp) {
-               tmp = DLIST_NEXT(pg);
-               pages_free((page_t *)(--pg));
-           }
-           OBJECT_INVALIDATE(mpool);
-           ok = TRUE;
-           STAT(STAT_MPOOLS_DESTROYED, 1);
-       }
-    } else {
-       STAT(STAT_MPOOLS_DESTROYED_FAILED, 1);
-       DEBUG_PRINTF("* %T mpool_destroy(%p)\n", mpool);
-    }
-
-    return ok;
-}
-
-
-/* malloc() clone which can be specified mpool_t to use, memory type
- * and optional memory clear flag.
- */
-void *_malloc(mpool_t *mpool, int memtype, size_t size, bool zero)
-{
-    void *mem = NULL;
-
-    if (OBJECT_VALID(mpool, OBJECT_MPOOL) &&
-           (memtype == _MEM_ANY || memtype < (enum _memtypes)_MEM_MAX)) {
-       register int p;
-       register size_t rsize;
-
-       /* Synchronization for cases where multiple tasks share an mpool_t */
-       if (mpool->shared)
-           lock_acquire(&mpool->lock);
-
-       /* Verify if any of our pool_t can serve the requested size */
-       rsize = (size_t)OALIGN_CEIL(sizeof(mnode_t), u_int32_t);
-       rsize += size;
-       for (p = 0; p < _MPOOLS; p++) {
-           if (mpool->pools[p][0].nodesize >= rsize) {
-               register mnode_t *n = NULL;
-
-               /* This pool can serve this request. */
-               if (memtype == _MEM_ANY) {
-                   register int t;
-
-                   /* Try available memory types in order */
-                   for (t = 0; t < (enum _memtypes)_MEM_MAX; t++) {
-                       n = (mnode_t *)pool_alloc(&mpool->pools[p][t], zero);
-                       if (n != NULL)
-                           break;
-                   }
-               } else
-                   n = (mnode_t *)pool_alloc(&mpool->pools[p][memtype], zero);
-               if (n != NULL) {
-                   /* Best case, everything went fine */
-                   n->type = MNT_PNODE;
-                   OBJECT_VALIDATE(n, OBJECT_MNODE);
-                   mem = (++n);
-                   break;
-               } else {
-                   STAT(STAT_MPOOLS_ALLOC_NOMEM, 1);
-                   DEBUG_PRINTF(
-                           "- %T _malloc(%p, %d, %u, %B) - Out of memory\n",
-                           mpool, memtype, size, zero);
-               }
-           }
-       }
-       if (p == _MPOOLS) {
-           register u_int32_t many;
-           register page_t *p;
-
-           /* We need to round size on page boundaries and allocate pages.
-            * If we were requested zeroed memory, the pageclr() will be used
-            * internally which is more efficient than memclr().
-            */
-           many = rsize / _PAGE_SIZE;
-           if (rsize % _PAGE_SIZE)
-               many++;
-           if ((p = pages_alloc(memtype, many, zero)) != NULL) {
-               register mnode_t *n = p->address;
-
-               /* Link in our pages list via the page_t->poolnode node_t */
-               DLIST_APPEND(&mpool->pages, &p->poolnode);
-               n->u.pgnode.pages = p;
-               n->u.pgnode.mpool = mpool;
-               n->type = MNT_PAGES;
-               OBJECT_VALIDATE(n, OBJECT_MNODE);
-               mem = (++n);
-           } else {
-               STAT(STAT_MPOOLS_ALLOC_NOMEM, 1);
-               DEBUG_PRINTF("- %T _malloc(%p, %d, %u, %B) - Out of memory\n",
-                       mpool, memtype, size, zero);
-           }
-       }
-
-       if (mpool->shared)
-           _lock_release(&mpool->lock);
-    } else {
-       STAT(STAT_MPOOLS_ALLOC_FAILED, 1);
-       DEBUG_PRINTF("* %T _malloc(%p, %d, %u, %B)\n",
-               mpool, memtype, size, zero);
-    }
-
-    if (mem != NULL)
-       STAT(STAT_MPOOLS_ALLOC, 1);
-
-    return mem;
-}
-
-
-/* free() clone for _malloc() */
-void *_free(void *block)
-{
-    register mpool_t *mpool = NULL;
-
-    if (block != NULL) {
-       register mnode_t *mn = block;
-
-       mn--;
-       if (OBJECT_VALID(mn, OBJECT_MNODE)) {
-
-           OBJECT_INVALIDATE(mn);
-           switch (mn->type) {
-           case MNT_PNODE:
-               /* A pool_t pnode_t which needs to be freed back. Track our
-                * mpool_t for synchronization if required.
-                */
-               if ((mpool = mn->u.pnode.page->pool->mpool) != NULL) {
-                   if (mpool->shared)
-                       lock_acquire(&mpool->lock);
-                   else
-                       mpool = NULL;
-               }
-               pool_free((pnode_t *)mn);
-               break;
-           case MNT_PAGES:
-               {
-                   register page_t *p = mn->u.pgnode.pages;
-
-                   /* A page_t which needs to be unlinked and freed.
-                    * Remember that pages are linked via page_t->poolnode
-                    * node_t. Track our mpool_t for synchronization if needed.
-                    */
-                   mpool = mn->u.pgnode.mpool;
-                   if (mpool->shared)
-                       lock_acquire(&mpool->lock);
-                   else
-                       mpool = NULL;
-                   DLIST_UNLINK(&mn->u.pgnode.mpool->pages, &p->poolnode);
-                   pages_free(p);
-                   break;
-               }
-           }
-           STAT(STAT_MPOOLS_FREE, 1);
-       } else {
-           STAT(STAT_MPOOLS_FREE_FAILED, 1);
-           DEBUG_PRINTF("* %T _free(%p)\n", block);
-       }
-    } else {
-       STAT(STAT_MPOOLS_FREE_FAILED, 1);
-       DEBUG_PRINTF("* %T _free(%p)\n", block);
-    }
-    if (mpool != NULL)
-       _lock_release(&mpool->lock);
-
-    return NULL;
-}
-
-
-
-/* This function initializes the various pool_t and _lock_t which are reserved
- * to allocate specific types of Xisop system objects for efficiency.
- */
-void spools_init(void)
-{
-    register int i;
-
-    /* XXX Should panic on failure */
-    for (i = 0; i < (enum _syspools)POOL_MAX; i++) {
-       _lock_init(&root->spools_locks[i]);
-       (void) pool_init(&root->spools[i], syspools_params[i].steppages,
-                        syspools_params[i].minpages,
-                        syspools_params[i].maxpages,
-                        syspools_params[i].nodesize, 0);
-    }
-}
-
-
-pnode_t *spool_alloc(u_int32_t pool)
-{
-    pnode_t *node = NULL;
-
-    if (pool < (enum _syspools)POOL_MAX) {
-       lock_acquire(&root->spools_locks[pool]);
-       node = pool_alloc(&root->spools[pool], FALSE);
-       _lock_release(&root->spools_locks[pool]);
-    }
-
-    if (node == NULL)
-       DEBUG_PRINTF("* %T spool_alloc(%u)\n", pool);
-
-    return node;
-}
-
-
-pnode_t *spool_free(u_int32_t pool, pnode_t *node)
-{
-    if (pool < (enum _syspools)POOL_MAX) {
-       lock_acquire(&root->spools_locks[pool]);
-       if (!pool_free(node))
-           DEBUG_PRINTF("* %T spool_free(%u, %p)\n", pool, node);
-       _lock_release(&root->spools_locks[pool]);
-    }
-
-    return NULL;
-}
-
-
-/* Specifically made to allocate general purpose memory for the kernel.
- * Although mpool_t now can support synchronization itself when shared,
- * it is faster to perform it unconditionally.
- */
-void *_kmalloc(int memtype, size_t size, bool zero)
-{
-    void *mem = NULL;
-
-    lock_acquire(&root->kernpool_lock);
-    mem = _malloc(root->kernpool, memtype, size, zero);
-    _lock_release(&root->kernpool_lock);
-
-    return mem;
-}
-
-void *_kfree(void *mem)
-{
-    lock_acquire(&root->kernpool_lock);
-    _free(mem);
-    _lock_release(&root->kernpool_lock);
-
-    return NULL;
-}
-
-
-/* Closer to ANSI-C but still for general purpose kernel memory */
-void *kmalloc(size_t size)
-{
-    return MALLOC(size);
-}
-
-void kfree(void *mem)
-{
-    FREE(mem);
-}
-
-
-/* These functions are ANSI-C standard, and only use the current task pool. */
-
-void *malloc(size_t size)
-{
-    return _malloc(CURTASK()->mpool, _MEM_ANY, size, FALSE);
-}
-
-void *calloc(int number, size_t size)
-{
-    return _malloc(CURTASK()->mpool, _MEM_ANY, number * size, TRUE);
-}
-
-void *realloc(void *ptr, size_t size)
-{
-    register void *nptr = ptr;
-
-    /* Not very efficient, but mostly provided for compatibility. */
-    if (nptr != NULL) {
-       if (size == 0)
-           /* Basically a request to free the buffer */
-           nptr = _free(nptr);
-       else {
-           register mnode_t *mnode;
-
-           /* Climb up to obtain actual buffer size */
-           mnode = (mnode_t *)nptr;
-           mnode--;
-           if (OBJECT_VALID(mnode, OBJECT_MNODE)) {
-               register size_t osize;
-
-               switch (mnode->type) {
-               case MNT_PNODE:
-                   {
-                       osize = mnode->u.pnode.page->pool->nodesize -
-                           sizeof(mnode_t);
-                       break;
-                   }
-               case MNT_PAGES:
-                   {
-                       register page_t *pages = mnode->u.pgnode.pages;
-
-                       osize = ((pages->last->id - pages->id) +1) *
-                           _PAGE_SIZE;
-                       break;
-                   }
-               default:
-                   nptr = NULL;
-                   osize = 0;
-                   break;
-               }
-
-               /* Is the requested size larger than the currently available
-                * number of bytes? If not, don't do anything, return the
-                * current buffer pointer.
-                */
-               if (nptr != NULL && osize < size) {
-                   /* Allocate a buffer which can at least hold the requested
-                    * number of bytes. Well at least, attempt to. If we can't
-                    * don't do anything and return NULL.
-                    */
-                   if ((nptr = malloc(size)) != NULL) {
-                       /* Allocation successful, copy all previous buffer
-                        * contents to the new one, then free the old buffer,
-                        * and return the new buffer pointer.
-                        */
-                       memcpy(nptr, ptr, osize);
-                       free(ptr);
-                   }
-               }
-           } else
-               nptr = NULL;
-       }
-    } else
-       /* A request to simply allocate */
-       nptr = malloc(size);
-
-    return nptr;
-}
-
-void free(void *ptr)
-{
-    _free(ptr);
-}
-
-
-/* Xisop extentions as we support multiple memory types */
-void *tmalloc(int memtype, size_t size)
-{
-    return _malloc(CURTASK()->mpool, memtype, size, FALSE);
-}
-
-void *tcmalloc(int memtype, int number, size_t size)
-{
-    return _malloc(CURTASK()->mpool, memtype, number * size, TRUE);
-}
-
-
-
-/* The following code is only compiled in if DEBUG was #defined in config.h */
-#ifdef DEBUG
-
-
-/* Dump the current state of all memory pages in the system. */
-void pages_dump(void)
-{
-    register u_int32_t ppool;
-    _ipl_t x;
-
-    /* Become absolutely uninterruptible */
-    x = _splhigh();
-
-    debug_printf("\nCURRENT STATE OF SYSTEM MEMORY PAGES\n");
-    for (ppool = 0; ppool < (enum _memtypes)_MEM_MAX; ppool++) {
-       register mchunk_t *mchunk;
-
-       debug_printf("\nDumping mchunks for ppool_t of _MEM_TYPE %u\n",
-               ppool);
-       DLIST_FOREACH(&(root->ppools[ppool].mchunks), mchunk) {
-           register page_t **index = mchunk->index;
-           register u_int32_t id, pages = mchunk->pages;
-
-           debug_printf(
-               " Dumping pages for mchunk_t *%p (%u pages, page_t **%p)\n",
-                   mchunk, pages, index);
-           debug_printf(" mchunk->free.top = ");
-           if (mchunk->free.top != NULL)
-               debug_printf(
-                       "%u (page_t *%p)\n", ((page_t *)mchunk->free.top)->id,
-                       mchunk->free.top);
-           else
-               debug_printf("NULL\n");
-           debug_printf(" mchunk->free.bottom = ");
-           if (mchunk->free.bottom != NULL)
-               debug_printf("%u (page_t *%p)\n",
-                       ((page_t *)mchunk->free.bottom)->id,
-                       mchunk->free.bottom);
-           else
-               debug_printf("NULL\n");
-           for (id = 0; id < pages; id++) {
-               register page_t *page = index[id];
-
-               /* Print summary information */
-               debug_printf(" - %u (page_t *%p, void *%p)\n   next = ",
-                       id, page, page->address);
-               if (page->node.next == NULL)
-                   debug_printf("NULL, prev = ");
-               else
-                   debug_printf("%u (page_t *%p), prev = ",
-                           ((page_t *)page->node.next)->id,
-                           page->node.next);
-               if (page->node.prev == NULL)
-                   debug_printf("NULL\n");
-               else
-                   debug_printf("%u (page_t *%p)\n",
-                           ((page_t *)page->node.prev)->id,
-                           page->node.prev);
-
-               /* Rest will vary depending if page is allocated */
-               if(page->state == PS_ALLOCATED) {
-                   debug_printf("   Allocated, last = ");
-                   if (page->last != NULL)
-                       debug_printf("%u (page_t *%p)\n", page->last->id,
-                               page->last);
-                   else
-                       debug_printf("NULL\n");
-                   if (page->pool != NULL)
-                       debug_printf("   pool_t = *%p, mem %d, nodesize %u\n",
-                               page->pool, page->pool->memtype,
-                               page->pool->nodesize);
-               } else
-                   debug_printf("   Free\n");
-
-               /* Perform some basic sanity checking and report problems
-                * which are known to disrupt the system. If those occur,
-                * the pools were corrupted and the system may need a reset
-                * for proper operation.
-                */
-               if (page->node.next != NULL) {
-                   register node_t *n = page->node.next;
-
-                   if (n->prev == NULL)
-                       debug_printf(
-                               "   * page->node.next->node.prev = NULL\n");
-                   else if (n->prev != &page->node)
-                       debug_printf(
-                               "   * page->node.next->node.prev != page\n");
-               }
-               if (page->node.prev != NULL) {
-                   register node_t *n = page->node.prev;
-
-                   if (n->next == NULL)
-                       debug_printf(
-                               "   * page->node.prev->node.next = NULL\n");
-                   else if (n->next != &page->node)
-                       debug_printf(
-                               "   * page->node.prev->node.next != page\n");
-               }
-               if (page->id != id)
-                   debug_printf("   * page->id != index[id]\n");
-               if (page->state != PS_FREE && page->state != PS_ALLOCATED)
-                   debug_printf("   * Unknown page->state\n");
-               if (page->state == PS_FREE && page->last != NULL)
-                   debug_printf("   * PS_FREE && last != NULL\n");
-               if (page->state == PS_FREE && page->pool != NULL)
-                   debug_printf("   * PS_FREE && page->pool != NULL");
-               if (page->mchunk != mchunk)
-                   debug_printf("   * page->mchunk != mchunk\n");
-           }
-       }
-    }
-
-    _splx(x);
-}
-
-
-#endif
diff --git a/Xisop/src/common/kernel/memory.h b/Xisop/src/common/kernel/memory.h
deleted file mode 100644 (file)
index 146d7b8..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/* $Id: memory.h,v 1.4 2004/06/04 03:09:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_MEMORY_H
-#define KERNEL_MEMORY_H
-
-
-
-#include <common/types.h>
-#include <common/kernlib/list.h>
-#include <processor/support.h>
-#include <port/support.h>
-
-
-
-/* Only common memory type which is always available */
-#define _MEM_ANY               -1
-
-/* Page state */
-#define PS_FREE                        0
-#define PS_ALLOCATED           1
-
-/* mnode_t types */
-#define MNT_PNODE              0
-#define MNT_PAGES              1
-
-
-
-/* This is a memory page node. One is required for each physical page which
- * is to be included in the memory management system. The pool_t related
- * fields seem to pollute the page space, but there is no better place to put
- * them; Using an additional page_t based structure for pool_t page_t nodes
- * would require allocating more memory. The pool_t primitives are such a
- * vital element to Xisop that we can add support for it inherently.
- */
-struct page {
-    node_t node;       /* Link to pages_free of mchunk or pages_t */
-    node_t poolnode;   /* Used for pool_t page linking */
-    mchunk_t *mchunk;  /* mchunk_t we belong to for freeing */
-    void *address;     /* Page address in memory (should be 32-bit aligned) */
-    page_t *last;      /* Allocated? Link to last contiguous node, or NULL */
-    pool_t *pool;      /* If part of a pool_t, pointer to the pool_t */
-    u_int32_t id;      /* Page index offset in mchunk_t */
-    u_int32_t pnodes;  /* Number of free blocks in this page_t for pool_t */
-    u_int32_t state;   /* PS_FREE | PS_ALLOCATED */
-};
-
-/* A chunk of memory consists of an arbitrary amount of contiguous pages
- * of physical memory. This construct allows to dynamically append memory
- * which can be mapped anytime, i.e. PCMCIA memory which just was inserted.
- * Obviously, to add new memory some memory is required to be setup for the
- * lists, index and page nodes. This memory should never be freed back unless
- * it is certain that the device was detached, and all allocated memory on it
- * is to be discarded. Each such chunk will be scanned in order for available
- * memory when memory is to be allocated from a ppool_t.
- */
-struct mchunk {
-    node_t node;       /* Link to mpool_t */
-    list_t free;       /* List of free pages */
-    ppool_t *ppool;    /* Link to ppool_t we belong to */
-    page_t **index;    /* Index of all pages in this mchunk_t */
-    u_int32_t pages;   /* Number of pages in this mchunk_t */
-    u_int32_t object_magic;    /* Validity sceal */
-};
-
-/* A pool of pages, there is one such pool per memory type. These are
- * initialized by the port-specific _init_memory() function.
- */
-struct ppool {
-    _lock_t lock;      /* Secure exclusive access lock */
-    list_t mchunks;    /* List of mchunk_t objects */
-};
-
-
-
-/* A pool used to allocate objects of a fixed size, which are smaller than
- * half a page. maxpages permits to restrict the pool from growing more than
- * wanted, minpages specifies the minimum number of pages which should always
- * remain allocated (and setup as objects), avgtotal and avgcnt are used for
- * statistics when freeing pages (and destroying their objects). An unused
- * page is moved to fpages list, and moved back in pages list when an object
- * on the page is used. If statistics show that the pool should shrink, pages
- * from fpages are freed back to the system (unless minpages is reached).
- * steppages specify how many pages to allocate and free at once. A page size
- * for the pool consists of steppages * _PAGE_SIZE. All pool objects always
- * start by a node_t, used for internal linking when freed, and can be used
- * for custom linking after allocation until freed back.
- */
-struct pool {
-    u_int32_t steppages, minpages,     /* Size requirements */
-       maxpages;
-    u_int32_t avgtotal, avgcnt;                /* Statistics for page_t cache */
-    u_int32_t nodesperpage;            /* Number of pnode_t per page_t */
-    size_t nodesize;                   /* 32-bit aligned size of pnode_t */
-    list_t pages, fpages,              /* Allocated and cached page_t's */
-       nodes;                          /* Ready free pnode_t's */
-    int memtype;                       /* Memory type to allocate */
-    u_int32_t object_magic;            /* Validity sceal */
-    mpool_t *mpool;                    /* mpool_t we belong to (or NULL) */
-};
-
-/* A pool_t node */
-struct pnode {
-    node_t node;               /* pool_t->nodes or user list_t linking */
-    page_t *page;              /* page_t this pnode_t belongs to */
-};
-
-
-
-/* And finally, the general purpose memory management functions, allowing
- * blocks of memory of arbitrary size and type to be allocated and freed back,
- * internally based upon the pool_t system.
- */
-struct mpool {
-    /* All required pool_t for the various memory types and request sizes */
-    pool_t pools[_MPOOLS][(enum _memtypes)_MEM_MAX];
-    list_t pages;              /* Large requests rounded on page boundaries */
-    u_int32_t object_magic;    /* Validity sceal */
-    /* These are used in the case where several tasks share a common mpool_t,
-     * In which case the mpool_t is synchronized and only destroyed when no
-     * more tasks are using it. Because Xisop does not support MMU the
-     * requirement for this is questionable. Especially that through the
-     * message passing system tasks can easily synchronize on wanted shared
-     * memory regions. It can however save some memory on very small systems.
-     * All tasks could potentially share the same mpool_t if the init task
-     * was setup to do so, for instance.
-     */
-    bool shared;
-    _lock_t lock;
-    u_int32_t usecount;
-};
-
-/* An mpool_t node, which prefixes all allocated blocks, the ones from pools
- * as well as the ones made of rounded pages (which were too large to satisfy
- * using the pool_t objects). Contrary to pool_*() and pages_*() functions, the
- * mnode_t is abstracted and hidden in the supplied data block. The pointer
- * supplied to the caller points immediately after this structure
- * (32-bit aligned). We use a union to reduce as much as possible the size
- * of the structure, and be able to reference back to both pnode_t or
- * page_t + mpool_t objects.
- */
-struct mnode {
-    union {
-       pnode_t pnode;          /* We're a pnode_t */
-       struct {
-           page_t *pages;      /* We're a page_t from mpool_t */
-           mpool_t *mpool;
-       } pgnode;
-    } u;
-    int type;                  /* MNT_PAGES || MNT_PNODE */
-    u_int32_t object_magic;    /* Validity sceal */
-};
-
-
-
-/* The pool_t types Xisop initializes for efficient management of common
- * system objects. These should correspond to the osize structure defined in
- * memory.c's spools_init() function.
- */
-enum _syspools {
-    POOL_TASK = 0,
-    POOL_PORT,
-    POOL_DEVICENODE,
-    POOL_DEVICEHANDLE,
-    POOL_MPOOL,
-    POOL_MAX
-};
-
-/* An array of these is filled in memory.c for pools initialization */
-struct syspools_params {
-    const char *label;
-    u_int32_t steppages, minpages, maxpages;
-    size_t nodesize;
-};
-
-
-
-/* Useful macros intended to be used by kernel code */
-#define TMALLOC(t, s)          _kmalloc((t), (s), FALSE)
-#define TCMALLOC(t, n, s)      _kmalloc((t), (n) * (s), TRUE)
-#define MALLOC(s)              _kmalloc(_MEM_ANY, (s), FALSE)
-#define CMALLOC(n, s)          _kmalloc(_MEM_ANY, (n) * (s), TRUE)
-#define FREE(p)                        _kfree((p))
-
-
-
-void memory_init(void);
-
-void spools_init(void);
-pnode_t *spool_alloc(u_int32_t);
-pnode_t *spool_free(u_int32_t, pnode_t *);
-
-mchunk_t *mchunk_init(void *, size_t);
-bool mchunk_attach(int, mchunk_t *);
-bool mchunk_detach(int, mchunk_t *);
-
-page_t *pages_alloc(int, u_int32_t, bool);
-bool pages_free(page_t *);
-
-bool pool_init(pool_t *, u_int32_t, u_int32_t, u_int32_t, size_t, int);
-bool pool_destroy(pool_t *);
-pnode_t *pool_alloc(pool_t *, bool);
-pnode_t *pool_free(pnode_t *);
-
-bool mpool_init(mpool_t *);
-bool mpool_destroy(mpool_t *);
-void *_malloc(mpool_t *, int, size_t, bool);
-void *_free(void *);
-#define mpool_alloc _malloc
-#define mpool_free _free
-
-void *_kmalloc(int, size_t, bool);
-void *_kfree(void *);
-void *kmalloc(size_t);
-void kfree(void *);
-
-void *malloc(size_t);
-void *calloc(int, size_t);
-void *realloc(void *, size_t);
-void free(void *);
-void *tmalloc(int, size_t);
-void *tcmalloc(int, int, size_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/object.h b/Xisop/src/common/kernel/object.h
deleted file mode 100644 (file)
index f9a3e23..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* $Id: object.h,v 1.4 2004/06/04 19:03:36 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* For a good example of code which uses these, look at port.c's port_create(),
- * port_reply() and port_destroy() functions.
- */
-
-
-
-#ifndef COMMON_KERNEL_OBJECT_H
-#define COMMON_KERNEL_OBJECT_H
-
-
-
-#include <common/kernel/main.h>
-
-
-
-/* These should be unique and quite uncommon to happen randomly */
-#define OBJECT_PORT            0x504f5254      /* PORT */
-#define        OBJECT_TASK             0x5441534b      /* TASK */
-#define OBJECT_POOL            0x504f4f4c      /* POOL */
-#define OBJECT_MPOOL           0x4d504f4c      /* MPOL */
-#define OBJECT_MNODE           0x4d4e4f44      /* MNOD */
-#define OBJECT_MCHUNK          0x4d43484b      /* MCHK */
-#define OBJECT_DEVICEHANDLE    0x44455648      /* DEVH */
-#define OBJECT_DEVICENODE      0x4445564e      /* DEVN */
-#define OBJECT_IOREQUEST       0x494f5251      /* IORQ */
-#define OBJECT_HASHTABLE       0x4854424c      /* HTBL */
-#define OBJECT_HASHNODE                0x484e4f44      /* HNOD */
-
-
-
-/* Validate an object */
-#define OBJECT_VALIDATE(o, m)  (o)->object_magic = (m)
-/* Invalidate an object */
-#define OBJECT_INVALIDATE(o)   (o)->object_magic = 0
-/* Register an object which others could depend on */
-#define OBJECT_REGISTER(o)     (o)->object_id = unique_id()
-/* Register a dependancy for the object */
-#define OBJECT_SETDEP(o, r)    do { \
-    (o)->objdep_id = (r)->object_id; \
-    (o)->objdep_magic = (r)->object_magic; \
-} while (/* CONSTCOND */0)
-
-/* Returns TRUE if the object is valid and of expected type, FALSE if not */
-#define OBJECT_VALID(o, m)     ((o) != NULL && (o)->object_magic == (m))
-/* Returns TRUE if the object's dependancy matches with (d) */
-#define OBJECT_DEPENDS(o, d)   ((d) != NULL && \
-       (d)->object_magic == (o)->objdep_magic && \
-       (d)->object_id == (o)->objdep_id)
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/port.c b/Xisop/src/common/kernel/port.c
deleted file mode 100644 (file)
index 8e17e36..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $Id: port.c,v 1.7 2004/10/14 15:05:23 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-#include <common/kernel/port.h>
-#include <common/kernel/main.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/object.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernlib/hash.h>
-#include <common/kernlib/string.h>
-
-
-
-port_t *port_create(const char *name)
-{
-    bstr_t *bstr = NULL;
-    signum_t signum;
-
-    if (name != NULL) {
-       if ((bstr = bstr_new(name, 32, FALSE)) == NULL) {
-           STAT(STAT_PORTS_CREATED_NOMEM, 1);
-           DEBUG_PRINTF("* %T port_create(%p) - Out of memory\n", name);
-       } else {
-           SYSTABLE_RLOCK(SYSTABLE_PUBLICPORTS);
-           if ((hashtable_lookup(SYSTABLE(SYSTABLE_PUBLICPORTS), bstr->data,
-                           bstr->len)) != NULL) {
-               SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-               STAT(STAT_PORTS_CREATED_EXISTS, 1);
-               DEBUG_PRINTF("* %T port_create(%p) - Port exists (%s)\n",
-                       bstr->data);
-               bstr = bstr_free(bstr);
-           }
-       }
-    }
-    if (name == NULL || bstr != NULL) {
-       if ((signum = signal_alloc()) != -1) {
-           register task_t *task = CURTASK();
-           register port_t *port = NULL;
-
-           if ((port = (port_t *)spool_alloc(POOL_PORT)) != NULL) {
-               /* Validate object, and register it since message_t depends on
-                * us for reply-port validation
-                */
-               OBJECT_VALIDATE(port, OBJECT_PORT);
-               OBJECT_REGISTER(port);
-               /* Initialize other port_t fields */
-               port->sigtask = task;
-               port->signum = signum;
-               DLIST_INIT(&port->messages);
-               port->name = bstr;
-               if (bstr != NULL) {
-                   /* Public port, link via sysnode */
-                   SYSTABLE_UPGRADE(SYSTABLE_PUBLICPORTS);
-                   (void) hashtable_link(SYSTABLE(SYSTABLE_PUBLICPORTS),
-                                         (hashnode_t *)port, bstr->data,
-                                         bstr->len, FALSE);
-                   SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-               }
-               /* Register task resource */
-               SCHED_DISABLE();
-               DLIST_APPEND(&task->resources.ports, &port->tasknode);
-               SCHED_ENABLE();
-               STAT(STAT_PORTS_CREATED, 1);
-
-               return port;
-           } else {
-               if (bstr != NULL)
-                   SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-               STAT(STAT_PORTS_CREATED_NOMEM, 1);
-               DEBUG_PRINTF("* %T port_create(%p) - Out of memory\n", name);
-           }
-           signal_free(SIGMASK(signum));
-       } else {
-           if (bstr != NULL)
-               SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-           STAT(STAT_PORTS_CREATED_NOSIG, 1);
-           DEBUG_PRINTF("* %T port_create(%p) - Out of signals\n", name);
-       }
-    }
-
-    if (bstr != NULL)
-       bstr_free(bstr);
-
-    return NULL;
-}
-
-
-/* Can destroy a port of any task. */
-port_t *port_destroy(port_t *port)
-{
-    if (OBJECT_VALID(port, OBJECT_PORT)) {
-       register task_t *task = port->sigtask;
-
-       SCHED_DISABLE();
-       OBJECT_INVALIDATE(port);
-       _signal_free(task, PORT_SIGMASK(port));
-       /* Unlink task resource, linked via tasknode */
-       DLIST_UNLINK(&task->resources.ports, &port->tasknode);
-       SCHED_ENABLE();
-       if (port->name != NULL) {
-           bstr_free(port->name);
-           /* Unlink system resource, linked via sysnode */
-           SYSTABLE_WLOCK(SYSTABLE_PUBLICPORTS);
-           hashtable_unlink(SYSTABLE(SYSTABLE_PUBLICPORTS),
-                   (hashnode_t *)port);
-           SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-       }
-       spool_free(POOL_PORT, (pnode_t *)port);
-       STAT(STAT_PORTS_DESTROYED, 1);
-    } else {
-       STAT(STAT_PORTS_DESTROYED_FAILED, 1);
-       DEBUG_PRINTF("* %T port_destroy(%p)\n", port);
-    }
-
-    return NULL;
-}
-
-
-port_t *port_find(const char *name)
-{
-    register port_t *port = NULL;
-
-    if (name != NULL) {
-       SYSTABLE_RLOCK(SYSTABLE_PUBLICPORTS);
-       port = (port_t *)hashtable_lookup(SYSTABLE(SYSTABLE_PUBLICPORTS),
-               name, strnlen(name, 32));
-       SYSTABLE_UNLOCK(SYSTABLE_PUBLICPORTS);
-    }
-
-    if (port != NULL)
-       STAT(STAT_PORTS_FIND_FOUND, 1);
-    else
-       STAT(STAT_PORTS_FIND_NOTFOUND, 1);
-
-    return port;
-}
-
-
-bool port_send(port_t *port, port_t *replyport, message_t *msg)
-{
-    bool ok = FALSE;
-    message_t *tmsg;
-
-    if (OBJECT_VALID(port, OBJECT_PORT) && msg != NULL) {
-       ok = TRUE;
-       if (replyport != NULL) {
-           if (OBJECT_VALID(replyport, OBJECT_PORT)) {
-               msg->replyport = replyport;
-               OBJECT_SETDEP(msg, replyport);
-           } else
-               ok = FALSE;
-       } else
-           msg->replyport = NULL;
-       /* Queue message */
-       SCHED_DISABLE();
-       tmsg = DLIST_TOP(&port->messages);
-       DLIST_APPEND(&port->messages, (node_t *)msg);
-       SCHED_ENABLE();
-       /* Notify that a message arrived, but only if the port was previously
-        * empty.
-        */
-       if (tmsg == NULL)
-           signal_send(port->sigtask, PORT_SIGMASK(port));
-    }
-
-    if (ok)
-       STAT(STAT_PORTS_SEND, 1);
-    else {
-       STAT(STAT_PORTS_SEND_FAILED, 1);
-       DEBUG_PRINTF("* %T port_send(%p, %p, %p)\n", port, replyport, msg);
-    }
-
-    return ok;
-}
-
-
-message_t *port_get(port_t *port)
-{
-    register message_t *msg = NULL;
-
-    if (OBJECT_VALID(port, OBJECT_PORT)) {
-       SCHED_DISABLE();
-       if ((msg = DLIST_TOP(&port->messages)) != NULL)
-           DLIST_UNLINK(&port->messages, (node_t *)msg);
-       SCHED_ENABLE();
-    } else {
-       STAT(STAT_PORTS_GET_FAILED, 1);
-       DEBUG_PRINTF("* %T port_get(%p)\n", port);
-    }
-
-    if (msg != NULL)
-       STAT(STAT_PORTS_GET, 1);
-
-    return msg;
-}
-
-
-bool port_reply(message_t *msg)
-{
-    bool ok = FALSE;
-
-    if (msg != NULL && OBJECT_DEPENDS(msg, msg->replyport)) 
-       ok = port_send(msg->replyport, NULL, msg);
-
-    if (ok)
-       STAT(STAT_PORTS_REPLY, 1);
-    else {
-       STAT(STAT_PORTS_REPLY_FAILED, 1);
-       DEBUG_PRINTF("* %T port_reply(%p)\n", msg);
-    }
-
-    return ok;
-}
-
-
-/* Somewhat like poll(), but returns the port which caused the awakening.
- * The task argument is optional, and specifies a prefered task to run next,
- * or NULL. Note that a task can only wait for messages on it's own ports.
- */
-port_t *port_wait(port_t **ports, u_int32_t num, task_t *yield)
-{
-    register port_t *port = NULL;
-
-    if (ports != NULL && num > 0) {
-       register sigmask_t sigmask = 0;
-       register u_int32_t i;
-
-       SCHED_DISABLE();
-       /* By definition, a port has a tied signal. Form the sigmask. */
-       for (i = 0; i < num; i++) {
-           register port_t *p = ports[i];
-
-           if (OBJECT_VALID(p, OBJECT_PORT)) {
-               sigmask |= PORT_SIGMASK(p);
-               if (DLIST_TOP(&p->messages) != NULL) {
-                   port = p;
-                   break;
-               }
-           }
-       }
-       SCHED_ENABLE();
-       /* Only wait if all ports were empty */
-       if (port == NULL) {
-           STAT(STAT_PORTS_WAIT, 1);
-           sigmask = signal_wait(sigmask, yield);
-           STAT(STAT_PORTS_WAIT_RETURNED_SLEEP, 1);
-           SCHED_DISABLE();
-           for (i = 0; i < num; i++) {
-               register port_t *p = ports[i];
-
-               if (OBJECT_VALID(p, OBJECT_PORT) &&
-                       (sigmask & PORT_SIGMASK(p))) {
-                   port = p;
-                   break;
-               }
-           }
-           /* A big problem! We awaken, but not as the result of one of the
-            * port signals. When such a thing can occur, the task should
-            * use signal_wait() and manually include in the mask the wanted
-            * port signals, not port_wait(). We'll return NULL of course.
-            */
-           if (i == num) {
-               STAT(STAT_PORTS_WAIT_RETURNED_NOSIG, 1);
-               DEBUG_PRINTF(
-                       "- %T port_wait(%p, %u, %p) - Unexpected signal\n",
-                       ports, num, yield);
-           }
-           SCHED_ENABLE();
-       } else
-           STAT(STAT_PORTS_WAIT_RETURNED_IMMEDIATE, 1);
-    } else {
-       STAT(STAT_PORTS_WAIT_FAILED, 1);
-       DEBUG_PRINTF("* %T port_wait(%p, %u, %p)\n", ports, num, yield);
-    }
-
-    return port;
-}
-
-
-/* Unlinks all currently queued messages (if any) from the supplied port_t.
- * Should normally be performed on the tasks of the caller process only.
- */
-bool port_flush(port_t *port)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(port, OBJECT_PORT)) {
-       ok = TRUE;
-       SCHED_DISABLE();
-       if (DLIST_TOP(&port->messages) != NULL)
-           DLIST_INIT(&port->messages);
-       SCHED_ENABLE();
-       STAT(STAT_PORTS_FLUSHED, 1);
-    } else {
-       STAT(STAT_PORTS_FLUSHED_FAILED, 1);
-       DEBUG_PRINTF("* %T port_flush(%p)\n", port);
-    }
-
-    return ok;
-}
diff --git a/Xisop/src/common/kernel/port.h b/Xisop/src/common/kernel/port.h
deleted file mode 100644 (file)
index 0a2ee44..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* $Id: port.h,v 1.2 2004/01/18 17:43:00 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_PORT_H
-#define KERNEL_PORT_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-#include <common/kernel/signal.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/main.h>
-#include <common/kernel/memory.h>
-#include <common/kernlib/hash.h>
-#include <common/kernlib/string.h>
-
-
-
-struct port {
-    hashnode_t sysnode;
-    node_t tasknode;           /* Link to task_t ressources list_t */
-    /* Validity sceal, message_t can depend on us */
-    u_int32_t object_magic, object_id;
-    /* Other */
-    task_t *sigtask;
-    signum_t signum;
-    list_t messages;
-    /* The following are used for public ports */
-    bstr_t *name;
-};
-
-struct message {
-    pnode_t node;      /* Allows for linking and using pool_t */
-    /* The following two are used to allow replying back, but only to the
-     * actually expected reply port.
-     */
-    port_t *replyport;
-    /* Object dependancy */
-    u_int32_t objdep_magic, objdep_id;
-};
-
-/* This message type is made to pass through the special multiplexed port */
-/* XXX */
-struct mmessage {
-    message_t node;
-    int type;
-    union {
-    } u;
-};
-
-
-
-#define PORT_SIGMASK(p)                SIGMASK((p)->signum)
-
-
-
-port_t *port_create(const char *);
-port_t *port_destroy(port_t *);
-port_t *port_find(const char *);
-bool port_send(port_t *, port_t *, message_t *);
-message_t *port_get(port_t *);
-bool port_reply(message_t *);
-port_t *port_wait(port_t **, u_int32_t, task_t *);
-bool port_flush(port_t *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/scheduler.c b/Xisop/src/common/kernel/scheduler.c
deleted file mode 100644 (file)
index f9329a4..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/* $Id: scheduler.c,v 1.5 2004/01/29 21:52:12 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/main.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/task.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/object.h>
-#include <processor/support.h>
-
-
-
-/* The famous initial context (the first scheduler interrupt context save
- * operation saves main()'s context there. This context is resumed when there
- * are no more tasks in the ready queue to run, in which case main()'s CPU
- * ideling loop resumes.
- */
-static _ctx_t _scontext;
-
-
-
-/* Used to initialize the xisop_root necessary fields */
-void scheduler_init(void)
-{
-    /* Initialize scheduler recursive lock, and obtain it. The system will
-     * need to SCHED_ENABLE() to start the scheduler.
-     */
-    _rlock_init(&root->sched_lock);
-    _rlock_acquire(&root->sched_lock);
-    DLIST_INIT(&root->tasks_ready);
-    DLIST_INIT(&root->tasks_wait);
-    DLIST_INIT(&root->tasks_dead);
-    root->curtask = NULL;
-    root->curctx = &_scontext;
-}
-
-
-/* This function only has effect if the scheduler recursive lock is free,
- * in which case scheduling is enabled. When so, it evaluates which task
- * should run next and internally performs task and context switching if
- * needed, via root->curtask and _scontext, the static context buffer used
- * by the scheduler interrupt handler to store and load CPU context. We are
- * only dealing with the tasks which are currently on the root->tasks_ready
- * queue, and are working appropriately around the events of no tasks in the
- * queue and the first context switch, and against recursion.
- *
- * What the scheduler timer interrupt does is disable the interrupt source,
- * save the current user CPU context in root->curctx, which may be _scontext
- * or old task context, execute the _FACILITY_SCHEDTIMER hooks calling
- * facility_exechooks(), call us, load back the saved user CPU context
- * from root->curctx, re-enable the interrupt source and return from exception
- * to the new context's PC address. So basically we are between the context
- * save and load operations, and can access and alter root->curtask and
- * root->curctx, thus the buffer it uses to load the context back.
- *
- * Our task priority scheduling algorithm uses a credits attribution method
- * where when starting a round, each task in the queue receives credits
- * according to it's specific priority. The round expires when none of the
- * tasks have any credits left, in which case a new round restarts over.
- * During a round, an effort is made to both allow tasks with the most credits
- * to run more often and faster than others, while still distributing as much
- * as possible their turns evenly to make the signal and message port systems
- * work as efficiently as possible in all cases.
- *
- * This does not account for how long each task has run, a task may
- * take any time from 0 to the scheduler rate before it is interrupted and
- * a credit is substracted from it. Another type of scheduler could be
- * more suitable for a realtime system.
- */
-void old_schedule(void)
-{
-    /* Do nothing unless the scheduler is enabled */
-    if (_rlock_try(&root->sched_lock)) {
-       register task_t *ntsk, *old;
-
-       if ((old = root->curtask) == NULL)
-           ntsk = DLIST_TOP(&root->tasks_ready);
-       else {
-           if (old->state == STATE_RUN)
-               old->state = STATE_READY;
-           for (;;) {
-               register task_t *tsk;
-               register priority_t credit;
-
-               /* Find which task has the most credits and deserves next run,
-                * but continue the loop at previous task, otherwise the
-                * highest priority task will get all turns at once until it
-                * reaches equality with other tasks.
-                */
-               credit = -128;
-               tsk = old;
-               ntsk = NULL;
-               for (;;) {
-                   if ((tsk = (task_t *)tsk->node.node.next) == NULL)
-                       tsk = DLIST_TOP(&root->tasks_ready);
-                   if (tsk != old) {
-                       if (credit < tsk->credits) {
-                           credit = tsk->credits;
-                           ntsk = tsk;
-                       }
-                   } else
-                       break;
-               }
-               if (ntsk == NULL) {
-                   /* If this happens there is only one task in the queue,
-                    * or none. Revert back to previous task, if any.
-                    */
-                   if (DLIST_NODES(&root->tasks_ready) > 0)
-                       ntsk = old;
-                   else break;
-               }
-
-               if (credit == -128 /* XXX && ntsk != old */) {
-                   /* All out of credits, redistribute them. This is the
-                    * end and beginning of a new round.
-                    */
-                   DLIST_FOREACH(&root->tasks_ready, tsk) {
-                       if ((tsk->credits = tsk->priority) == -128)
-                           tsk->credits++;
-                   }
-                   continue;
-               }
-
-               break;
-           }
-       }
-
-       if (ntsk != NULL) {
-           /* This is the next task to run */
-           ntsk->credits--;
-           if (ntsk != old) {
-               /* Perform actual context switch */
-               STAT(STAT_SCHED_PREEMPTED, 1);
-               ntsk->state = STATE_RUN;
-               root->curtask = ntsk;
-               root->curctx = &ntsk->ctx;
-           }
-       } else {
-           root->curtask = NULL;
-           root->curctx = &_scontext;
-       }
-
-       _rlock_release(&root->sched_lock);
-    }
-}
-
-/* Because there seems to be a bug with the previous function and that
- * all we need for testing and building the rest of Xisop is at least
- * round robin, here is a function which at least works for now.
- */
-void schedule(task_t *pref)
-{
-    if (_rlock_try(&root->sched_lock)) {
-       register task_t *tsk;
-
-       /* First evaluate if requested task is ok to switch to */
-       if (OBJECT_VALID(pref, OBJECT_TASK) && pref != root->curtask &&
-               pref->state == STATE_READY)
-           tsk = pref;
-       else {
-           if ((tsk = root->curtask) == NULL)
-               tsk = DLIST_TOP(&root->tasks_ready);
-           else {
-               /* The current task may not be in the ready list anymore */
-               if (tsk->state == STATE_READY || tsk->state == STATE_RUN) {
-                   tsk->state = STATE_READY;
-                   if ((tsk = DLIST_NEXT(tsk)) == NULL)
-                       tsk = DLIST_TOP(&root->tasks_ready);
-               } else
-                   tsk = DLIST_TOP(&root->tasks_ready);
-           }
-       }
-       if (tsk != NULL) {
-           tsk->state = STATE_RUN;
-           root->curtask = tsk;
-           root->curctx = &tsk->ctx;
-       } else {
-           /* No tasks in the ready queue to run, return to the original
-            * main() context, which idles the CPU as much as possible
-            * using sys_idle().
-            */
-           root->curtask = NULL;
-           root->curctx = &_scontext;
-       }
-       _rlock_release(&root->sched_lock);
-    }
-}
-
-
-/* Allows to make a task sleep forcibly. The only way it can then wake up
- * is by task_wakeup() using at least one of the bits in the flags.
- */
-void task_sleep(task_t *task, u_int32_t flags, task_t *yield)
-{
-    bool current = FALSE;
-
-    SCHED_DISABLE();
-    if (OBJECT_VALID(task, OBJECT_TASK) &&
-           (task->state == STATE_READY || task->state == STATE_RUN)) {
-       task->sleepflags = flags;
-       task->state = STATE_WAIT;
-       DLIST_SWAP(&root->tasks_wait, &root->tasks_ready, (node_t *)task,
-               FALSE);
-       if (task == root->curtask)
-           current = TRUE;
-    }
-    SCHED_ENABLE();
-    if (current)
-       _yield(yield);
-}
-
-/* Awakes a task which should have been put asleep using task_sleep().
- * The task is only awaken if at least one of the reasons in flags matches.
- */
-bool task_wakeup(task_t *task, u_int32_t flags)
-{
-    bool ok = FALSE;
-
-    SCHED_DISABLE();
-    if (OBJECT_VALID(task, OBJECT_TASK) &&
-           task->state == STATE_WAIT && (task->sleepflags & flags)) {
-       task->state = STATE_READY;
-       task->sleepflags = 0;
-       task->credits = task->priority;
-       if (task->credits == -128)
-           task->credits++;
-       DLIST_SWAP(&root->tasks_ready, &root->tasks_wait, (node_t *)task,
-               FALSE);
-       ok = TRUE;
-    }
-    SCHED_ENABLE();
-
-    return ok;
-}
-
-
-void sched_disable(void)
-{
-    SCHED_DISABLE();
-}
-
-void sched_enable(void)
-{
-    SCHED_ENABLE();
-}
-
-
-/* Nestled locking is not permitted with these locks */
-void lock_acquire(_lock_t *lock)
-{
-    /* Always immediately _yield() unless we can obtain the lock.
-     * This way we use the less CPU time possible while at the same time
-     * allowing the locker to eventually release the lock.
-     */
-    for (;;) {
-       if (_lock_try(lock))
-           break;
-       _yield(NULL);
-    }
-}
-
-void lock_release(_lock_t *lock)
-{
-    _lock_release(lock);
-}
-
-
-/* A lock type permitting multiple readers but exclusive access for write */
-void rwlock_init(rwlock_t *lock)
-{
-    _lock_init(&lock->exclusive_lock);
-    _rlock_init(&lock->recursive_lock);
-    lock->state = RWLOCK_SLOCKED;
-}
-
-void rwlock_acquire(rwlock_t *lock, bool exclusive)
-{
-    lock_acquire(&lock->exclusive_lock);
-    if (exclusive) {
-       while (!_rlock_try(&lock->recursive_lock))
-           _yield(NULL);
-       lock->state = RWLOCK_XLOCKED;
-       _rlock_release(&lock->recursive_lock);
-    } else {
-       _rlock_acquire(&lock->recursive_lock);
-       lock->state = RWLOCK_SLOCKED;
-       _lock_release(&lock->exclusive_lock);
-    }
-}
-
-void rwlock_release(rwlock_t *lock)
-{
-    switch (lock->state) {
-    case RWLOCK_SLOCKED:
-       _rlock_release(&lock->recursive_lock);
-       break;
-    case RWLOCK_XLOCKED:
-       lock->state = RWLOCK_SLOCKED;
-       _lock_release(&lock->exclusive_lock);
-       break;
-    }
-}
-
-bool rwlock_try(rwlock_t *lock, bool exclusive)
-{
-    bool ok = FALSE;
-
-    if (_lock_try(&lock->exclusive_lock)) {
-       if (exclusive) {
-           if (_rlock_try(&lock->recursive_lock)) {
-               _rlock_release(&lock->recursive_lock);
-               _lock_release(&lock->exclusive_lock);
-           } else {
-               lock->state = RWLOCK_XLOCKED;
-               ok = TRUE;
-           }
-       } else {
-           _rlock_acquire(&lock->recursive_lock);
-           lock->state = RWLOCK_SLOCKED;
-           _lock_release(&lock->exclusive_lock);
-           ok = TRUE;
-       }
-    }
-
-    return ok;
-}
-
-void rwlock_upgrade(rwlock_t *lock)
-{
-    if (lock->state == RWLOCK_SLOCKED) {
-       lock_acquire(&lock->exclusive_lock);
-       _rlock_release(&lock->recursive_lock);
-       while (!_rlock_try(&lock->recursive_lock))
-           _yield(NULL);
-       lock->state = RWLOCK_XLOCKED;
-       _rlock_release(&lock->recursive_lock);
-    }
-}
-
-void rwlock_downgrade(rwlock_t *lock)
-{
-    if (lock->state == RWLOCK_XLOCKED) {
-       _rlock_acquire(&lock->recursive_lock);
-       lock->state = RWLOCK_SLOCKED;
-       _lock_release(&lock->exclusive_lock);
-    }
-}
diff --git a/Xisop/src/common/kernel/scheduler.h b/Xisop/src/common/kernel/scheduler.h
deleted file mode 100644 (file)
index 02b95ce..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $Id: scheduler.h,v 1.2 2004/01/19 00:03:23 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_SCHEDULER_H
-#define KERNEL_SCHEDULER_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-#include <processor/support.h>
-
-
-
-/* Scheduler control without affecting the scheduler interrupt */
-#define SCHED_DISABLE()                _rlock_acquire(&root->sched_lock)
-#define SCHED_ENABLE()         _rlock_release(&root->sched_lock)
-
-/* Sleep reason flags for task_sleep() and task_wakeup() */
-#define TSF_SIGNAL             (1L << 0)
-#define TSF_KERNEL             (1L << 1)
-#define TSF_CUSTOM             (1L << 2)
-
-/* State of an rwlock_t */
-enum _rwlock_states {
-    RWLOCK_SLOCKED,
-    RWLOCK_XLOCKED
-};
-
-struct rwlock {
-    _lock_t exclusive_lock;
-    _rlock_t recursive_lock;
-    enum _rwlock_states state;
-};
-
-
-
-void scheduler_init(void);
-void schedule(task_t *);
-void task_sleep(task_t *, u_int32_t, task_t *);
-bool task_wakeup(task_t *, u_int32_t);
-void sched_disable(void);
-void sched_enable(void);
-
-void lock_acquire(_lock_t *);
-void lock_release(_lock_t *);
-void rwlock_init(rwlock_t *);
-void rwlock_acquire(rwlock_t *, bool);
-void rwlock_release(rwlock_t *);
-bool rwlock_try(rwlock_t *, bool);
-void rwlock_upgrade(rwlock_t *);
-void rwlock_downgrade(rwlock_t *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/signal.c b/Xisop/src/common/kernel/signal.c
deleted file mode 100644 (file)
index a882416..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $Id: signal.c,v 1.3 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/signal.h>
-#include <common/kernel/task.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/main.h>
-#include <common/kernel/syscall.h>
-#include <common/kernel/object.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-
-
-
-/* Attempts to allocate a general purpose user signal from the current task */
-signum_t signal_alloc(void)
-{
-    register signum_t signum = -1;
-    register task_t *task = CURTASK();
-
-    if (task->sigalloc != 0xFFFFFFFF) {
-       register sigmask_t sigmask = task->sigalloc;
-
-       for (signum = 0; signum < 32; signum++) {
-           if ((sigmask & SIGMASK(signum)) == 0) {
-               sigmask |= SIGMASK(signum);
-               task->sigalloc = sigmask;
-               STAT(STAT_SIGNALS_ALLOC, 1);
-               break;
-           }
-       }
-       if (signum == 32)
-           signum = -1;
-    } else {
-       STAT(STAT_SIGNALS_ALLOC_NOSIG, 1);
-       DEBUG_PRINTF("- %T signal_alloc() - Out of signals\n");
-    }
-
-    return signum;
-}
-
-
-void _signal_free(task_t *task, sigmask_t sigmask)
-{
-    if (OBJECT_VALID(task, OBJECT_TASK)) {
-       /* Refuse to free reserved signals */
-       sigmask &= ~SIGRESMASK;
-       /* But free all other requested ones */
-       task->sigalloc &= ~sigmask;
-       STAT(STAT_SIGNALS_FREE, 1);
-    }
-}
-
-
-/* Frees back specified allocated signals of the current process, for future
- * obtention with signal_alloc() again.
- */
-void signal_free(sigmask_t sigmask)
-{
-    _signal_free(CURTASK(), sigmask);
-}
-
-
-/* Suspends the current task until at least one signal in sigmask is received
- * by it. The task is moved to the wait queue and sigwait is set, as
- * opposition to yield() which does not change the task state and just causes
- * a reschedule.
- * Obviously, using a sigmask of 0 here woild suspend the task indefinitely,
- * and is invalid. If the task needs to be awakened on a timeout event, it
- * should allocate a signal for that event and ensure to receive that signal
- * when the delay expires. This can be done using a timer.device or another
- * task.
- * The optional task argument, which may be NULL, specifies a preference to
- * which task to run next (as we yield()).
- */
-sigmask_t signal_wait(sigmask_t sigmask, task_t *yield)
-{
-    register sigmask_t recvmask = 0;
-
-    if (sigmask != 0) {
-       register task_t *t = CURTASK();
-
-       sigmask |= SIGRESMASK;          /* Always awake on those */
-
-       SCHED_DISABLE();
-       /* Set new sigwait mask */
-       t->sigwait = sigmask;
-       SCHED_ENABLE();
-
-       /* Swap task to waiting queue (we know that we are currently in the
-        * ready one, in STATE_RUN, otherwise we would not be running), and
-        * relay control back to scheduler immediately.
-        */
-       task_sleep(t, TSF_SIGNAL, yield);
-
-       /* If we get here, it's because we were swapped back to the ready queue
-        * as the result of receiving a signal we were waiting for, and
-        * were awaken by the scheduler, and we are back in STATE_RUN. Clear
-        * the sigwait mask, but also return it so that the caller knows which
-        * signal(s) caused our task to wake up again.
-        */
-       SCHED_DISABLE();
-       recvmask = t->sigrecv;
-       t->sigrecv = 0;
-       SCHED_ENABLE();
-
-       STAT(STAT_SIGNALS_WAIT_RETURNED_SLEEP, 1);
-    } else {
-       STAT(STAT_SIGNALS_WAIT_FAILED, 1);
-       DEBUG_PRINTF("* %T signal_wait(%b, %p)\n", sigmask, yield);
-    }
-
-    return recvmask;
-}
-
-
-/* Sends a signal to a task. The task is immediately moved to the ready
- * queue if it currently was waiting for it. The current task is however
- * left executing, but may _yield() if it wants the other end to be able to
- * react to the signal as soon as possible. Otherwise the scheduler frequency
- * and tasks priorities will decide when the other end can run.
- */
-void signal_send(task_t *task, sigmask_t sigmask)
-{
-    if (OBJECT_VALID(task, OBJECT_TASK) && sigmask != 0) {
-       bool awake = FALSE;
-
-       SCHED_DISABLE();
-       /* Apply signals */
-       task->sigrecv |= sigmask;
-       SCHED_ENABLE();
-
-       STAT(STAT_SIGNALS_SEND, 1);
-
-       /* If needed, swap task to ready queue */
-       if ((task->sigwait & task->sigrecv) != 0)
-           awake = task_wakeup(task, TSF_SIGNAL);
-
-       /* XXX UGH! Unless we _yield(), synchronization problems quickly occur
-        * among communicating tasks, they eventually all reside in the wait
-        * queue, in which case they obviously deadlock. And strangely enough,
-        * we have to _yield() twice to solve this issue! Why is currently
-        * still a mystery, but possibly that it has to do with the fact that
-        * when communicating through message ports, we expect a reply?
-        * Maybe that the scheduler should be left to evaluate when a task
-        * should be moved to the waiting queue, and when it needs to be
-        * brought back on the ready queue because it received an expected
-        * signal... rather than having tasks do so themselves, which is what
-        * we currently are doing.
-        */
-       if (awake) {
-           STAT(STAT_SIGNALS_SEND_WOKE, 1);
-           _yield(task);
-           _yield(NULL);
-       }
-    } else {
-       STAT(STAT_SIGNALS_SEND_FAILED, 1);
-       DEBUG_PRINTF("* %T signal_send(%p, %b)\n", task, sigmask);
-    }
-}
diff --git a/Xisop/src/common/kernel/signal.h b/Xisop/src/common/kernel/signal.h
deleted file mode 100644 (file)
index 50eca01..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $Id: signal.h,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_SIGNAL_H
-#define KERNEL_SIGNAL_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-
-
-
-/* Reserved signals */
-#define SIGRESERVED    2
-#define SIGRESMASK     0x00000003L
-#define SIGTERM                0
-#define SIGPOLL                1
-
-
-/* Useful to form a sigmask_t from signum_t */
-#define SIGMASK(n)     (sigmask_t )(1L << (n))
-
-
-signum_t signal_alloc(void);
-void signal_free(sigmask_t);
-void _signal_free(task_t *, sigmask_t);
-sigmask_t signal_wait(sigmask_t, task_t *);
-void signal_send(task_t *, sigmask_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/statistic.c b/Xisop/src/common/kernel/statistic.c
deleted file mode 100644 (file)
index 154823b..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/* $Id: statistic.c,v 1.3 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernel/main.h>
-#include <common/kernlib/string.h>
-#include <config.h>
-
-
-
-#ifdef STATISTICS
-
-
-
-/* Should match with stat_keys enum of statistic.h */
-const static char *stat_strings[] = {
-    "mem.mchunks.attach",
-    "mem.mchunks.attach.failed",
-    "mem.mchunks.detach",
-    "mem.mchunks.detach.failed",
-    "mem.pages.alloc",
-    "mem.pages.alloc.nomem",
-    "mem.pages.free",
-    "mem.pages.free.failed",
-    "mem.pages.buffered",
-    "mem.pages.unbuffered",
-    "mem.pages.reused",
-    "mem.pools.created",
-    "mem.pools.created.failed",
-    "mem.pools.enlarged",
-    "mem.pools.destroyed",
-    "mem.pools.destroyed.failed",
-    "mem.pools.alloc",
-    "mem.pools,alloc.failed",
-    "mem.pools.alloc.nomem",
-    "mem.pools.free",
-    "mem.pools.free.failed",
-    "mem.mpools.created",
-    "mem.mpools.created.failed",
-    "mem.mpools.destroyed",
-    "mem.mpools.destroyed.failed",
-    "mem.mpools.alloc",
-    "mem.mpools.alloc.failed",
-    "mem.mpools.alloc.nomem",
-    "mem.mpools.free",
-    "mem.mpools.free.failed",
-    "syscalls.invalid",
-    "syscalls.invoked",
-    "hooks.attached",
-    "hooks.attached.failed",
-    "hooks.attached.nomem",
-    "hooks.detached",
-    "hooks.detached,failed",
-    "hooks.detached.noexist",
-    "hooks.expired",
-    "hooks.executed",
-    "hooks.skipped",
-    "facility.disabled",
-    "facility.disabled.failed",
-    "facility.enabled",
-    "facility.enabled.failed",
-    "facility.executed",
-    "facility.executed.failed",
-    "facility.executed.locked",
-    "sched.preempted",
-    "tasks.alloc",
-    "tasks.alloc.failed",
-    "tasks.alloc.nomem",
-    "tasks.free",
-    "tasks.free.failed",
-    "tasks.started",
-    "tasks.started.failed",
-    "tasks.ended",
-    "tasks.ended.failed",
-    "ports.created",
-    "ports.created.exists",
-    "ports.created.nomem",
-    "ports.created.nosig",
-    "ports.destroyed",
-    "ports.destroyed.failed",
-    "ports.find.found",
-    "ports.find.notfound",
-    "ports.send",
-    "ports.send.failed",
-    "ports.send",
-    "ports.send.failed",
-    "ports.get",
-    "ports.get.failed",
-    "ports.reply",
-    "ports.reply.failed",
-    "ports.wait",
-    "ports.wait.failed",
-    "ports.wait.sleep",
-    "ports.wait.returned.immediate",
-    "ports.wait.returned.sleep",
-    "ports.wait.returned.nosig",
-    "ports.flushed",
-    "ports.flushed.failed",
-    "signals.alloc",
-    "signals.alloc.nosig",
-    "signals.free",
-    "signals.wait",
-    "signals.wait.failed",
-    "signals.wait.returned.sleep",
-    "signals.send",
-    "signals.send.failed",
-    "signals.send.woke",
-    NULL
-};
-
-
-
-void statistic_init(void)
-{
-    register u_int32_t i;
-
-    for (i = 0; i < (enum stat_keys)STAT_MAX; i++)
-       root->stats[i] = 0;
-}
-
-
-void stat_dump(void)
-{
-    register u_int32_t i;
-
-    for (i = 0; i < (enum stat_keys)STAT_MAX; i++)
-       DEBUG_PRINTF("%u\t%s\n", root->stats[i], stat_strings[i]);
-}
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/statistic.h b/Xisop/src/common/kernel/statistic.h
deleted file mode 100644 (file)
index 8024431..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* $Id: statistic.h,v 1.2 2004/01/18 17:43:00 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_STATISTIC_H
-#define KERNEL_STATISTIC_H
-
-
-
-#include <config.h>
-
-
-
-#ifndef STATISTICS
-
-#define STAT(k, m)
-
-#else
-
-
-
-enum stat_keys {
-    STAT_MCHUNKS_ATTACH = 0,
-    STAT_MCHUNKS_ATTACH_FAILED,
-    STAT_MCHUNKS_DETACH,
-    STAT_MCHUNKS_DETACH_FAILED,
-    STAT_PAGES_ALLOC,
-    STAT_PAGES_ALLOC_NOMEM,
-    STAT_PAGES_FREE,
-    STAT_PAGES_FREE_FAILED,
-    STAT_PAGES_BUFFERED,
-    STAT_PAGES_UNBUFFERED,
-    STAT_PAGES_REUSED,
-    STAT_POOLS_CREATED,
-    STAT_POOLS_CREATED_FAILED,
-    STAT_POOLS_ENLARGED,
-    STAT_POOLS_DESTROYED,
-    STAT_POOLS_DESTROYED_FAILED,
-    STAT_POOLS_ALLOC,
-    STAT_POOLS_ALLOC_FAILED,
-    STAT_POOLS_ALLOC_NOMEM,
-    STAT_POOLS_FREE,
-    STAT_POOLS_FREE_FAILED,
-    STAT_MPOOLS_CREATED,
-    STAT_MPOOLS_CREATED_FAILED,
-    STAT_MPOOLS_DESTROYED,
-    STAT_MPOOLS_DESTROYED_FAILED,
-    STAT_MPOOLS_ALLOC,
-    STAT_MPOOLS_ALLOC_FAILED,
-    STAT_MPOOLS_ALLOC_NOMEM,
-    STAT_MPOOLS_FREE,
-    STAT_MPOOLS_FREE_FAILED,
-    STAT_SYSCALLS_INVALID,
-    STAT_SYSCALLS_INVOKED,
-    STAT_HOOKS_ATTACHED,
-    STAT_HOOKS_ATTACHED_FAILED,
-    STAT_HOOKS_ATTACHED_NOMEM,
-    STAT_HOOKS_DETACHED,
-    STAT_HOOKS_DETACHED_FAILED,
-    STAT_HOOKS_DETACHED_NOEXIST,
-    STAT_HOOKS_EXPIRED,
-    STAT_HOOKS_EXECUTED,
-    STAT_HOOKS_SKIPPED,
-    STAT_FACILITY_DISABLED,
-    STAT_FACILITY_DISABLED_FAILED,
-    STAT_FACILITY_ENABLED,
-    STAT_FACILITY_ENABLED_FAILED,
-    STAT_FACILITY_EXECUTED,
-    STAT_FACILITY_EXECUTED_FAILED,
-    STAT_FACILITY_EXECUTED_LOCKED,
-    STAT_SCHED_PREEMPTED,
-    STAT_TASKS_ALLOC,
-    STAT_TASKS_ALLOC_FAILED,
-    STAT_TASKS_ALLOC_NOMEM,
-    STAT_TASKS_FREE,
-    STAT_TASKS_FREE_FAILED,
-    STAT_TASKS_STARTED,
-    STAT_TASKS_STARTED_FAILED,
-    STAT_TASKS_ENDED,
-    STAT_TASKS_ENDED_FAILED,
-    STAT_PORTS_CREATED,
-    STAT_PORTS_CREATED_EXISTS,
-    STAT_PORTS_CREATED_NOMEM,
-    STAT_PORTS_CREATED_NOSIG,
-    STAT_PORTS_DESTROYED,
-    STAT_PORTS_DESTROYED_FAILED,
-    STAT_PORTS_FIND_FOUND,
-    STAT_PORTS_FIND_NOTFOUND,
-    STAT_PORTS_SEND,
-    STAT_PORTS_SEND_FAILED,
-    STAT_PORTS_GET,
-    STAT_PORTS_GET_FAILED,
-    STAT_PORTS_REPLY,
-    STAT_PORTS_REPLY_FAILED,
-    STAT_PORTS_WAIT,
-    STAT_PORTS_WAIT_FAILED,
-    STAT_PORTS_WAIT_SLEEP,
-    STAT_PORTS_WAIT_RETURNED_IMMEDIATE,
-    STAT_PORTS_WAIT_RETURNED_SLEEP,
-    STAT_PORTS_WAIT_RETURNED_NOSIG,
-    STAT_PORTS_FLUSHED,
-    STAT_PORTS_FLUSHED_FAILED,
-    STAT_SIGNALS_ALLOC,
-    STAT_SIGNALS_ALLOC_NOSIG,
-    STAT_SIGNALS_FREE,
-    STAT_SIGNALS_WAIT,
-    STAT_SIGNALS_WAIT_FAILED,
-    STAT_SIGNALS_WAIT_RETURNED_SLEEP,
-    STAT_SIGNALS_SEND,
-    STAT_SIGNALS_SEND_FAILED,
-    STAT_SIGNALS_SEND_WOKE,
-    STAT_MAX
-};
-
-
-
-#define STAT(k, n)     root->stats[(enum stat_keys)(k)] += (n)
-
-
-
-void statistic_init(void);
-void statistic_dump(void);
-
-
-
-#endif
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/syscall.c b/Xisop/src/common/kernel/syscall.c
deleted file mode 100644 (file)
index 9df06e8..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/* $Id: syscall.c,v 1.2 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* It also would be possible to simply use a structure with all the
- * function pointers of the various types... And have the user functions
- * refer those with the structure as well, just like for Xisop libraries...
- * However, this system is a little more secure for the kernel stack,
- * which state is always controled. It also allows to export an ID which
- * we can validate.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/main.h>
-#include <common/kernel/syscall.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/exception.h>
-#include <common/kernel/memory.h>
-#include <port/support.h> /* XXX */
-
-
-
-static void _sys_getroot(void *, void *);
-static void _sys_int_disable(void *, void *);
-static void _sys_int_enable(void *, void *);
-static void _sys_idle(void *, void *);
-static void _sys_custom(void *, void *);
-
-
-
-/* Should match with enum in syscall.h */
-static void (*_syscalls[])(void *, void *) = {
-    _sys_getroot,
-    _sys_int_disable,
-    _sys_int_enable,
-    _sys_idle,
-    _sys_custom
-};
-
-
-
-/* Called by port-specific code before initializing interrupt facilities */
-void syscall_init(void)
-{
-    root->syscalls = _syscalls;
-}
-
-
-/* The following consist of the kernel-side functions which execute in
- * supervisor mode.
- */
-
-/* Syscall trap handler */
-void _scatch(u_int32_t func, void *res, void *args)
-{
-    if (func < (enum syscalls)SYS_MAX && root->syscalls[func])
-       root->syscalls[func](res, args);
-    else {
-       STAT(STAT_SYSCALLS_INVALID, 1);
-       DEBUG_PRINTF("* %T _scatch(%u, %p, %p) - Invalid syscall number\n",
-               func, res, args);
-    }
-    STAT(STAT_SYSCALLS_INVOKED, 1);
-}
-
-
-static void _sys_getroot(void *res, void *args)
-{
-    struct _sres {
-       struct xisop_root *root;
-    } *sres = res;
-
-    sres->root = root;
-}
-
-
-/* ARGSUSED */
-static void _sys_int_disable(void *res, void *args)
-{
-    _splhigh();
-}
-
-/* ARGSUSED */
-static void _sys_int_enable(void *res, void *args)
-{
-    _spl0();
-}
-
-/* ARGSUSED */
-static void _sys_idle(void *res, void *args)
-{
-    _idle();
-}
-
-
-static void _sys_custom(void *res, void *args)
-{
-    struct _sargs {
-       void (*func)(void *, void *);
-       void *args;
-    } *sargs = args;
-
-    sargs->func(res, sargs->args);
-}
-
-
-
-/* And here are the functions which are called from userspace to trigger
- * system calls.
- */
-
-/* Returns the Xisop system pointer. This obviously should be used with care */
-struct xisop_root *sys_getroot(void)
-{
-    struct _sres {
-       struct xisop_root *root;
-    } sres;
-
-    _syscall(SYS_GETROOT, &sres, NULL);
-
-    return sres.root;
-}
-
-
-/* And these allow to disable all interrupts, which of course also causes
- * the scheduler to be disabled. Should however not generally be used as a
- * substitute to sched_disable().
- */
-void sys_int_disable(void)
-{
-    _syscall(SYS_INT_DISABLE, NULL, NULL);
-}
-
-void sys_int_enable(void)
-{
-    _syscall(SYS_INT_ENABLE, NULL, NULL);
-}
-
-/* Causes the CPU to sleep until the next interrupt occurs */
-void sys_idle(void)
-{
-    _syscall(SYS_IDLE, NULL, NULL);
-}
-
-
-/* Since Xisop does not use MMU, and in now way claims to be secure against
- * it's own tasks, other than providing clean facilities, a very useful
- * syscall to execute arbitrary code in supervisor mode. If one needs
- * unix security, they should be running NetBSD :)
- * This allows userspace tasks to extend system calls. The user provided
- * function uses the same semantics as Xisop syscall ones. An int value
- * can be returned, which will then be returned by sys_custom(), and
- * arbitrary data may be written into the supplied results pointer if wanted
- * (the first void * argument, which is set to the supplied res pointer).
- * The user function can obtain it's arguments from the second void *,
- * which is supplied using args. This way possibilities are endless.
- */
-void sys_custom(void *res, void (*func)(void *, void *), void *args)
-{
-    struct _sargs {
-       void (*func)(void *, void *);
-       void *args;
-    } sargs = {
-       func,
-       args
-    };
-
-    _syscall(SYS_CUSTOM, res, &sargs);
-}
diff --git a/Xisop/src/common/kernel/syscall.h b/Xisop/src/common/kernel/syscall.h
deleted file mode 100644 (file)
index 639a0c5..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* $Id: syscall.h,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERN_SYSCALL_H
-#define KERN_SYSCALL_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/exception.h>
-#include <common/kernel/memory.h>
-
-
-
-/* Currently available syscalls */
-enum syscalls {
-    SYS_GETROOT = 0,
-    SYS_INT_DISABLE,
-    SYS_INT_ENABLE,
-    SYS_IDLE,
-    SYS_CUSTOM,
-    SYS_MAX
-};
-
-
-
-void syscall_init(void);
-void _scatch(u_int32_t, void *, void *);
-
-struct xisop_root *sys_getroot(void);
-void sys_int_disable(void);
-void sys_int_enable(void);
-void sys_idle(void);
-void sys_custom(void *, void (*)(void *, void *), void *);
-
-
-
-extern void (*_syscalls[])(void *, void *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernel/task.c b/Xisop/src/common/kernel/task.c
deleted file mode 100644 (file)
index 0234078..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/* $Id: task.c,v 1.8 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/task.h>
-#include <common/kernel/port.h>
-#include <common/kernel/main.h>
-#include <common/kernel/scheduler.h>
-#include <common/kernel/object.h>
-#include <common/kernel/statistic.h>
-#include <common/kernel/debug.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/syscall.h>
-#include <port/support.h>
-#include <processor/support.h>
-
-
-
-static void task_startend_code(void);
-
-static int task_reaper(void *, void *);
-
-
-
-task_t *task_alloc(int (*start)(void *, void *), void *res, void *args,
-       priority_t priority, size_t stacksize, u_int8_t flags)
-{
-    if (start != NULL && stacksize != 0) {
-       register page_t *stack = NULL;
-       register u_int32_t pages;
-
-       pages = stacksize / _PAGE_SIZE;
-       if (stacksize % _PAGE_SIZE)
-           pages++;
-       if ((stack = pages_alloc(0, pages, FALSE)) != NULL) {
-           register task_t *task = NULL;
-
-           if ((task = (task_t *)spool_alloc(POOL_TASK)) != NULL) {
-               if ((flags & TF_SHARED) != 0) {
-                   register mpool_t *mpool = CURTASK()->mpool;
-
-                   if (OBJECT_VALID(mpool, OBJECT_MPOOL)) {
-                       /* This task will share mpool_t with parent */
-                       lock_acquire(&mpool->lock);
-                       mpool->shared = TRUE;
-                       mpool->usecount++;
-                       task->mpool = mpool;
-                       _lock_release(&mpool->lock);
-                   }
-               } else {
-                   /* This task needs it's own unique mpool_t */
-                   if ((task->mpool = (mpool_t *)spool_alloc(POOL_MPOOL))
-                           != NULL) {
-                       if (!mpool_init(task->mpool))
-                           task->mpool = (mpool_t *)spool_free(POOL_MPOOL,
-                                   (pnode_t *)task->mpool);
-                   }
-               }
-               if (task->mpool != NULL) {
-                   /* Validate task_t object */
-                   OBJECT_VALIDATE(task, OBJECT_TASK);
-                   /* Initialize other task_t fields */
-                   task->sleepflags = 0;
-                   task->flags = flags;
-                   task->state = STATE_START;
-                   task->priority = priority;
-                   task->sigalloc = task->sigwait = task->sigrecv = 0;
-                   task->start = start;
-                   task->res = res;
-                   task->args = args;
-                   task->rescode = 0;
-                   task->stack = stack;
-                   task->stacksize = pages * _PAGE_SIZE;
-                   _ctx_init(&task->ctx, (u_int32_t *)stack->address,
-                           task->stacksize, (void *)task_startend_code);
-                   /* Resources */
-                   DLIST_INIT(&task->resources.ports);
-                   DLIST_INIT(&task->resources.devices);
-                   task->resources.device = NULL;
-                   STAT(STAT_TASKS_ALLOC, 1);
-
-                   return task;
-               } else {
-                   STAT(STAT_TASKS_ALLOC_NOMEM, 1);
-                   DEBUG_PRINTF(
-                   "* %T task_alloc(%p. %p, %p, %d, %u, %x) - mpool_init()\n",
-                       start, res, args, (int32_t)priority, stacksize,
-                       (u_int32_t)flags);
-               }
-               spool_free(POOL_TASK, (pnode_t *)task);
-           } else {
-               STAT(STAT_TASKS_ALLOC_NOMEM, 1);
-               DEBUG_PRINTF(
-               "* %T task_alloc(%p, %p, %p, %d, %u, %x) - Out of memory\n",
-                       start, res, args, (int32_t)priority, stacksize,
-                       (u_int32_t)flags);
-           }
-           pages_free(stack);
-       } else {
-           STAT(STAT_TASKS_ALLOC_NOMEM, 1);
-           DEBUG_PRINTF(
-               "* %T task_alloc(%p, %p, %p, %d, %u, %x) - Out of memory\n",
-               start, res, args, (int32_t)priority, stacksize,
-               (u_int32_t)flags);
-       }
-    } else {
-       STAT(STAT_TASKS_ALLOC_FAILED, 1);
-       DEBUG_PRINTF("* %T task_alloc(%p, %p, %p, %d, %u, %x)\n",
-               start, res, args, (int32_t)priority, stacksize,
-               (u_int32_t)flags);
-    }
-
-    return NULL;
-}
-
-
-/* Free a task_t. Also unlinks the task from the system lists. The task
- * must first have been processed by task_end() and thus moved into the
- * dead queue.
- */
-task_t *task_free(task_t *task)
-{
-    if (OBJECT_VALID(task, OBJECT_TASK) &&
-           (task->state == STATE_DEAD || task->state == STATE_START)) {
-       SCHED_DISABLE();
-       if (task->state == STATE_DEAD)
-           DLIST_UNLINK(&root->tasks_dead, (node_t *)task);
-       SCHED_ENABLE();
-       if (task->stack != NULL)
-           pages_free(task->stack);
-       /* Free task resources */
-       /* All ports the task created. Linked via port_t->tasknode. */
-       {
-           register port_t *port, *next;
-
-           for (port = DLIST_TOP(&(task->resources.ports)); port != NULL;
-                   port = next) {
-               next = DLIST_NEXT(&port->tasknode);
-               port_destroy((port_t *)&(((hashnode_t *)port)[-1]));
-           }
-       }
-       /* Devices we opened. Linked via device_t->tasknode. */
-       {
-           register node_t *node, *next;
-
-           for (node = DLIST_TOP(&(task->resources.devices)); node != NULL;
-                   node = next) {
-               next = DLIST_NEXT(node);
-               device_close((device_t *)&(((pnode_t *)node)[-1]));
-           }
-       }
-       /* If we are a device */
-       if (task->resources.device)
-           device_detach(task->resources.device);
-       /* XXX other future resources handling, like opened libraries, etc */
-       /* Invalidate task */
-       OBJECT_INVALIDATE(task);
-       /* All memory the task allocated using malloc(). If mpool_destroy()
-        * fails with FALSE, either a problem occured or the mpool_t is still
-        * in use by another task sharing it, in which case we do not free it.
-        */
-       if (mpool_destroy(task->mpool))
-           spool_free(POOL_MPOOL, (pnode_t *)task->mpool);
-       /* And finally the task node itself. */
-       spool_free(POOL_TASK, (pnode_t *)task);
-       STAT(STAT_TASKS_FREE, 1);
-    } else {
-       STAT(STAT_TASKS_FREE_FAILED, 1);
-       DEBUG_PRINTF("* %T task_free(%p)\n", task);
-    }
-
-    return NULL;
-}
-
-
-/* Allows to start a new task */
-bool task_start(task_t *task)
-{
-    bool ok = FALSE;
-
-    if (OBJECT_VALID(task, OBJECT_TASK) && task->state == STATE_START) {
-       /* This task was just allocated, start it */
-       task->state = STATE_READY;
-       if ((task->credits = task->priority) == -128)
-           task->credits++;
-       SCHED_DISABLE();
-       DLIST_APPEND(&root->tasks_ready, (node_t *)task);
-       SCHED_ENABLE();
-       ok = TRUE;
-       STAT(STAT_TASKS_STARTED, 1);
-    } else {
-       STAT(STAT_TASKS_STARTED_FAILED, 1);
-       DEBUG_PRINTF("* %T task_start(%p)\n", task);
-    }
-
-    return ok;
-}
-
-
-bool task_end(task_t *task)
-{
-    bool ok = FALSE, current = FALSE;
-
-    if (OBJECT_VALID(task, OBJECT_TASK) && task->state != STATE_DEAD) {
-       ok = TRUE;
-       SCHED_DISABLE();
-       switch (task->state) {
-       case STATE_RUN:
-           /* FALLTHROUGH */
-       case STATE_READY:
-           DLIST_SWAP(&root->tasks_dead, &root->tasks_ready, (node_t *)task,
-                   FALSE);
-           break;
-       case STATE_WAIT:
-           DLIST_SWAP(&root->tasks_dead, &root->tasks_wait, (node_t *)task,
-                   FALSE);
-           break;
-       default:
-           ok = FALSE;
-           break;
-       }
-       if (ok) {
-           STAT(STAT_TASKS_ENDED, 1);
-           task->state = STATE_DEAD;
-           /* Wakeup reaper as there's at least one task on the dead queue */
-           task_wakeup(root->task_reaper, TSF_KERNEL);
-           /* If it's the current task, ensure to yield now. */
-           if (task == root->curtask)
-               current = TRUE;
-       }
-       SCHED_ENABLE();
-    }
-
-    if (current) {
-       /* We also probably could go to sleep indefinitely instead,
-        * but as we are in the dead queue, we are certain that we will not
-        * be given another chance to run until we get freed.
-        */
-       for (;;)
-           _yield(NULL);
-    }
-    if (!ok) {
-       STAT(STAT_TASKS_ENDED_FAILED, 1);
-       DEBUG_PRINTF("* %T task_end(%p)\n", task);
-    }
-
-    return ok;
-}
-
-
-priority_t task_getpriority(task_t *task)
-{
-    register priority_t p = 0;
-
-    if (OBJECT_VALID(task, OBJECT_TASK))
-       p = task->priority;
-
-    return p;
-}
-
-
-priority_t task_setpriority(task_t *task, priority_t new)
-{
-    register priority_t p = 0;
-
-    if (OBJECT_VALID(task, OBJECT_TASK)) {
-       SCHED_DISABLE();
-       p = task->priority;
-       task->priority = new;
-       if ((task->credits = new) == -128)
-           task->credits++;
-       SCHED_ENABLE();
-    }
-
-    return p;
-}
-
-
-/* This is the code which each new task automatically starts executing, which
- * performs some initializations and then executes the task-specific code.
- * It also takes control again when the task ends and returns.
- */
-static void task_startend_code(void)
-{
-    register task_t *task = CURTASK();
-
-    /* XXX Setup our reserved signals and port */
-
-    /* Call the supplied entry point function */
-    task->rescode = task->start(task->res, task->args);
-
-    /* Adios amigo! Translation: KTHXBYE!111 */
-    task_end(task);
-    /* NOTREACHED */
-}
-
-
-
-/* System tasks
- * ============
- */
-
-/* This consists of Xisop init task. It's purpose is to launch the system
- * tasks as well as all tasks which the port-specific code defined which should
- * be launched. We also link in system and port-defined shared libraries.
- * Resident devices and handlers actually consist of tasks and are given
- * no special treatment.
- */
-/* ARGSUSED */
-int task_init(void *res, void *args)
-{
-    /* Register ourself */
-    root->task_init = CURTASK();
-
-    /* Attach system shared libraries */
-    {
-       /* XXX */
-    }
-
-    /* Launch system tasks, which auto-register themselves by storeing their
-     * address in the Xisop root structure.
-     */
-    {
-       register task_t *task;
-
-       /* Task reaper */
-       if ((task = task_alloc(task_reaper, NULL, NULL, 0, 4096,
-                       TF_KERNEL | TF_SHARED)) != NULL)
-           task_start(task);
-    }
-
-    /* Attach port-specified shared libraries and launch port-specific tasks */
-    _port_init();
-
-    /* And perform our init task shores, which are neverending. */
-    {
-       port_t *pubport;
-
-       if ((pubport = port_create("INIT")) != NULL) {
-           port_t *ports[] = {
-               pubport
-           };
-           register message_t *msg;
-
-           /* Currently just reply to any message we get and do nothing */
-           for (;;) {
-               if ((port_wait(ports, 1, NULL)) == pubport) {
-                   while ((msg = port_get(pubport)) != NULL)
-                       port_reply(msg);
-               }
-           }
-       }
-    }
-
-    /* XXX We actually could safely die here for now, but don't want to.
-     * Eventually we will make sure that the tasks remain running, and
-     * restart tasks which are marked to be persistant if they ever die.
-     */
-    /* NOTREACHED */
-    return 0;
-}
-
-
-/* This consists of the reaper task, which is started by Xisop init task.
- * Our duty consists of sleeping, but to free the tasks which are on the
- * dead queue, if any, when wakeing up. The only event which awakes us up
- * consists of the task_end() function. As tasks may have alot of resources
- * to free back to the system, it is a good idea to have this task dedicating
- * it's own CPU time to do it, it releives all other tasks, as well as the
- * kernel from having to.
- */
-/* ARGSUSED */
-static int task_reaper(void *res, void *args)
-{
-    /* Register ourselves for task_end() */
-    root->task_reaper = CURTASK();
-
-    for (;;) {
-       task_sleep(CURTASK(), TSF_KERNEL, NULL);
-       /* We were awaken by task_end() */
-       for (;;) {
-           register task_t *task;
-
-           SCHED_DISABLE();
-           task = DLIST_TOP(&root->tasks_dead);
-           SCHED_ENABLE();
-           if (task != NULL) {
-               /* Free this task and let some CPU time to others */
-               task_free(task);
-               _yield(NULL);
-           } else
-               break;
-       }
-    }
-
-    /* NOTREACHED */
-    return 0;
-}
diff --git a/Xisop/src/common/kernel/task.h b/Xisop/src/common/kernel/task.h
deleted file mode 100644 (file)
index ea9f069..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* $Id: task.h,v 1.2 2004/01/19 18:07:11 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_TASK_H
-#define KERNEL_TASK_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/signal.h>
-#include <common/kernel/port.h>
-#include <common/kernel/device.h>
-#include <common/kernlib/string.h>
-#include <common/kernlib/list.h>
-#include <processor/support.h>
-/*#include <kern/handler.h>    XXX I must be able to include this!*/
-
-
-
-/* Useful macro to be used in kernel code */
-#define CURTASK()              (root->curtask)
-
-
-
-/* task.state */
-#define STATE_START            0
-#define STATE_READY            1
-#define STATE_WAIT             2
-#define STATE_DEAD             3       /* To be removed */
-#define STATE_RUN              4
-
-/* task.flags and tn_message.event */
-#define TF_KERNEL              (1 << 0)        /* Kernelspace task */
-#define TF_SYSTEM              (1 << 1)        /* A system task */
-#define TF_DEVICE              (1 << 2)        /* Task is a device */
-#define TF_HANDLER             (1 << 3)        /* Task is a handler */
-#define TF_OS                  (1 << 4)        /* OS resident task */
-#define TF_SHARED              (1 << 5)        /* Shares mpool_t w/ parent */
-
-/* some defined values for task.priority */
-#define PRI_MAX                        127     /* highest priority */
-#define PRI_DEFAULT            0       /* default priority for normal tasks */
-#define PRI_MIN                        -127    /* lowest priority */
-
-
-
-/* Task's allocated resources */
-struct resources {
-    list_t ports;              /* Linked via port_t->tasknode */
-    list_t devices;            /* Linked via device_t->tasknode */
-    devicenode_t *device;      /* If we are a device */
-    /*handlernode_t *handler;*/        /* If we are a handler */
-};
-
-/* XXX Don't know if this will be useful/required yet */
-/* These, similarly to the task's memory pool, will only be freed once the
- * parent task is freed, in case it has threads.
- * XXX hmm I think that the message ports cannot be shared among threads, since
- * they require a signal bit, allocated on the specific task!
- * now would signal shareing be wanted? several tasks would then be awaken
- * by the same signal. I doubt we want this on xisop.
- */
-/*
-struct procstate {
-       lock *currentdir;
-       lock *in;
-       lock *out;
-       lock *err;
-       struct handlerpacket pkt;
-       struct msgport *pktrp;
-};
-*/
-
-/* This is a task node, as the kernel sees it. */
-struct task {
-    /* Tasks use the primary node for swapping */
-    pnode_t node;
-    /* User multipurpose node */
-    node_t usernode;
-
-    /* Validity sceal */
-    u_int32_t object_magic;
-
-    /* Info */
-    u_int32_t sleepflags;
-    u_int8_t flags;
-    u_int8_t state;
-
-    /* Credits are given according to priority by the scheduler */
-    priority_t priority, credits;
-
-    /* Signal */
-    sigmask_t sigalloc, sigwait, sigrecv;
-    /* XXX sigfunc sighandlers[32]; */
-
-    /* Entry point and parameters/results */
-    int (*start)(void *, void *);
-    void *res, *args;
-    int rescode;
-
-    /* Context */
-    page_t *stack;
-    size_t stacksize;
-    _ctx_t ctx;
-
-    /* Memory pool, which can be shared or unique */
-    mpool_t *mpool;
-
-    /* Resources we have opened which need special handling other than
-     * freeing the memory they allocated.
-     */
-    struct resources resources;
-};
-
-
-
-task_t *task_alloc(int (*)(void *, void *), void *, void *, priority_t,
-       size_t, u_int8_t);
-task_t *task_free(task_t *);
-bool task_start(task_t *);
-bool task_end(task_t *);
-priority_t task_getpriority(task_t *);
-priority_t task_setpriority(task_t *, priority_t);
-
-int task_init(void *, void *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/clean.sh b/Xisop/src/common/kernlib/clean.sh
deleted file mode 100755 (executable)
index c8bd473..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../generic_makedefs.sh
-
-cleanlib .
-cleanlib string
-show $L_RM ar/*.a
diff --git a/Xisop/src/common/kernlib/fifo.h b/Xisop/src/common/kernlib/fifo.h
deleted file mode 100644 (file)
index 3e4cc71..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* $Id: fifo.h,v 1.2 2004/06/04 19:03:36 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_FIFO_H
-#define KERNLIB_FIFO_H
-
-
-
-#include <common/types.h>
-
-
-
-/* Allows to create a new fifo_t type structure, to fit any data type */
-#define FIFO_DEFINE(n, o)      typedef struct n {                      \
-    o *top, *bottom, *head, *tail;                                     \
-    u_int32_t size;                                                    \
-} n
-
-FIFO_DEFINE(fifo8_t, u_int8_t);
-FIFO_DEFINE(fifo16_t, u_int16_t);
-FIFO_DEFINE(fifo32_t, u_int32_t);
-FIFO_DEFINE(fifo64_t, u_int64_t);
-
-
-
-/* Initializes a FIFO */
-#define FIFO_INIT(f, b, s)     do {                                    \
-    (f)->top = (f)->head = (f)->tail = (b);                            \
-    (f)->bottom = &((b)[(s)]);                                         \
-    (f)->size = (s) - 1;                                               \
-} while (/* CONSTCOND */0)
-
-/* Used to compute the next location of a tail or head pointer, accounting
- * for the necessary occasional rotation.
- */
-#define FIFO_NEXT(f, p)        (&((p)[1]) == (f)->bottom ? (f)->top : &((p)[1]))
-
-/* Returns TRUE if the FIFO is full, that is, cannot hold more elements */
-#define FIFO_FULL(f)           (FIFO_NEXT((f), (f)->head) == (f)->tail)
-
-/* Returns TRUE if the FIFO is empty */
-#define FIFO_EMPTY(f)          ((f)->head == (f)->tail)
-
-/* Returns the number of currently held elements into a FIFO */
-#define FIFO_STAT(f)           (FIFO_EMPTY(f) ? 0 :                    \
-       (f)->head - (f)->tail > 0 ?                                     \
-           ((f)->head - (f)->tail) / sizeof(*(f)->head):               \
-               ((f)->size - ((f)->tail - (f)->head)) / sizeof(*(f)->head))
-
-#define FIFO_AVAIL(f)          ((f)->size - FIFO_STAT(f))
-
-#define FIFO_FLUSH(f)          ((f)->tail = (f)->head)
-
-/* If no available room the oldest element is lost. The caller may verify
- * with FIFO_FULL() first if needed.
- */
-#define FIFO_PUT(f, e)         do {                                    \
-    *(f)->head = *(e);                                                 \
-    (f)->head = FIFO_NEXT((f), (f)->head);                             \
-    if (FIFO_EMPTY(f))                                                 \
-       (f)->tail = FIFO_NEXT((f), (f)->tail);                          \
-} while (/* CONSTCOND */0)
-
-/* Has no action if the buffer has no more elements, but does not return any
- * result to say so. The caller may use FIFO_EMPTY() to check if needed.
- */
-#define FIFO_GET(f, e)         do {                                    \
-    if (!FIFO_EMPTY(f)) {                                              \
-       *(e) = *(f)->tail;                                              \
-       (f)->tail = FIFO_NEXT((f), (f)->tail);                          \
-    }                                                                  \
-} while (/* CONSTCOND */0)
-
-#define FIFO_FIND(f, p, e)     do {                                    \
-    register typeof(*(e)) *r;                                          \
-                                                                       \
-    *(p) = NULL;                                                       \
-    for (r = (f)->tail; r != (f)->head; r = FIFO_NEXT(f, r))           \
-       if (*r == *(e)) {                                               \
-           *(p) = r;                                                   \
-           break;                                                      \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-/* XXX Those are bugged for now */
-#define FIFO_ALLOC(f, p, a, s) do {                                    \
-    register int r;                                                    \
-                                                                       \
-    if ((r = (f)->tail - (f)->head) != 0) {                            \
-       if (r < 1)                                                      \
-           r = (f)->bottom - (f)->head;                                \
-       if ((r /= sizeof(*(f)->head)) > (int)(s))                       \
-           r = (int)(s);                                               \
-       *(p) = (f)->head;                                               \
-       (f)->head = (&((f)->head[r]) == (f)->bottom ? (f)->top :        \
-           &((f)->head[r]));                                           \
-    }                                                                  \
-    *(a) = (size_t)r;                                                  \
-} while (/* CONSTCOND */0)
-
-#define FIFO_FREE(f, p, a, s)  do {                                    \
-    register int r;                                                    \
-                                                                       \
-    if ((r = (f)->head - (f)->tail) != 0) {                            \
-       if (r < 1)                                                      \
-           r = (f)->bottom - (f)->tail;                                \
-       if ((r /= sizeof(*(f)->tail)) > (int)(s))                       \
-           r = (int)(s);                                               \
-       *(p) = (f)->tail;                                               \
-       (f)->tail = (&((f)->tail[r]) == (f)->bottom ? (f)->top :        \
-           &((f)->tail[r]));                                           \
-    }                                                                  \
-    *(a) = (size_t)r;                                                  \
-} while (/* CONSTCOND */0)
-
-#define FIFO_WRITE(f, p, a, s) do {                                    \
-    /* XXX */                                                          \
-} while (/* CONSTCOND */0)
-
-#define FIFO_READ(f, p, a, s)  do {                                    \
-    /* XXX */                                                          \
-} while (/* CONSTCOND */0)
-
-
-
-size_t getnfifo8(u_int8_t *, fifo8_t *, size_t);
-size_t putnfifo8(fifo8_t *, u_int8_t *, size_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/hash.c b/Xisop/src/common/kernlib/hash.c
deleted file mode 100644 (file)
index c652405..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/* $Id: hash.c,v 1.6 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software written by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/debug.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/object.h>
-#include <common/kernlib/list.h>
-#include <common/kernlib/hash.h>
-
-
-
-/* This system is safe to use 32-bit hashes internally, despite the possibility
- * for collisions. We maintain an array or buckets, within which the entries
- * are distributed. A 32-bit hash collision entry will end up on the same
- * bucket. We however also make sure to not allow to store exact duplicate
- * keys. The number if buckets will increase and decrease whenever the system
- * detects that it becomes necessary for efficiency. The larger the number of
- * buckets, the less nodes are likely to coexist in each bucket. The bucket
- * index to use is evaluated using a modulo to convert the 32-bit hash to
- * fit into the current number of buckets in the table. Of course, when
- * the number of buckets is to be updated (which ideally happens rarely),
- * the entries are rehashed to be properly indexed within the new capacity.
- *
- * The number of buckets is automatically doubled when the table fills up
- * at a factor of 1. This way, we avoid having to calculate a fill factor
- * using floating point arithmetic. Commonly used value for the initial hash
- * table bucket capacity is 16, which are set HT_DEFAULT_CAPACITY represents.
- *
- * Searching for a key by pattern, which requires iterating through the
- * nodes, rather than through it's absolute key can actually be a little
- * slower than running through a simple linked list of absolute hash values,
- * since all buckets must be scanned. However, we ensure to stop running
- * through buckets when the total number of mappings have been scanned already.
- * Lookups using the absolute key of the node will be much faster in the case
- * where the hash table grows considerably, however.
- */
-
-
-
-#define HASH_INDEX(h, s)       ((h) % (s))
-
-
-
-static void hashtable_rehash(hashtable_t *, unsigned int);
-
-
-
-bool hashtable_init(hashtable_t *t, const char *label,
-       unsigned int initialcapacity, void *(*allocfunc)(size_t),
-       void (*freefunc)(void *),
-       int (*keycomp)(const void *, const void *, size_t),
-       u_int32_t (*keyhash)(const void *, size_t), bool dynamic)
-{
-    if (!OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       if ((t->array = allocfunc(sizeof(list_t) * initialcapacity)) != NULL) {
-           unsigned int i;
-
-           OBJECT_VALIDATE(t, OBJECT_HASHTABLE);
-           t->label = label;
-           t->malloc = allocfunc;
-           t->free = freefunc;
-           t->keycomp = keycomp;
-           t->keyhash = keyhash;
-           t->nodes = 0;
-           t->initial = t->capacity = initialcapacity;
-           t->avgtotal = t->avgcnt = initialcapacity;
-           t->dynamic = dynamic;
-           t->iterating = FALSE;
-           for (i = 0; i < initialcapacity; i++)
-               DLIST_INIT(&(t->array[i]));
-
-           return TRUE;
-       } else
-           DEBUG_PRINTF("* %T hashtable_init(%p = %s) - malloc(%d)\n",
-                   label, t, (int)sizeof(list_t) * initialcapacity);
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_init(%p = %s) - Table already initialized",
-               label, t);
-
-    return FALSE;
-}
-
-
-void hashtable_destroy(hashtable_t *t, bool freeall)
-{
-    if (OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       if (t->array != NULL) {
-           if (freeall) {
-               register unsigned int i, done;
-               register list_t *l;
-               register hashnode_t *k, *kt;
-
-               for (i = done = 0; done < t->nodes && i < t->capacity; i++) {
-                   l = &(t->array[i]);
-                   if (DLIST_NODES(l) > 0) {
-                       for (k = DLIST_TOP(l); k != NULL; k = kt) {
-                           kt = DLIST_NEXT(k);
-                           pool_free((pnode_t *)k);
-                           done++;
-                       }
-                   }
-               }
-           }
-           t->free(t->array);
-       }
-       OBJECT_INVALIDATE(t);
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_destroy(%p) - Invalid hashtable_t pointer",
-               t);
-}
-
-
-hashnode_t *hashtable_lookup(hashtable_t *t, const void *key, size_t keysize)
-{
-    register u_int32_t hash;
-    register unsigned int i;
-    register list_t *l;
-    register hashnode_t *k = NULL;
-
-    if (OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       hash = t->keyhash(key, keysize);
-       i = HASH_INDEX(hash, t->capacity);
-       l = &(t->array[i]);
-       if (DLIST_NODES(l) > 0) {
-           DLIST_FOREACH(l, k) {
-               if (k->hash == hash && k->keysize == keysize &&
-                       t->keycomp(k->key, key, keysize) == 0)
-                   break;
-           }
-       }
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_lookup(%p) - Invalid hashtable_t pointer",
-               t);
-
-    return k;
-}
-
-
-bool hashtable_link(hashtable_t *t, hashnode_t *k, const void *key,
-       size_t keysize, bool check)
-{
-    register u_int32_t hash;
-    register unsigned int i;
-    register list_t *l;
-    bool ok = TRUE;
-
-    if (!OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       DEBUG_PRINTF("* %T hashtable_link(%p) - Invalid hashtable_t pointer",
-               t);
-       return FALSE;
-    }
-    if (k == NULL) {
-       DEBUG_PRINTF(
-               "* %T hashtable_link(NULL) - Table (%p = %s) Invalid "
-               "hashnode_t pointer",
-               t, t->label);
-       return FALSE;
-    }
-
-    hash = t->keyhash(key, keysize);
-    i = HASH_INDEX(hash, t->capacity);
-    l = &(t->array[i]);
-    if (check) {
-       /* We do not allow exact duplicates, so verify first. Duplicate
-        * hashes are fine, however, as long as the key data is not identical.
-        */
-       if (DLIST_NODES(l) > 0) {
-           register hashnode_t *tk;
-
-           DLIST_FOREACH(l, tk) {
-               if (tk == k || (tk->hash == hash && tk->keysize == keysize &&
-                           t->keycomp(tk->key, key, keysize) == 0)) {
-                   DEBUG_PRINTF(
-                           "* %T hashtable_link(%p = %s, %p) - Duplicate key "
-                           "insert attempt", t, t->label, k);
-                   ok = FALSE;
-                   break;
-               }
-           }
-       }
-    }
-    if (ok) {
-       OBJECT_VALIDATE(k, OBJECT_HASHNODE);
-       k->hash = hash;
-       k->list = l;
-       k->key = key;
-       k->keysize = keysize;
-       DLIST_INSERT(l, (node_t *)k);
-       /* Grow capacity if necessary */
-       t->nodes++;
-       if (t->dynamic && !t->iterating) {
-           if (t->dynamic && !t->iterating)
-               hashtable_rehash(t, t->capacity * 2);
-       }
-    }
-
-    return ok;
-}
-
-
-void hashtable_unlink(hashtable_t *t, hashnode_t *k)
-{
-    if (OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       if (OBJECT_VALID(k, OBJECT_HASHNODE)) {
-           unsigned int exceeding;
-
-           OBJECT_INVALIDATE(k);
-           DLIST_UNLINK(k->list, (node_t *)k);
-           k->list = NULL;
-           t->nodes--;
-
-           /* Verify if the capacity should be reduced, using statistics */
-           t->avgtotal += t->capacity;
-           t->avgcnt++;
-           if (t->avgcnt > t->capacity / (t->initial * 3)) {
-               t->avgcnt = 1;
-               t->avgtotal = t->capacity;
-           }
-           /* Rehash with a smaller capacity if necessary */
-           if (t->dynamic && !t->iterating) {
-               if ((exceeding = t->capacity - (t->avgtotal / t->avgcnt)) > 0)
-                   hashtable_rehash(t, t->capacity - exceeding);
-           }
-       } else
-           DEBUG_PRINTF(
-                   "* %T hashtable_unlink(%p) - Table (%p = %s) Invalid "
-                   "hashnode_t pointer",
-                   k, t, t->label);
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_unlink(%p) - Invalid hashtable_t pointer",
-               t);
-}
-
-
-/* Note that as the user generally has a pool_t dedicated to the hashnode_t
- * elements for a particular table, it may be more efficient to not use
- * the <freeall> option and to pool_free() which does not need to iterate
- * through nodes. This function has to however, because it obviously cannot
- * assume that the caller wishes to free all nodes of the origin pool_t, or
- * that all entries origin from the same pool_t.
- */
-void hashtable_empty(hashtable_t *t, bool freeall)
-{
-    register unsigned int i;
-    register list_t *l;
-    register hashnode_t *k, *kt;
-
-    if (OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       if (freeall) {
-           for (i = 0; i < t->capacity; i++) {
-               l = &(t->array[i]);
-               if (DLIST_NODES(l) > 0) {
-                   for (k = DLIST_TOP(l); k != NULL; k = kt) {
-                       kt = DLIST_NEXT(k);
-                       pool_free((pnode_t *)k);
-                   }
-               }
-           }
-       } else {
-           for (i = 0; i < t->capacity; i++)
-               DLIST_INIT(&(t->array[i]));
-       }
-       if (t->dynamic && !t->iterating)
-           hashtable_rehash(t, t->initial);
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_empty(%p) - Invalid hashtable_t pointer",
-               t);
-}
-
-
-void hashtable_iterate(hashtable_t *t,
-       bool (*func)(hashnode_t *, void *), void *udata)
-{
-    register unsigned int i;
-    register list_t *l;
-    register hashnode_t *k, *kt;
-
-    if (OBJECT_VALID(t, OBJECT_HASHTABLE)) {
-       if (t->nodes > 0) {
-           t->iterating = TRUE;
-           for (i = 0; i < t->capacity; i++) {
-               l = &(t->array[i]);
-               if (DLIST_NODES(l) > 0) {
-                   /* Note that we use a temporary variable to hold the next
-                    * key, in case the user function alters the key node
-                    * (i.e. unlinks it)
-                    */
-                   for (k = DLIST_TOP(l); k != NULL; k = kt) {
-                       kt = DLIST_NEXT(k);
-                       if (!func(k, udata)) {
-                           t->iterating = FALSE;
-                           return;
-                       }
-                   }
-               }
-           }
-           t->iterating = FALSE;
-       }
-    } else
-       DEBUG_PRINTF(
-               "* %T hashtable_iterate(%p) - Invalid hashtable_t pointer",
-               t);
-}
-
-
-/* Rehashes the whole hashtable so that the capacity may be changed to the
- * specified one. The memory area is also automatically changed. Ideally,
- * this only occurs rarely. If it fails because of a lack of memory, the
- * hash table will simply not be affected, but lookups will become slower.
- */
-static void hashtable_rehash(hashtable_t *t, unsigned int newcapacity)
-{
-    list_t *newarray;
-
-    if ((newarray = t->malloc(sizeof(list_t) * newcapacity)) != NULL) {
-       register unsigned int i, done;
-
-       for (i = 0; i < newcapacity; i++)
-           DLIST_INIT(&newarray[i]);
-
-       for (i = done = 0; done < t->nodes && i < t->capacity; i++) {
-           register hashnode_t *k, *kt;
-           register list_t *l, *newl;
-
-           l = &(t->array[i]);
-           if (DLIST_NODES(l) > 0) {
-               for (k = DLIST_TOP(l); k != NULL; k = kt) {
-                   kt = DLIST_NEXT(k);
-                   newl = &newarray[HASH_INDEX(k->hash, newcapacity)];
-                   DLIST_SWAP(newl, l, (node_t *)k, TRUE);
-                   k->list = newl;
-                   done++;
-               }
-           }
-       }
-
-       t->capacity = newcapacity;
-       t->free(t->array);
-       t->array = newarray;
-    }
-}
diff --git a/Xisop/src/common/kernlib/hash.h b/Xisop/src/common/kernlib/hash.h
deleted file mode 100644 (file)
index ed04553..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* $Id: hash.h,v 1.5 2004/06/04 02:15:47 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_HASH_H
-#define KERNLIB_HASH_H
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernlib/list.h>
-
-
-
-struct hashnode {
-    pnode_t node;
-    u_int32_t object_magic, hash;
-    list_t *list;
-    const void *key;
-    size_t keysize;
-    /* Custom user data will follow, uncluding the key element to which the
-     * previous key pointer is expected to point.
-     */
-};
-
-struct hashtable {
-    pnode_t node;      /* In case we want a pool_t of hashtable_t */
-    u_int32_t object_magic;
-    unsigned int initial, capacity, nodes;
-    const char *label;
-    list_t *array;
-    void *(*malloc)(size_t);
-    void (*free)(void *);
-    int (*keycomp)(const void *, const void *, size_t);
-    u_int32_t (*keyhash)(const void *, size_t);
-    unsigned int avgtotal, avgcnt;
-    bool dynamic, iterating;
-};
-
-
-
-#define HT_DEFAULT_CAPACITY    16
-
-#define HASHTABLE_NODES(t)     ((t)->nodes)
-
-
-
-bool hashtable_init(hashtable_t *, const char *, unsigned int,
-       void *(*)(size_t), void (*)(void *),
-       int (*)(const void *, const void *, size_t),
-       u_int32_t (*)(const void *, size_t), bool);
-void hashtable_destroy(hashtable_t *, bool);
-hashnode_t *hashtable_lookup(hashtable_t *, const void *, size_t);
-bool hashtable_link(hashtable_t *, hashnode_t *, const void *, size_t, bool);
-void hashtable_unlink(hashtable_t *, hashnode_t *);
-void hashtable_empty(hashtable_t *, bool);
-void hashtable_iterate(hashtable_t *, bool (*)(hashnode_t *, void *),
-       void *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/lifo.h b/Xisop/src/common/kernlib/lifo.h
deleted file mode 100644 (file)
index ae9e260..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $Id: lifo.h,v 1.3 2004/06/04 19:14:07 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_LIFO_H
-#define KERNLIB_LIFO_H
-
-
-
-#include <common/types.h>
-
-
-
-/* LIFO_DEFINE(lifotypename, objecttype); */
-#define LIFO_DEFINE(n, o)      typedef struct n {                      \
-    u_int32_t size, elements;                                          \
-    o *buffer, *endbuffer, *head;                                      \
-} n
-
-/* Because of the way this is implemented using macros, it would also be
- * possible to provide lifo types to hold structures.
- */
-LIFO_DEFINE(lifo8_t, u_int8_t);
-LIFO_DEFINE(lifo16_t, u_int16_t);
-LIFO_DEFINE(lifo32_t, u_int32_t);
-LIFO_DEFINE(lifo64_t, u_int64_t);
-
-
-
-/* XXX Although it's great to use macros for these operations, it also
- * prevents assembly functions to be provided to replace them.
- */
-/* void LIFO_INIT(lifo*_t *, u_int*_t *, u_int32_t); */
-#define LIFO_INIT(f, b, s)     do {                                    \
-    (f)->size = (s);                                                   \
-    (f)->elements = 0;                                                 \
-    (f)->buffer = (f)->endbuffer = (f)->head = (b);                    \
-} while (/* CONSTCOND */0)
-
-/* bool LIFO_FULL(lifo*_t *); */
-#define LIFO_FULL(f)   ((f)->elements == (f)->size)
-
-/* u_int32_t LIFO_STAT(lifo*_t *); */
-#define LIFO_STAT(f)   ((f)->elements)
-
-/* void LIFO_FLUSH(lifo*_t *); */
-#define LIFO_FLUSH(f)  do {                                            \
-    (f)->head = (f)->buffer;                                           \
-    (f)->elements = 0;                                                 \
-} while (/* CONSTCOND */0)
-
-/* void LIFO_PUT(lifo*_t *, u_int*_t *); */
-#define LIFO_PUT(s, e) do {                                            \
-    if ((s)->elements < (s)->size) {                                   \
-       *((s)->head++) = *(e);                                          \
-       (s)->elements++;                                                \
-    }                                                                  \
-} while (/* CONSTCOND */0)
-
-/* void LIFO_GET(lifo*_t *, u_int*_t *); */
-#define LIFO_GET(s, e) do {                                            \
-    if ((s)->elements > 0) {                                           \
-       *(e) = *(--(s)->head);                                          \
-       (s)->elements--;                                                \
-    }                                                                  \
-} while (/* CONSTCOND */0)
-
-/* LIFO_ALLOC(lifo*_t *, u_int*_t **, size_t *); */
-
-/* LIFO_FREE(lifo*_t, u_int*_t **, size_t *); */
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/list.h b/Xisop/src/common/kernlib/list.h
deleted file mode 100644 (file)
index ebb8bd1..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* $Id: list.h,v 1.5 2004/06/04 19:14:07 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNEL_LIST_H
-#define KERNEL_LIST_H
-
-
-
-#include <common/types.h>
-
-
-
-typedef struct list    list_t;
-typedef struct node    node_t;
-
-
-
-struct node {
-    node_t *prev, *next;
-};
-
-struct list {
-    node_t *top, *bottom;
-    u_int32_t nodes;
-};
-
-
-
-/* Some macros to optimize operations on doubly linked lists */
-#define DLIST_INITIALIZER      {NULL, NULL, 0}
-
-#define DLIST_INIT(lst)                do {                                    \
-    (lst)->top = (lst)->bottom = NULL;                                 \
-    (lst)->nodes = 0;                                                  \
-} while (/* CONSTCOND */0)
-
-#define DLIST_UNLINK(lst, nod) do {                                    \
-    register node_t *prev = (nod)->prev, *next = (nod)->next;          \
-                                                                       \
-    if (prev != NULL)                                                  \
-       prev->next = next;                                              \
-    else                                                               \
-       (lst)->top = next;                                              \
-    if (next != NULL)                                                  \
-       next->prev = prev;                                              \
-    else                                                               \
-       (lst)->bottom = prev;                                           \
-    (lst)->nodes--;                                                    \
-} while (/* CONSTCOND */0)
-
-#define DLIST_APPEND(lst, nod) do {                                    \
-    register node_t *tmp = (lst)->bottom;                              \
-                                                                       \
-    if (tmp != NULL) {                                                 \
-       tmp->next = (nod);                                              \
-       (nod)->prev = tmp;                                              \
-       (nod)->next = NULL;                                             \
-       (lst)->bottom = (nod);                                          \
-    } else {                                                           \
-       (lst)->bottom = (lst)->top = (nod);                             \
-       (nod)->next = (nod)->prev = NULL;                               \
-    }                                                                  \
-    (lst)->nodes++;                                                    \
-} while (/* CONSTCOND */0)
-
-#define DLIST_INSERT(lst, nod) do {                                    \
-    register node_t *tmp = (lst)->top;                                 \
-                                                                       \
-    if (tmp != NULL) {                                                 \
-       tmp->prev = (nod);                                              \
-       (nod)->prev = NULL;                                             \
-       (nod)->next = tmp;                                              \
-       (lst)->top = (nod);                                             \
-    } else {                                                           \
-       (lst)->top = (lst)->bottom = (nod);                             \
-       (nod)->next = (nod)->prev = NULL;                               \
-    }                                                                  \
-    (lst)->nodes++;                                                    \
-} while (/* CONSTCOND */0)
-
-#define DLIST_INSERTAT(lst, atnode, nod) do {                          \
-    register node_t *prev = (atnode)->prev, *next = (atnode);          \
-                                                                       \
-    (nod)->next = next;                                                        \
-    next->prev = (nod);                                                        \
-    if (prev != NULL) {                                                        \
-       prev->next = (nod);                                             \
-       (nod)->prev = prev;                                             \
-    } else {                                                           \
-       (lst)->top = (nod);                                             \
-       (nod)->prev = NULL;                                             \
-    }                                                                  \
-    (lst)->nodes++;                                                    \
-} while (/* CONSTCOND */0)
-
-#define DLIST_SWAP(dst, src, nod, ins) do {                            \
-    register node_t *prev = (nod)->prev, *next = (nod)->next;          \
-                                                                       \
-    if (prev != NULL)                                                  \
-       prev->next = next;                                              \
-    else                                                               \
-       (src)->top = next;                                              \
-    if (next != NULL)                                                  \
-       next->prev = prev;                                              \
-    else                                                               \
-       (src)->bottom = prev;                                           \
-    (src)->nodes--;                                                    \
-    if ((ins)) {                                                       \
-       if ((prev = (dst)->top) != NULL) {                              \
-           prev->prev = (nod);                                         \
-           (nod)->prev = NULL;                                         \
-           (nod)->next = prev;                                         \
-           (dst)->top = (nod);                                         \
-       } else {                                                        \
-           (dst)->top = (dst)->bottom = (nod);                         \
-           (nod)->next = (nod)->prev = NULL;                           \
-       }                                                               \
-    } else {                                                           \
-       if ((prev = (dst)->bottom) != NULL) {                           \
-           prev->next = (nod);                                         \
-           (nod)->prev = prev;                                         \
-           (nod)->next = NULL;                                         \
-           (dst)->bottom = (nod);                                      \
-       } else {                                                        \
-           (dst)->bottom = (dst)->top = (nod);                         \
-           (nod)->next = (nod)->prev = NULL;                           \
-       }                                                               \
-    }                                                                  \
-    (dst)->nodes++;                                                    \
-} while (/* CONSTCOND */0)
-
-#define DLIST_TOP(lst)         ((void *)((list_t *)(lst))->top)
-#define DLIST_BOTTOM(lst)      ((void *)((list_t *)(lst))->bottom)
-#define DLIST_NEXT(var)                ((void *)((node_t *)(var))->next)
-#define DLIST_PREV(var)                ((void *)((node_t *)(var))->prev)
-
-#define DLIST_FOREACH(lst, var)                                                \
-    for ((var) = DLIST_TOP((lst)); (var) != NULL; (var) = DLIST_NEXT((var)))
-
-#define DLIST_NODES(lst)       (((list_t *)(lst))->nodes)
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/make.sh b/Xisop/src/common/kernlib/make.sh
deleted file mode 100755 (executable)
index 0bf7318..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../makedefs.sh
-
-buildlib string
-show $C_AR ar/string.a string/*.o
-show $C_RANLIB ar/string.a
-
-buildlib .
-show $C_AR ar/kernlib.a *.o
-show $C_RANLIB ar/kernlib.a
diff --git a/Xisop/src/common/kernlib/rand.c b/Xisop/src/common/kernlib/rand.c
deleted file mode 100644 (file)
index f2071fe..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* $Id: rand.c,v 1.2 2004/01/29 04:56:50 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software written by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Algorithm was borrowed from:
- *      Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
- * "Random number generators: good ones are hard to find",
- * Park and Miller, Communications of the ACM, vol. 31, no. 10,
- * October 1988, p. 1195.
- *
- * The 10,000nth invokation with default initial seed of 1 should result
- * in 1043618065. Of course, this is a highly predictable algorithm, but
- * it is rather well distributed, while also being quite fast, and is thus
- * suitable in the implementation of ANSI/C89 rand(3)/srand(3) functions.
- * Do NOT use for cryptography related work.
- *  Matt
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/rand.h>
-
-
-
-static unsigned int global_seed = 1;
-
-
-
-int rand(void)
-{
-    /*
-    register int a, b;
-
-    a = b = (signed int)global_seed;
-    a /= 127773;
-    b %= 127773;
-
-    b *= 16807;
-    a *= 2836;
-    b -= a;
-    if (b <= 0)
-       b += 0x7fffffff;
-
-    global_seed = b;
-
-    return b;
-    */
-
-    int v;
-
-    if ((v = (global_seed % 127773 * 16807) -
-               (global_seed / 127773 * 2836)) < 1)
-       v += 0x7fffffff;
-    global_seed = v;
-
-    return v;
-}
-
-
-void srand(unsigned int seed)
-{
-    global_seed = seed;
-}
-
-
-/* This is the POSIX reentrant variant where caller supplies seed */
-int rand_r(unsigned int *seed)
-{
-    int v;
-
-    if ((v = (*seed % 127773 * 16807) - (*seed / 127773 * 2836)) < 1)
-       v += 0x7fffffff;
-    *seed = v;
-
-    return v;
-}
diff --git a/Xisop/src/common/kernlib/rand.h b/Xisop/src/common/kernlib/rand.h
deleted file mode 100644 (file)
index 29ed498..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Id: rand.h,v 1.1 2004/01/29 04:55:06 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software written by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_RAND_H
-#define KERNLIB_RAND_H
-
-
-
-#include <common/types.h>
-
-
-
-int rand(void);
-void srand(unsigned int);
-int rand_r(unsigned int *);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/setjmp.h b/Xisop/src/common/kernlib/setjmp.h
deleted file mode 100644 (file)
index e19e520..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id: setjmp.h,v 1.1 2004/01/30 07:01:24 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_SETJMP_H
-#define KERNLIB_SETJMP_H
-
-
-
-/* These functions, as well as _ctx_t are defined by the processor-specific
- * support headerfile, <processor/support.h>. These are the C89/ANSI
- * setjmp()/longjmp().
- */
-
-
-
-#include <common/types.h>
-#include <processor/support.h>
-
-
-
-typedef _ctx_t jmp_buf[1];
-
-
-
-int setjmp(jmp_buf);
-void longjmp(jmp_buf, int);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/string.h b/Xisop/src/common/kernlib/string.h
deleted file mode 100644 (file)
index cba5365..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* $Id: string.h,v 1.3 2004/06/03 05:40:46 mmondor Exp $ */
-
-/*
- * Copyright (C) 1989-2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef KERNLIB_STRING_H
-#define KERNLIB_STRING_H
-
-
-
-#include <common/types.h>
-#include <processor/support.h>
-
-
-
-/* This is used for some kernel strings, such as public message port names */
-typedef struct bstr {
-    size_t size, len;  /* Maximum and current lengths */
-    u_int8_t data[1];  /* Actual buffer follows */
-} bstr_t;
-
-
-bstr_t *bstr_alloc(size_t);
-bstr_t *bstr_new(const char *, size_t, bool);
-bstr_t *bstr_free(bstr_t *);
-
-
-
-/* More conventional string functions */
-size_t strlen(const char *);
-size_t strnlen(const char *, size_t);
-
-char *_strcpy(char *, const char *);
-size_t _strncpy(char *, const char *, size_t);
-
-char *_strcat(char *, const char *);
-char *_strncat(char *, const char *, size_t);
-
-int strcmp(const char *, const char *);
-int strncmp(const char *, const char *, size_t);
-
-char *strchr(const char *, int);
-char *strnchr(const char *, int, size_t);
-char *strrchr(const char *, int);
-char *strnrchr(const char *, int, size_t);
-
-char *_strdup(const char *);
-char *_strndup(const char *, size_t);
-
-int straspl(char **, char *, int);
-int strspl(char **, char *, int, char);
-
-int strcasecmp(const char *, const char *);
-int strncasecmp(const char *, const char *, size_t);
-void _strlower(char *);
-void _strupper(char *);
-u_int32_t _strpack32(const char *, size_t);
-u_int32_t _memcasehash32(const void *, size_t);
-int _memcasecmp(const void *, const void *, size_t);
-
-u_int32_t htol(const char *);
-void _strrev(char *);
-u_int32_t memhash32(const void *, size_t);
-
-#define memclr(a, l)   memset((a), 0, (l))
-int memcmp(const void *, const void *, size_t);
-void *memcpy(void *, const void *, size_t);
-void *memmove(void *, const void *, size_t);
-void *memset(void *, int, size_t);
-void pageclr(void *, u_int32_t);
-
-
-
-#endif
diff --git a/Xisop/src/common/kernlib/string/_strcat.c b/Xisop/src/common/kernlib/string/_strcat.c
deleted file mode 100644 (file)
index f431a05..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* $Id: _strcat.c,v 1.1 2004/06/03 05:40:02 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* XXX Unlike ANSI, returns pointer at end of destination rather to beginning
- * to allow special optimizations in loops.
- */
-char *_strcat(char *dest, const char *src)
-{
-    for (; *dest != '\0'; dest++) ;
-    for (; (*dest = *src++) != '\0'; dest++) ;
-
-    return (dest);
-}
diff --git a/Xisop/src/common/kernlib/string/_strcpy.c b/Xisop/src/common/kernlib/string/_strcpy.c
deleted file mode 100644 (file)
index affc726..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Id: _strcpy.c,v 1.1 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* XXX Unlike standard strcpy(), returns pointer to end of copied string in
- * destination, rather than to beginning, more useful to optimize some loops.
- * This variant should never be called strcpy() (i.e., could be called
- * _strcpy() however).
- */
-char *_strcpy(char *dest, const char *src)
-{
-    for (; (*dest = *src++) != '\0'; dest++) ;
-
-    return (dest);
-}
diff --git a/Xisop/src/common/kernlib/string/_strdup.c b/Xisop/src/common/kernlib/string/_strdup.c
deleted file mode 100644 (file)
index 76a78c9..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: _strdup.c,v 1.3 2004/06/03 05:54:44 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/main.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Uses kernel memory pool, should only be used by kernel code */
-char *_strdup(const char *str)
-{
-    char *new;
-    register const char *ptr;
-    register size_t len;
-
-    for (new = NULL, ptr = str; *ptr != '\0'; ptr++) ;
-
-    len = (size_t)(ptr - str) + 1;
-    if ((new = MALLOC(len)) != NULL)
-       (void) memcpy(new, str, len);
-
-    return new;
-}
diff --git a/Xisop/src/common/kernlib/string/_strncat.c b/Xisop/src/common/kernlib/string/_strncat.c
deleted file mode 100644 (file)
index 61115b2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: _strncat.c,v 1.1 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* XXX Unlike ANSI, returns pointer at end of destination rather to beginning
- * to allow special optimizations in loops.
- */
-char *_strncat(char *dest, const char *src, size_t max)
-{
-    if (max != 0) {
-       register const char *toptr;
-
-       for (toptr = dest, toptr += max; dest < toptr && *dest != '\0';
-               dest++) ;
-       for (; dest < toptr && (*dest = *src++) != '\0'; dest++) ;
-       if (dest < toptr)
-           *dest = '\0';
-    }
-
-    return dest;
-}
diff --git a/Xisop/src/common/kernlib/string/_strncpy.c b/Xisop/src/common/kernlib/string/_strncpy.c
deleted file mode 100644 (file)
index d9132eb..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $Id: _strncpy.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Unlike the useless return code of the standard ANSI one,
- * this function returns the number of bytes successfully copied.
- */
-size_t _strncpy(char *dest, const char *src, size_t max)
-{
-    if (max > 0) {
-       register const char *sptr;
-       register char *toptr;
-
-       for (sptr = src, toptr = dest, toptr += max;
-               dest < toptr && (*dest = *sptr) != '\0'; sptr++, dest++) ;
-       if (dest == toptr)
-           *dest = '\0';
-
-       return ((size_t)(sptr - src));
-    }
-
-    *dest = '\0';
-    return 0;
-}
diff --git a/Xisop/src/common/kernlib/string/_strndup.c b/Xisop/src/common/kernlib/string/_strndup.c
deleted file mode 100644 (file)
index 007d15e..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $Id: _strndup.c,v 1.3 2004/06/03 05:54:44 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/main.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Uses kernel memory. */
-char *_strndup(const char *str, size_t max)
-{
-    char *new;
-    register const char *ptr, *toptr;
-    size_t len;
-
-    for (toptr = ptr = str, toptr += max, new = NULL;
-           ptr < toptr && *ptr != '\0'; ptr++) ;
-    len = (size_t)(ptr - str);
-    if ((new = MALLOC(len + 1)) != NULL) {
-       (void) memcpy(new, str, len);
-       new[len] = '\0';
-    }
-
-    return new;
-}
diff --git a/Xisop/src/common/kernlib/string/_strrev.c b/Xisop/src/common/kernlib/string/_strrev.c
deleted file mode 100644 (file)
index 3019ad2..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $Id: _strrev.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Iteratively reverses the supplied string */
-void _strrev(char *str)
-{
-    register char *p1, *p2, t;
-
-    for (p1 = p2 = str; *p2; p2++) ;
-    if (p2 > p1)
-       p2--;
-
-    for (;p1 < p2; p1++, p2--) {
-       t = *p1;
-       *p1 = *p2;
-       *p2 = t;
-    }
-}
diff --git a/Xisop/src/common/kernlib/string/bstr_alloc.c b/Xisop/src/common/kernlib/string/bstr_alloc.c
deleted file mode 100644 (file)
index 34b63c6..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: bstr_alloc.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/main.h>
-
-
-
-/* This is always allocated using kernel memory, and is for use by kernel
- * functions.
- */
-bstr_t *bstr_alloc(size_t size)
-{
-    bstr_t *bstr = NULL;
-
-    if ((bstr = MALLOC(sizeof(bstr_t) + size + 1)) != NULL) {
-       bstr->size = size;
-       bstr->len = 0;
-       *bstr->data = 0;
-    }
-
-    return bstr;
-}
diff --git a/Xisop/src/common/kernlib/string/bstr_free.c b/Xisop/src/common/kernlib/string/bstr_free.c
deleted file mode 100644 (file)
index ba7b837..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* $Id: bstr_free.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-#include <common/kernel/memory.h>
-
-
-
-bstr_t *bstr_free(bstr_t *bstr)
-{
-    if (bstr != NULL)
-       FREE(bstr);
-
-    return NULL;
-}
diff --git a/Xisop/src/common/kernlib/string/bstr_new.c b/Xisop/src/common/kernlib/string/bstr_new.c
deleted file mode 100644 (file)
index 04eca59..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $Id: bstr_new.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/main.h>
-
-
-
-/* This is always allocated using kernel memory, and is for use by kernel
- * functions.
- */
-bstr_t *bstr_new(const char *string, size_t max, bool fixed)
-{
-    register bstr_t *bstr = NULL;
-    register size_t len = strnlen(string, max);
-    register size_t size;
-
-    if (fixed)
-       size = max;
-    else
-       size = len;
-
-    if ((bstr = MALLOC(sizeof(bstr_t) + size + 1)) != NULL) {
-       bstr->size = size;
-       bstr->len = len;
-       memcpy(bstr->data, string, len);
-       bstr->data[len] = 0;
-    }
-
-    return bstr;
-}
diff --git a/Xisop/src/common/kernlib/string/case.c b/Xisop/src/common/kernlib/string/case.c
deleted file mode 100644 (file)
index 4835110..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* $Id: case.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-static const unsigned char toupper_table[] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
-    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 
-    0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 
-    0x1E, 0x1F, ' ',  '!',  '"',  '#',  '$',  '%',  '&',  0x27, 
-    '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',  '0',  '1',  
-    '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',  ':',  ';',  
-    '<',  '=',  '>',  '?',  '@',  'A',  'B',  'C',  'D',  'E',  
-    'F',  'G',  'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',  
-    'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',  'X',  'Y',  
-    'Z',  '[',  0x5C, ']',  '^',  '_',  '`',  'A',  'B',  'C',  
-    'D',  'E',  'F',  'G',  'H',  'I',  'J',  'K',  'L',  'M',  
-    'N',  'O',  'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',  
-    'X',  'Y',  'Z',  '{',  '|',  '}',  '~',  0x7F, 0x80, 0x81, 
-    0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 
-    0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 
-    0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 
-    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 
-    0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 
-    0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 
-    0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 
-    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 
-    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 
-    0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 
-    0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 
-    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 
-    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-};
-
-static const unsigned char tolower_table[] = {
-    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
-    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 
-    0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 
-    0x1E, 0x1F, ' ',  '!',  '"',  '#',  '$',  '%',  '&',  0x27, 
-    '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',  '0',  '1',  
-    '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',  ':',  ';',  
-    '<',  '=',  '>',  '?',  '@',  'a',  'b',  'c',  'd',  'e',  
-    'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',  
-    'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  'x',  'y',  
-    'z',  '[',  0x5C, ']',  '^',  '_',  '`',  'a',  'b',  'c',  
-    'd',  'e',  'f',  'g',  'h',  'i',  'j',  'k',  'l',  'm',  
-    'n',  'o',  'p',  'q',  'r',  's',  't',  'u',  'v',  'w',  
-    'x',  'y',  'z',  '{',  '|',  '}',  '~',  0x7F, 0x80, 0x81, 
-    0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 
-    0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 
-    0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 
-    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 
-    0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 
-    0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 
-    0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 
-    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 
-    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 
-    0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 
-    0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 
-    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 
-    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-};
-
-
-
-int strcasecmp(const char *s1, const char *s2)
-{
-    register const unsigned char *us1, *us2;
-    register unsigned char cs1, cs2;
-
-    for (us1 = (const unsigned char *)s1, us2 = (const unsigned char *)s2,
-           cs1 = tolower_table[(int)*us1], cs2 = tolower_table[(int)*us2];
-           cs1 != '\0' && cs2 != '\0' &&
-           (cs1 = tolower_table[(int)*us1]) ==
-           (cs2 = tolower_table[(int)*us2]);
-           us1++, us2++) ;
-
-    return ((int)(cs1 - cs2));
-}
-
-
-int strncasecmp(const char *s1, const char *s2, size_t max)
-{
-    register const unsigned char *us1, *us2, *toptr;
-    register unsigned char cs1, cs2;
-
-    if (max == 0)
-       return 0;
-
-    for (us1 = (const unsigned char *)s1, us2 = (const unsigned char *)s2,
-           cs1 = tolower_table[(int)*us1], cs2 = tolower_table[(int)*us2],
-           toptr = us1, toptr += max;
-           us1 < toptr && cs1 != '\0' && cs2 != '\0' &&
-           (cs1 = tolower_table[(int)*us1]) ==
-           (cs2 = tolower_table[(int)*us2]);
-           us1++, us2++) ;
-
-    return (us1 < toptr ? ((int)(cs1 - cs2)) : 0);
-}
-
-
-void _strlower(char *str)
-{
-    register unsigned char *ustr;
-
-    for (ustr = (unsigned char *)str; *ustr != '\0'; ustr++)
-       *ustr = tolower_table[(int)*ustr];
-}
-
-
-void _strupper(char *str)
-{
-    register unsigned char *ustr;
-
-    for (ustr = (unsigned char *)str; *ustr != '\0'; ustr++)
-       *ustr = toupper_table[(int)*ustr];
-}
-
-
-/* This function generates a 32-bit hash using the supplied string which
- * is suitable for fast lookup for command comparision. It simply converts
- * characters to uppercase and stores them in the value. It of course can
- * only perform this for 4 bytes. It will stop at either end of string '\0'
- * or space ' '. If the string has more than 4 characters -1 is returned.
- */
-u_int32_t _strpack32(const char *str, size_t min)
-{
-    register unsigned const char *ustr;
-    register u_int32_t hash = 0;
-    size_t i;
-
-    for (ustr = (unsigned const char *)str, i = 0; *ustr > 32 && i < 5; i++) {
-       hash <<= 8;
-       hash |= toupper_table[(int)*ustr++];
-    }
-    if (i < min || i > 4)
-       hash = 0;
-
-    return hash;
-}
-
-
-/* These functions are useful to use in conjunction with hash tables if
- * case-insensitive processing of data is required while case-sensitivity of
- * records storage must be preserved.
- */
-
-u_int32_t _memcasehash32(const void *mem, size_t size)
-{
-    register u_int32_t hash;
-    register const unsigned char *curmem, *tomem;
-
-    hash = 0;
-    curmem = tomem = mem;
-    tomem += size;
-
-#if !defined(_ARCH_LOWCACHE)
-    while (curmem < tomem - 4) {
-#if !defined(_ARCH_USEINDEXING)
-       hash = toupper_table[(int)*curmem++] + (31 * hash);
-       hash = toupper_table[(int)*curmem++] + (31 * hash);
-       hash = toupper_table[(int)*curmem++] + (31 * hash);
-       hash = toupper_table[(int)*curmem++] + (31 * hash);
-#else  /* !defined(_ARCH_USEINDEXING) */
-       hash = toupper_table[(int)curmem[0]] + (31 * hash);
-       hash = toupper_table[(int)curmem[1]] + (31 * hash);
-       hash = toupper_table[(int)curmem[2]] + (31 * hash);
-       hash = toupper_table[(int)curmem[3]] + (31 * hash);
-       curmem += 4;
-#endif /* !defined(_ARCH_USEINDEXING) */
-    }
-#endif /* !defined(_ARCH_LOWCACHE) */
-    while (curmem < tomem)
-       hash = toupper_table[(int)*curmem++] + (31 * hash);
-
-    return hash;
-}
-
-int _memcasecmp(const void *s1, const void *s2, size_t size)
-{
-    register const unsigned char *ptr1, *ptr2, *toptr;
-
-#define CMP()  toupper_table[(int)*ptr1++] != toupper_table[(int)*ptr2++]
-#define RET()  return (int)(toupper_table[(int)*(--ptr1)] - \
-                       toupper_table[(int)*(--ptr2)])
-
-    ptr1 = toptr = s1;
-    toptr += size;
-    ptr2 = s2;
-
-#if !defined(_ARCH_LOWCACHE)
-    while (ptr1 < toptr - 4)
-       if (CMP() || CMP() || CMP() || CMP())
-           RET();
-#endif
-    while (ptr1 < toptr)
-       if (CMP())
-           RET();
-
-#undef CMP
-#undef RET
-
-    return 0;
-}
diff --git a/Xisop/src/common/kernlib/string/htol.c b/Xisop/src/common/kernlib/string/htol.c
deleted file mode 100644 (file)
index 79ef88d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Id: htol.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Converts an hexadecimal string to u_int32_t */
-u_int32_t htol(const char *s)
-{
-    register u_int32_t v = 0;
-
-    while (*s) {
-       if (*s >= '0' && *s <= '9') {
-           if (v <= (u_int16_t)-1)
-               v = (u_int16_t)v * 16;
-           else
-               v = v * 16;
-           v += *s++ - '0';
-       } else if (*s >= 'a' && *s <= 'f') {
-           if (v <= (u_int16_t)-1)
-               v = (u_int16_t)v * 16;
-           else
-               v = v * 16;
-           v += *s++ - 87;
-       } else if (*s >= 'A' && *s <= 'F') {
-           if (v <= (u_int16_t)-1)
-               v = (u_int16_t)v * 16;
-           else
-               v = v * 16;
-           v += *s++ - 55;
-       } else break;
-    }
-
-    return v;
-}
diff --git a/Xisop/src/common/kernlib/string/memcmp.c b/Xisop/src/common/kernlib/string/memcmp.c
deleted file mode 100644 (file)
index 6b3b0f9..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $Id: memcmp.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-int memcmp(const void *dest, const void *src, size_t len)
-{
-    register const unsigned char *ptr, *toptr, *dptr;
-
-    ptr = toptr = src;
-    toptr += len;
-    dptr = dest;
-
-#define RET(a, b)      return (int)(*(--(a)) - *(--(b)))
-
-#if _ARCH_INT_BITS == 8
-
-#if !defined(_ARCH_LOWCACHE)
-    while (ptr < toptr - 8)
-       if (*ptr++ != *dptr++ || *ptr++ != *dptr++ || *ptr++ != *dptr++ ||
-           *ptr++ != *dptr++ || *ptr++ != *dptr++ || *ptr++ != *dptr++ ||
-           *ptr++ != *dptr++ || *ptr++ != *dptr++)
-           RET(dptr, ptr);
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-    while (ptr < toptr)
-       if (*ptr++ != *dptr++)
-           RET(dptr, ptr);
-
-#else                          /* _ARCH_INT_BITS != 8 */
-
-    if (len < 32 || ((int)ptr % sizeof(int)) != ((int)dptr % sizeof(int))) {
-#if !defined(_ARCH_LOWCACHE)
-       while (ptr < toptr - 8)
-           if (*ptr++ != *dptr++ || *ptr++ != *dptr++ || *ptr++ != *dptr++ ||
-                   *ptr++ != *dptr++ || *ptr++ != *dptr++ ||
-                   *ptr++ != *dptr++ || *ptr++ != *dptr++ ||
-                   *ptr++ != *dptr++)
-               RET(dptr, ptr);
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (ptr < toptr)
-           if (*ptr++ != *dptr++)
-               RET(dptr, ptr);
-    } else {
-       register const unsigned int *lptr, *ltoptr, *ldptr, *ldtoptr;
-       register const unsigned char *dtoptr;
-
-       dtoptr = dptr;
-       dtoptr += len;
-       lptr = (const unsigned int *)OALIGN_CEIL(ptr, int);
-       ltoptr = (const unsigned int *)OALIGN_FLOOR(toptr, int);
-       ldptr = (const unsigned int *)OALIGN_CEIL(dptr, int);
-       ldtoptr = (const unsigned int *)OALIGN_FLOOR(dtoptr, int);
-       if (ldtoptr - ldptr < ltoptr - lptr)
-           ltoptr--;
-
-       while (ptr < (const unsigned char *)lptr)
-           if (*ptr++ != *dptr++)
-               RET(dptr, ptr);
-#if !defined(_ARCH_LOWCACHE)
-       while (lptr < ltoptr - (sizeof(int) * 8)) {
-           if (*lptr++ != *ldptr++ || *lptr++ != *ldptr++ ||
-                   *lptr++ != *ldptr++ || *lptr++ != *ldptr++ ||
-                   *lptr++ != *ldptr++ || *lptr++ != *ldptr++ ||
-                   *lptr++ != *ldptr++ || *lptr++ != *ldptr++)
-               RET(ldptr, lptr);
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (lptr < ltoptr)
-           if (*lptr++ != *ldptr++)
-               RET(ldptr, lptr);
-       ptr = (const unsigned char *)lptr;
-       dptr = (const unsigned char *)ldptr;
-       while (ptr < toptr)
-           if (*ptr++ != *dptr++)
-               RET(dptr, ptr);
-    }
-
-#endif                         /* _ARCH_INT_BITS == 8 */
-
-#undef RET
-
-    return 0;
-}
diff --git a/Xisop/src/common/kernlib/string/memcpy.c b/Xisop/src/common/kernlib/string/memcpy.c
deleted file mode 100644 (file)
index 398d91e..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* $Id: memcpy.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-void *memcpy(void *dest, const void *src, size_t len)
-{
-    register const unsigned char *ptr, *toptr;
-    register unsigned char *dptr;
-
-    ptr = toptr = src;
-    toptr += len;
-    dptr = dest;
-
-#if _ARCH_INT_BITS == 8
-
-#if !defined(_ARCH_LOWCACHE)
-    while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-       *dptr++ = *ptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-       dptr[0] = ptr[0];
-       dptr[1] = ptr[1];
-       dptr[2] = ptr[2];
-       dptr[3] = ptr[3];
-       dptr[4] = ptr[4];
-       dptr[5] = ptr[5];
-       dptr[6] = ptr[6];
-       dptr[7] = ptr[7];
-       dptr += 8;
-       ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-    }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-    while (ptr < toptr)
-       *dptr++ = *ptr++;
-
-#else                          /* _ARCH_INT_BITS != 8 */
-
-    if (len < 32 || ((int)ptr % sizeof(int)) != ((int)dptr % sizeof(int))) {
-#if !defined(_ARCH_LOWCACHE)
-       while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-           dptr[0] = ptr[0];
-           dptr[1] = ptr[1];
-           dptr[2] = ptr[2];
-           dptr[3] = ptr[3];
-           dptr[4] = ptr[4];
-           dptr[5] = ptr[5];
-           dptr[6] = ptr[6];
-           dptr[7] = ptr[7];
-           dptr += 8;
-           ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (ptr < toptr)
-           *dptr++ = *ptr++;
-    } else {
-       register const unsigned int *lptr, *ltoptr;
-       register unsigned int *ldptr, *ldtoptr;
-       register unsigned char *dtoptr;
-
-       dtoptr = dptr;
-       dtoptr += len;
-       lptr = (const unsigned int *)OALIGN_CEIL(ptr, int);
-       ltoptr = (const unsigned int *)OALIGN_FLOOR(toptr, int);
-       ldptr = (unsigned int *)OALIGN_CEIL(dptr, int);
-       ldtoptr = (unsigned int *)OALIGN_FLOOR(dtoptr, int);
-       if (ldtoptr - ldptr < ltoptr - lptr)
-           ltoptr--;
-
-       while (ptr < (const unsigned char *)lptr)
-           *dptr++ = *ptr++;
-#if !defined(_ARCH_LOWCACHE)
-       while (lptr < ltoptr - (sizeof(int) * 8)) {
-#if !defined(_ARCH_USEINDEXING)
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-           *ldptr++ = *lptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-           ldptr[0] = lptr[0];
-           ldptr[1] = lptr[1];
-           ldptr[2] = lptr[2];
-           ldptr[3] = lptr[3];
-           ldptr[4] = lptr[4];
-           ldptr[5] = lptr[5];
-           ldptr[6] = lptr[6];
-           ldptr[7] = lptr[7];
-           ldptr = &ldptr[8];
-           lptr = &lptr[8];
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (lptr < ltoptr)
-           *ldptr++ = *lptr++;
-       ptr = (unsigned const char *)lptr;
-       dptr = (unsigned char *)ldptr;
-       while (ptr < toptr)
-           *dptr++ = *ptr++;
-    }
-
-#endif                         /* _ARCH_INT_BITS == 8 */
-
-    return dest;
-}
diff --git a/Xisop/src/common/kernlib/string/memhash32.c b/Xisop/src/common/kernlib/string/memhash32.c
deleted file mode 100644 (file)
index 9184827..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $Id: memhash32.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-u_int32_t memhash32(const void *mem, size_t size)
-{
-    register u_int32_t hash;
-    register const unsigned char *curmem, *tomem;
-
-    hash = 0;
-    curmem = tomem = mem;
-    tomem += size;
-
-#if !defined(_ARCH_LOWCACHE)
-    while (curmem < tomem - 4) {
-#if !defined(_ARCH_USEINDEXING)
-       hash = *curmem++ + (31 * hash);
-       hash = *curmem++ + (31 * hash);
-       hash = *curmem++ + (31 * hash);
-       hash = *curmem++ + (31 * hash);
-#else  /* !defined(_ARCH_USEINDEXING) */
-       hash = curmem[0] + (31 * hash);
-       hash = curmem[1] + (31 * hash);
-       hash = curmem[2] + (31 * hash);
-       hash = curmem[3] + (31 * hash);
-       curmem += 4;
-#endif /* !defined(_ARCH_USEINDEXING) */
-    }
-#endif /* !defined(_ARCH_LOWCACHE) */
-    while (curmem < tomem)
-       hash = *curmem++ + (31 * hash);
-
-    return hash;
-}
diff --git a/Xisop/src/common/kernlib/string/memmove.c b/Xisop/src/common/kernlib/string/memmove.c
deleted file mode 100644 (file)
index cd0db28..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/* $Id: memmove.c,v 1.1 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Can work with overlapping areas */
-void *memmove(void *dest, const void *src, size_t len)
-{
-    register const unsigned char *ptr = NULL, *toptr = NULL;
-    register unsigned char *dptr = NULL;
-    size_t d;
-
-    if (dest < src)
-       d = (const unsigned char *)src - (unsigned char *)dest;
-    else
-       d = (unsigned char *)dest - (const unsigned char *)src;
-
-#if _ARCH_INT_BITS == 8
-
-    if (dest < src) {
-       /* Copy in increasing order */
-       ptr = toptr = (const unsigned char *)src;
-       toptr += len;
-       dptr = dest;
-#if !defined(_ARCH_LOWCACHE)
-       while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-           *dptr++ = *ptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-           dptr[0] = ptr[0];
-           dptr[1] = ptr[1];
-           dptr[2] = ptr[2];
-           dptr[3] = ptr[3];
-           dptr[4] = ptr[4];
-           dptr[5] = ptr[5];
-           dptr[6] = ptr[6];
-           dptr[7] = ptr[7];
-           dptr += 8;
-           ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (ptr < toptr)
-           *dptr++ = *ptr++;
-    } else if (dest > src) {
-       /* Copy in reverse order */
-       ptr = toptr = (const unsigned char *)src;
-       ptr += len;
-       dptr = dest;
-       dptr += len;
-#if !defined(_ARCH_LOWCACHE)
-       while (ptr >= toptr + 8) {
-#if !defined(_ARCH_USEINDEXING)
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-           *dptr-- = *ptr--;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-           dptr[0] = ptr[0];
-           dptr[-1] = ptr[-1];
-           dptr[-2] = ptr[-2];
-           dptr[-3] = ptr[-3];
-           dptr[-4] = ptr[-4];
-           dptr[-5] = ptr[-5];
-           dptr[-6] = ptr[-6];
-           dptr[-7] = ptr[-7];
-           dptr -= 8;
-           ptr -= 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (ptr >= toptr)
-           *dptr-- = *ptr--;
-    }
-
-#else                          /* _ARCH_INT_BITS != 8 */
-
-    if (len < 32 || d < sizeof(int) ||
-       ((int)ptr % sizeof(int)) != ((int)dptr % sizeof(int))) {
-       if (dest < src) {
-           /* Copy in increasing order */
-           ptr = toptr = (const unsigned char *)src;
-           toptr += len;
-           dptr = dest;
-#if !defined(_ARCH_LOWCACHE)
-           while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-               *dptr++ = *ptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-               dptr[0] = ptr[0];
-               dptr[1] = ptr[1];
-               dptr[2] = ptr[2];
-               dptr[3] = ptr[3];
-               dptr[4] = ptr[4];
-               dptr[5] = ptr[5];
-               dptr[6] = ptr[6];
-               dptr[7] = ptr[7];
-               dptr += 8;
-               ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-           }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-           while (ptr < toptr)
-               *dptr++ = *ptr++;
-       } else if (dest > src) {
-           /* Copy in reverse order */
-           ptr = toptr = (const unsigned char *)src;
-           ptr += len;
-           dptr = dest;
-           dptr += len;
-#if !defined(_ARCH_LOWCACHE)
-           while (ptr >= toptr + 8) {
-#if !defined(_ARCH_USEINDEXING)
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-               *dptr-- = *ptr--;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-               dptr[0] = ptr[0];
-               dptr[-1] = ptr[-1];
-               dptr[-2] = ptr[-2];
-               dptr[-3] = ptr[-3];
-               dptr[-4] = ptr[-4];
-               dptr[-5] = ptr[-5];
-               dptr[-6] = ptr[-6];
-               dptr[-7] = ptr[-7];
-               dptr -= 8;
-               ptr -= 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-           }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-           while (ptr >= toptr)
-               *dptr-- = *ptr--;
-       }
-    } else {
-       if (dest < src) {
-           /* Increasing order */
-           register const unsigned int *lptr, *ltoptr;
-           register unsigned int *ldptr, *ldtoptr;
-           register unsigned char *dtoptr;
-
-           ptr = toptr = (const unsigned char *)src;
-           toptr += len;
-           dptr = dest;
-
-           dtoptr = dptr;
-           dtoptr += len;
-           lptr = (const unsigned int *)OALIGN_CEIL(ptr, int);
-           ltoptr = (const unsigned int *)OALIGN_FLOOR(toptr, int);
-           ldptr = (unsigned int *)OALIGN_CEIL(dptr, int);
-           ldtoptr = (unsigned int *)OALIGN_FLOOR(dtoptr, int);
-           if (ldtoptr - ldptr < ltoptr - lptr)
-               ltoptr--;
-
-           while (ptr < (const unsigned char *)lptr)
-               *dptr++ = *ptr++;
-#if !defined(_ARCH_LOWCACHE)
-           while (lptr < ltoptr - (sizeof(int) * 8)) {
-#if !defined(_ARCH_USEINDEXING)
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-               *ldptr++ = *lptr++;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-               ldptr[0] = lptr[0];
-               ldptr[1] = lptr[1];
-               ldptr[2] = lptr[2];
-               ldptr[3] = lptr[3];
-               ldptr[4] = lptr[4];
-               ldptr[5] = lptr[5];
-               ldptr[6] = lptr[6];
-               ldptr[7] = lptr[7];
-               ldptr = &ldptr[8];
-               lptr = &lptr[8];
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-           }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-           while (lptr < ltoptr)
-               *ldptr++ = *lptr++;
-           ptr = (const unsigned char *)lptr;
-           dptr = (unsigned char *)ldptr;
-           while (ptr < toptr)
-               *dptr++ = *ptr++;
-       } else if (dest > src) {
-           /* Reverse order */
-           register const int *lptr, *ltoptr;
-           register int *ldptr, *ldtoptr;
-           register char *dtoptr;
-
-           ptr = toptr = (const unsigned char *)src;
-           ptr += len;
-           dptr = dest;
-           dptr += len;
-
-           dtoptr = dest;
-           lptr = (const unsigned int *)OALIGN_FLOOR(ptr, int);
-           ldptr = (unsigned int *)OALIGN_FLOOR(dptr, int);
-           ltoptr = (const unsigned int *)OALIGN_CEIL(toptr, int);
-           ldtoptr = (unsigned int *)OALIGN_CEIL(dtoptr, int);
-           if (ldptr - ldtoptr < lptr - ltoptr)
-               ltoptr++;
-
-           while (ptr >= (const unsigned char *)lptr)
-               *dptr-- = *ptr--;
-#if !defined(_ARCH_LOWCACHE)
-           while (lptr >= ltoptr + (sizeof(int) * 8)) {
-#if !defined(_ARCH_USEINDEXING)
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-               *ldptr-- = *lptr--;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-               ldptr[0] = lptr[0];
-               ldptr[-1] = lptr[-1];
-               ldptr[-2] = lptr[-2];
-               ldptr[-3] = lptr[-3];
-               ldptr[-4] = lptr[-4];
-               ldptr[-5] = lptr[-5];
-               ldptr[-6] = lptr[-6];
-               ldptr[-7] = lptr[-7];
-               ldptr = &ldptr[-8];
-               lptr = &lptr[-8];
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-           }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-           while (lptr >= ltoptr)
-               *ldptr-- = *lptr--;
-           ptr = (const unsigned char *)lptr;
-           dptr = (unsigned char *)ldptr;
-           while (ptr >= toptr)
-               *dptr-- = *ptr--;
-       }
-    }
-
-#endif                         /* _ARCH_INT_BITS == 8 */
-
-    return dest;
-}
diff --git a/Xisop/src/common/kernlib/string/memset.c b/Xisop/src/common/kernlib/string/memset.c
deleted file mode 100644 (file)
index 65f0cdd..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* $Id: memset.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-void *memset(void *mem, int fill, size_t len)
-{
-    register unsigned char *ptr, *toptr;
-    u_int8_t byte = (u_int8_t)fill;
-
-    ptr = toptr = mem;
-    toptr += len;
-
-#if _ARCH_INT_BITS == 8
-
-#if !defined(_ARCH_LOWCACHE)
-    while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-       *ptr++ = byte;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-       ptr[0] = byte;
-       ptr[1] = byte;
-       ptr[2] = byte;
-       ptr[3] = byte;
-       ptr[4] = byte;
-       ptr[5] = byte;
-       ptr[6] = byte;
-       ptr[7] = byte;
-       ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-    }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-    while (ptr < toptr)
-       *ptr++ = byte;
-
-#else                          /* _ARCH_INT_BITS != 8 */
-
-    if (len < 32) {
-#if !defined(_ARCH_LOWCACHE)
-       while (ptr < toptr - 8) {
-#if !defined(_ARCH_USEINDEXING)
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-           *ptr++ = byte;
-#else                          /* !defined(_ARCH_USEDARRAYS) */
-           ptr[0] = byte;
-           ptr[1] = byte;
-           ptr[2] = byte;
-           ptr[3] = byte;
-           ptr[4] = byte;
-           ptr[5] = byte;
-           ptr[6] = byte;
-           ptr[7] = byte;
-           ptr += 8;
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (ptr < toptr)
-           *ptr++ = byte;
-    } else {
-       register unsigned int *lptr, *ltoptr, lword = 0;
-
-       if (byte != 0) {
-#if _ARCH_INT_BITS == 16
-           lword = ((byte << 8) & 0xff00) | (byte & 0x00ff);
-#elif _ARCH_INT_BITS == 32
-           /* Creating a 16-bit word from the 8-bit one, then the 32-bit word
-            * from the 16-bit one require less instructions.
-            */
-           register u_int16_t tmp;
-
-           tmp = ((byte << 8) & 0xff00) | (byte & 0x00ff);
-           lword = ((tmp << 16) & 0xffff0000) | (tmp & 0x0000ffff);
-#elif _ARCH_INT_BITS == 64
-           /* Unlikely, since long is usually 64-bit on 64-bit archs, leaving
-            * 32-bit ints.
-            * Creating a 16-bit word from the 8-bit one, a 32-bit word from
-            * the 16-bit one and a 64-bit word from the 32-bit one require
-            * less instructions.
-            */
-           register u_int32_t tmp2;
-           register u_int16_t tmp;
-
-           tmp = ((byte << 8) & 0xff00) | (byte & 0x00ff);
-           tmp2 = ((tmp << 16) & 0xffff0000) | (tmp & 0x0000ffff);
-           lword = ((tmp2 << 32) & 0xffffffff00000000ULL) |
-               (tmp2 & 0x00000000ffffffffULL);
-#endif
-       }
-
-       lptr = (unsigned int *)OALIGN_CEIL(ptr, int);
-       ltoptr = (unsigned int *)OALIGN_FLOOR(toptr, int);
-
-       while (ptr < (unsigned char *)lptr)
-           *ptr++ = byte;
-#if !defined(_ARCH_LOWCACHE)
-       while (lptr < ltoptr - (sizeof(int) * 8)) {
-#if !defined(_ARCH_USEINDEXING)
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-           *lptr++ = lword;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-           lptr[0] = lword;
-           lptr[1] = lword;
-           lptr[2] = lword;
-           lptr[3] = lword;
-           lptr[4] = lword;
-           lptr[5] = lword;
-           lptr[6] = lword;
-           lptr[7] = lword;
-           lptr = &lptr[8];
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-       }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-       while (lptr < ltoptr)
-           *lptr++ = lword;
-       ptr = (unsigned char *)lptr;
-       while (ptr < toptr)
-           *ptr++ = byte;
-    }
-
-#endif                         /* _ARCH_INT_BITS == 8 */
-
-    return mem;
-}
diff --git a/Xisop/src/common/kernlib/string/pageclr.c b/Xisop/src/common/kernlib/string/pageclr.c
deleted file mode 100644 (file)
index cb74b59..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* $Id: pageclr.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-#include <port/support.h>
-
-
-
-/* Faster than memset(), but assumes that <mem> be aligned and that _PAGE_SIZE
- * is a multiple of sizeof(int).
- */
-void pageclr(void *mem, u_int32_t many)
-{
-    register int *lptr, *ltoptr, lword = 0;
-
-    lptr = (int *)mem;
-    ltoptr = (int *)(((u_int8_t *)mem + (_PAGE_SIZE * many)));
-
-#if !defined(_ARCH_LOWCACHE)
-    while (lptr < ltoptr - (sizeof(int) * 16)) {
-#if !defined(_ARCH_USEINDEXING)
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-       *lptr++ = lword;
-#else                          /* !defined(_ARCH_USEINDEXING) */
-       lptr[0] = lword;
-       lptr[1] = lword;
-       lptr[2] = lword;
-       lptr[3] = lword;
-       lptr[4] = lword;
-       lptr[5] = lword;
-       lptr[6] = lword;
-       lptr[7] = lword;
-       lptr[8] = lword;
-       lptr[9] = lword;
-       lptr[10] = lword;
-       lptr[11] = lword;
-       lptr[12] = lword;
-       lptr[13] = lword;
-       lptr[14] = lword;
-       lptr[15] = lword;
-       lptr = &lptr[16];
-#endif                         /* !defined(_ARCH_USEINDEXING) */
-    }
-#endif                         /* !defined(_ARCH_LOWCACHE) */
-    while (lptr < ltoptr)
-       *lptr++ = lword;
-}
diff --git a/Xisop/src/common/kernlib/string/straspl.c b/Xisop/src/common/kernlib/string/straspl.c
deleted file mode 100644 (file)
index 7f15a91..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* $Id: straspl.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Splits columns of a string delimited by spaces and/or tabs, and fills
- * char **argv with pointers to each column. Returns the number of columns
- * that could be filled in. The supplied string IS modified.
- */
-int straspl(char **argv, char *str, int maxcols)
-{
-    register char *ptr, *ptr2;
-    int col;
-
-    for (ptr = str, col = 0; *ptr != '\0' && col < maxcols; ) {
-       for (; *ptr == ' ' || *ptr == '\t'; ptr++) ;
-       if (*ptr != '\0') {
-           for (ptr2 = ptr; *ptr != '\0' && *ptr != ' ' && *ptr != '\t';
-                   ptr++) ;
-           if (ptr != ptr2) {
-               if (*ptr != '\0')
-                   *ptr++ = '\0';
-               argv[col++] = ptr2;
-           } else
-               break;
-       } else
-           break;
-    }
-
-    return col;
-}
diff --git a/Xisop/src/common/kernlib/string/strchr.c b/Xisop/src/common/kernlib/string/strchr.c
deleted file mode 100644 (file)
index fd4c51d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: strchr.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-char *strchr(const char *str, int c)
-{
-    for (; *str != '\0' && *str != c; str++) ;
-
-    return (*str != '\0' ? (char *)str : NULL);
-}
diff --git a/Xisop/src/common/kernlib/string/strcmp.c b/Xisop/src/common/kernlib/string/strcmp.c
deleted file mode 100644 (file)
index 3d5c931..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: strcmp.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-int strcmp(const char *s1, const char *s2)
-{
-    for (; *s1 != '\0' && *s2 != '\0' && *s1 == *s2; s1++, s2++) ;
-
-    return ((int)((const unsigned char)*s1 - (const unsigned char)*s2));
-}
diff --git a/Xisop/src/common/kernlib/string/strlen.c b/Xisop/src/common/kernlib/string/strlen.c
deleted file mode 100644 (file)
index 3bcca1b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $Id: strlen.c,v 1.2 2004/06/03 05:40:03 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-size_t strlen(const char *str)
-{
-    register const char *ptr = str;
-
-    /* Although this causes ptr to be increased even when 0 is reached,
-     * compilers generally generate better code.
-     * i.e. GCC2-m68k:  tstb %a0@+  vs  tstb %a0@  and  addql #1, %a0
-     * Matt
-     */
-    while (*ptr++ != '\0') ;
-
-    /* Don't forget to substract 1 */
-    return ((size_t)((ptr - 1) - str));
-}
diff --git a/Xisop/src/common/kernlib/string/strnchr.c b/Xisop/src/common/kernlib/string/strnchr.c
deleted file mode 100644 (file)
index a7ba5b8..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $Id: strnchr.c,v 1.2 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-char *strnchr(const char *str, int c, size_t max)
-{
-    if (max > 0) {
-       register const char *toptr;
-
-       for (toptr = str, toptr += max;
-               str < toptr && *str != '\0' && (int)*str != c; str++) ;
-
-       if (str == toptr || *str == '\0')
-           return NULL;
-
-       return (char *)str;
-    }
-
-    return NULL;
-}
diff --git a/Xisop/src/common/kernlib/string/strncmp.c b/Xisop/src/common/kernlib/string/strncmp.c
deleted file mode 100644 (file)
index de97198..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $Id: strncmp.c,v 1.3 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-int strncmp(const char *s1, const char *s2, size_t max)
-{
-    if (max > 0) {
-       register const char *toptr;
-
-       for (toptr = s1, toptr += max; s1 < toptr && *s1 != '\0' &&
-               *s2 != '\0' && *s1 == *s2; s1++, s2++) ;
-
-       return (s1 < toptr ?
-               ((int)((const unsigned char)*s1 - (const unsigned char)*s2)) :
-               0);
-    }
-
-    return 0;
-}
diff --git a/Xisop/src/common/kernlib/string/strnlen.c b/Xisop/src/common/kernlib/string/strnlen.c
deleted file mode 100644 (file)
index 231521e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id: strnlen.c,v 1.2 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-size_t strnlen(const char *str, size_t max)
-{
-    register const char *fptr, *tptr;
-
-    for (fptr = tptr = str, tptr += max; fptr < tptr && *fptr != '\0'; fptr++)
-       ;
-
-    return ((size_t)(fptr - str));
-}
diff --git a/Xisop/src/common/kernlib/string/strnrchr.c b/Xisop/src/common/kernlib/string/strnrchr.c
deleted file mode 100644 (file)
index a156119..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* $Id: strnrchr.c,v 1.2 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-char *strnrchr(const char *str, int c, size_t max)
-{
-    register const char *toptr, *found;
-
-    for (found = NULL, toptr = str, toptr += max;
-           str < toptr && *str != '\0'; str++) {
-       if (*str == c)
-           found = str;
-    }
-
-    return (char *)found;
-}
diff --git a/Xisop/src/common/kernlib/string/strrchr.c b/Xisop/src/common/kernlib/string/strrchr.c
deleted file mode 100644 (file)
index d871c0e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Id: strrchr.c,v 1.2 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-char *strrchr(const char *str, int c)
-{
-    register const char *found;
-
-    for (found = NULL; *str != '\0'; str++) {
-       if (*str == c)
-           found = str;
-    }
-
-    return (char *)found;
-}
diff --git a/Xisop/src/common/kernlib/string/strspl.c b/Xisop/src/common/kernlib/string/strspl.c
deleted file mode 100644 (file)
index 0dac4a9..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $Id: strspl.c,v 1.2 2004/06/03 05:40:04 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include <common/kernlib/string.h>
-
-
-
-/* Splits columns of a string delimited by sep, and fills
- * char **argv with pointers to each column. Returns the number of columns
- * that could be filled in. The supplied string IS modified. Note that two
- * contiguous separators cause empty entries to be filled in. An exception
- * consists of the last separator, which is ignored if nothing is found after
- * it.
- */
-int strspl(char **argv, char *str, int maxcols, char sep)
-{
-    register char *ptr, *ptr2;
-    int col;
-
-    for (col = 0, ptr = str; *ptr != '\0' && col < maxcols; ) {
-       for (ptr2 = ptr; *ptr != '\0' && *ptr != sep; ptr++) ;
-       if (*ptr != '\0')
-           *ptr++ = '\0';
-       argv[col++] = ptr2;
-    }
-
-    return col;
-}
-
-
diff --git a/Xisop/src/common/make.sh b/Xisop/src/common/make.sh
deleted file mode 100755 (executable)
index 962d2c7..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../makedefs.sh
-
-# Build kernlib
-show cd kernlib
-./make.sh
-show cd ..
-
-# Build kernel
-show cd kernel
-./make.sh
-show cd ..
diff --git a/Xisop/src/common/types.h b/Xisop/src/common/types.h
deleted file mode 100644 (file)
index c46da28..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $Id: types.h,v 1.6 2004/06/03 05:54:44 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef COMMON_TYPES_H
-#define COMMON_TYPES_H
-
-
-
-typedef unsigned char          u_int8_t;
-typedef signed char            int8_t;
-typedef unsigned short         u_int16_t;
-typedef signed short           int16_t;
-typedef unsigned long          u_int32_t;
-typedef signed long            int32_t;
-typedef unsigned long long     u_int64_t;
-typedef signed long long       int64_t;
-typedef int                    bool;
-typedef u_int32_t              size_t;
-typedef int32_t                        ssize_t;
-#define NULL                   ((void *)0)
-#define TRUE                   /* CONSTCOND */(1)
-#define FALSE                  /* CONSTCOND */(0)
-
-/* For code-embedded copyright and CVS/RCS ID strings */
-#define COPYRIGHT(x)           static const char _copyright[] = x
-#define RCSID(x)               static const char _rcsid[] = x
-
-
-/* Useful to o-align a value relative to v (sizes and pointers) */
-#define OALIGN_CEIL(v, o) \
-    ((((size_t)(v)) + (sizeof(o)) - 1) / (sizeof(o)) * (sizeof(o)))
-#define OALIGN_FLOOR(v, o)     ((size_t)(v) - (((size_t)(v) % sizeof(o))))
-
-/* Useful to byte align a value with supplied size */
-#define BALIGN_CEIL(v, s)      ((((size_t)(v)) + (s) - 1) / (s) * (s))
-#define BALIGN_FLOOR(v, s)     ((size_t)(v) - (((size_t)(v) % (s))))
-
-/* Import necessary processor-specific optimization macros */
-#include <processor/support.h>
-/* For network and host byte order of 16-bit and 32-bit types */
-#if defined(_ARCH_LITTLE_ENDIAN)
-#define BYTEORDER_NETWORK16            _bswap16
-#define BYTEORDER_HOST16               _bswap16
-#define BYTEORDER_NETWORK32            _bswap32
-#define BYTEORDER_HOST32               _bswap32
-#elif defined(_ARCH_BIG_ENDIAN)
-#define BYTEORDER_NETWORK16(w)         (w)
-#define BYTEORDER_HOST16(w)            (w)
-#define BYTEORDER_NETWORK32(w)         (w)
-#define BYTEORDER_HOST32(w)            (w)
-#else
-error "Endian not specified (_ARCH_LITTLE_ENDIAN | _ARCH_BIG_ENDIAN)";
-#endif
-/* Ensure that _ARCH_INT_BITS was defined */
-#ifndef _ARCH_INT_BITS
-error "Bits in an int (_ARCH_INT_BITS) not specified (8, 16, 32, 64)";
-#endif
-
-/* common/kernel/device.h */
-typedef struct devicenode      devicenode_t;
-typedef struct devicehandle    device_t;
-typedef struct iorequest       iorequest_t;
-
-/* common/kernel/exception.h */
-typedef u_int32_t              hookid_t;
-typedef struct _int_hook       hook_t;
-typedef struct _int_facility   facility_t;
-
-/* common/kernel/memory.h */
-typedef struct page            page_t;
-typedef struct mchunk          mchunk_t;
-typedef struct pool            pool_t;
-typedef struct ppool           ppool_t;
-typedef struct pnode           pnode_t;
-typedef struct mpool           mpool_t;
-typedef struct mnode           mnode_t;
-
-/* common/kernel/port.h */
-typedef struct port            port_t;
-typedef struct message         message_t;
-typedef struct mmessage                mmessage_t;
-
-/* common/kernel/scheduler.h */
-typedef struct rwlock          rwlock_t;
-
-/* common/kernel/signal.h */
-typedef int                    signum_t;
-typedef u_int32_t              sigmask_t;
-
-/* common/kernel/task.h */
-typedef struct task            task_t;
-typedef int8_t                 priority_t;
-
-/* common/kernlib/hash.h */
-typedef struct hashtable       hashtable_t;
-typedef struct hashnode                hashnode_t;
-
-
-#endif
diff --git a/Xisop/src/config.h b/Xisop/src/config.h
deleted file mode 100644 (file)
index 08cc233..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* $Id: config.h,v 1.5 2004/01/29 05:02:02 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-
-
-/* Flags which are possible to uncomment to compile in the kernel */
-
-#define DEBUG          4096
-#define STATISTICS
-
-
-
-#endif
diff --git a/Xisop/src/generic_makedefs.sh b/Xisop/src/generic_makedefs.sh
deleted file mode 100644 (file)
index a3bf722..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-
-# $Id: generic_makedefs.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-# These are various defaults which are used for the building process.
-# Change as required, and don't forget to create the ./port and ./processor
-# symbolic links to their respective directory.
-
-# Local non-cross building tools
-L_AR='ar qS'
-L_AS='as'
-L_CC='gcc'
-L_LD='ld'
-L_NM='nm'
-L_OBJDUMP='objdump'
-L_RANLIB='ranlib'
-L_STRIP='strip'
-L_CAT='cat'
-L_DD='dd'
-
-# Other general purpose tools
-L_RM='rm -f'
-L_LN='ln -s'
-L_SED='sed'
-L_ECHO='echo'
-L_LS='ls'
-
-show()
-{
-       # Only output to stderr, not stdout
-       $L_ECHO "$@" >&2
-       $@
-}
-
-# Deletes all .o files in a directory
-# $1 = directory
-cleanlib()
-{
-       show $L_RM $1/*.o
-}
diff --git a/Xisop/src/make.sh b/Xisop/src/make.sh
deleted file mode 100755 (executable)
index 3ae7f99..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ./generic_makedefs.sh
-
-usage()
-{
-       $L_ECHO
-       $L_ECHO 'Usage: ./make.sh -t <target>'
-       $L_ECHO
-       $L_ECHO 'Available targets:'
-       $L_ECHO '- amiga'
-       $L_ECHO
-}
-
-while getopts t: f; do
-       case $f in
-       t)
-               case $OPTARG in
-               amiga)
-                       PROCESSOR='processors/m68k'
-                       PORT='ports/amiga'
-               ;;
-               *)
-                       $L_ECHO "Unknown target $OPTARG"
-               ;;
-               esac
-       ;;
-       *)
-               usage
-               exit 0
-       ;;
-       esac
-done
-if [ -z $PORT ] || [ -z $PROCESSOR ]; then
-       usage
-       exit 0
-fi
-
-./clean.sh
-show $L_LN $PROCESSOR processor
-show $L_LN $PORT port
-show $L_LN $PORT/makedefs.sh makedefs.sh
-show export SRCDIR=`pwd`
-
-# XXX Is this a bug? As port/ symbolic link goes down two levels, I have to
-# cd back two levels?
-
-# Build processor-specific support code to processor/ar/*.a
-show cd processor
-show ./make.sh
-
-# Build port-specific support code to port/ar/*.a
-show cd ../../port
-show ./make.sh
-
-# Build the portable common code to common/kernel/ar/*.a,
-# common/kernlib/ar/*.a and XXX ???
-# and link to global ELF relocatable kernel object xisop.o
-show cd ../../common
-show ./make.sh
-
-# Let the port-specific boot code create the kernel image
-show cd ../port/boot
-show ./make.sh
-
-show cd ..
diff --git a/Xisop/src/ports/amiga/boot/DOTuaerc b/Xisop/src/ports/amiga/boot/DOTuaerc
deleted file mode 100644 (file)
index b78e08c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-config_description=UAE
-x11.rom_path=./
-x11.floppy_path=./
-x11.hardfile_path=./
-x11.low_bandwidth=false
-x11.use_mitshm=false
-x11.hide_cursor=true
-32bit_blits=true
-use_gui=nowait
-use_debugger=false
-kickstart_rom_file=/home/mmondor/kick.rom
-floppy0=/home/mmondor/src/work/Xisop/src/ports/amiga/boot/xisop.adf
-floppy1=
-floppy2=
-floppy3=
-sound_output=none
-joyport0=mouse
-joyport1=kbd1
-kbd_lang=us
-immediate_blits=yes
-cpu_speed=max
-cpu_type=68000
-chipmem_size=2
-fastmem_size=4
-#filesystem=rw,System3.1:/data2/amiga/System3.1
-#filesystem=rw,Work:/data2/amiga/Work
-#filesystem=rw,ASM:/data2/amiga/asm
diff --git a/Xisop/src/ports/amiga/boot/README b/Xisop/src/ports/amiga/boot/README
deleted file mode 100644 (file)
index a088fde..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-DOTuaerc               ~/.uaerc used for testing and developping with UAE
-                       Amiga emulator
-
-xisop.adf              Actual Amiga bootable Xisop floppy image
-
-image.bin              Consists of the actual compiled kernel binary image
-image.o                        Useful for debugging, objdump -drw image.o
-bootf/bootf.bin                Compiled floppy boot sector image
-bootf/kernel.bin       Compiled floppy boot sector image + Xisop image
-
-config.h               File to modify depending on your Amiga model and
-                       kernel size, stack size, etc.
diff --git a/Xisop/src/ports/amiga/boot/bootf/bootf_c.c b/Xisop/src/ports/amiga/boot/bootf/bootf_c.c
deleted file mode 100644 (file)
index 7088e55..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* $Id: bootf_c.c,v 1.2 2004/01/20 20:56:20 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This used to be done by assembly code, it's however best to have a C
- * loader which could eventually perform fancy stuff, and relocation as well.
- * If the loader eventually gets too large to fit into the default boot block
- * size, this boot block can then simply serve to load another loader and
- * launch it.
- */
-
-
-
-#include <common/types.h>
-
-#include "../config.h"
-
-
-COPYRIGHT("\0\nXisop bootloader Copyright 2001-2003, Matthew Mondor, \
-All rights reserved.\n");
-
-
-
-/* CONFIGURATION */
-#define KERNSTART      1024    /* Start of kernel image on disk */
-#define READSIZE       4096    /* Block size for read/relocation (512 min) */
-
-
-
-#define MEMF_CHIP      0x0001
-#define MEMF_FAST      0x0002
-#define CMD_READ       2
-#define ALRT_NOMEM     0x00010001
-#define ALRT_RERR      0x14000001
-
-
-struct iostdreq {
-    u_int8_t pad[28];
-    u_int16_t command;
-    u_int8_t flags;
-    int8_t error;
-    u_int32_t actual, length;
-    void *data;
-    u_int32_t offset;
-};
-
-
-void *AllocMem(long, long);
-void *AllocAbs(long, void *);
-void FreeMem(void *, long);
-long DoIO(struct iostdreq *);
-void Alert(long, void *);
-
-void load(struct iostdreq *);
-
-
-
-void load(struct iostdreq *ioreq)
-{
-    void *buf = NULL, *readbuf = NULL;
-    bool ok = FALSE;
-
-    /* Allocate CHIP memory buffer to load disk blocks into */
-    if ((readbuf = AllocMem(READSIZE, MEMF_CHIP)) != NULL) {
-
-       if ((buf = AllocAbs(KERNSIZE + STACKSIZE, (void *)KERNADDR))
-               == (void *)KERNADDR) {
-           register u_int32_t offset, *addr, *toaddr;
-
-           /* Read image from disk starting at KERNSTART, upto
-            * KERNSTART + KERNSIZE, in blocks of READSIZE bytes, which we
-            * relocate to our kernel buffer on the fly in KERNADDR.
-            */
-           for (offset = KERNSTART, addr = buf, toaddr = buf + KERNSIZE;
-                   addr < toaddr; offset += READSIZE) {
-               register u_int32_t *raddr, *taddr;
-
-               /* Read a block */
-               ioreq->command = CMD_READ;
-               ioreq->length = READSIZE;
-               ioreq->data = readbuf;
-               ioreq->offset = offset;
-               if ((DoIO(ioreq)) != 0) {
-                   Alert(ALRT_RERR, load);
-                   for (;;) ;
-                   /* NOTREACHED */
-               }
-
-               /* Relocate block */
-               for (raddr = readbuf, taddr = readbuf + READSIZE;
-                       raddr < taddr; *addr++ = *raddr++) ;
-           }
-           ok = TRUE;
-       }
-       FreeMem(readbuf, READSIZE);
-       if (ok) {
-           void (*code)(u_int32_t *, size_t);
-
-           /* Jump to relocated code, passing it the supervisor stack */
-           code = (void *)KERNADDR;
-           code((u_int32_t *)STACKADDR, STACKSIZE);
-       }
-    }
-
-    Alert(ALRT_NOMEM, load);
-    for (;;) ;
-    /* NOTREACHED */
-}
diff --git a/Xisop/src/ports/amiga/boot/bootf/bootf_s.s b/Xisop/src/ports/amiga/boot/bootf/bootf_s.s
deleted file mode 100644 (file)
index 2937275..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $Id: bootf_s.s,v 1.2 2004/01/20 20:56:20 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-ExecBase =     0x0004
-
-
-.globl _start, AllocMem, AllocAbs, FreeMem, DoIO, Alert
-
-
-.text
-
-| AmigaOS boot header (checksum should be calculated after assembling)
-| This is actually loaded at 0x0020b660, the ROM jumps at 0x0020b66c.
-       .long   0x444f5300, 0x00000000, 0x00000000
-
-_start:
-
-| Loader code (startup leaves us with a6 to exec.lib and a1 to IOreq pointer)
-| Call our C load() function!
-|
-       movel   %a1, %sp@-
-       bsrl    load
-| NOTREACHED
-       addql   #4, %sp
-       rts
-
-
-| Amiga library of required function stubs for load() C function
-
-| [d0]void * = [-198]AllocMem([d0]long bytes, [d1]long reqs)
-|
-AllocMem:
-       moveml  %a6/%d1-%d0, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d0
-       movel   %sp@(20), %d1
-       jsr     %a6@(-198)
-       moveal  %d0, %a0
-       moveml  %sp@+, %d0-%d1/%a6
-       rts
-
-| [d0]void * = [-204]AllocAbs([d0]long bytes, [a1]void *addr)
-|
-AllocAbs:
-       moveml  %a1/%a6/%d0, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d0
-       moveal  %sp@(20), %a1
-       jsr     %a6@(-204)
-       moveal  %d0, %a0
-       moveml  %sp@+, %d0/%a6/%a1
-       rts
-
-| void [-210]FreeMem([a1]memptr, [d0]bytesize)
-|
-FreeMem:
-       moveml  %a1/%a6/%d0, %sp@-
-       moveal  ExecBase:w, %a6
-       moveal  %sp@(16), %a1
-       movel   %sp@(20), %d0
-       jsr     %a6@(-210)
-       moveml  %sp@+, %d0/%a6/%a1
-       rts
-
-| [d0] = [-456]DoIO([a1]struct IORequest *)
-|
-DoIO:
-       moveml  %a1/%a6, %sp@-
-       moveal  ExecBase:w, %a6
-       moveal  %sp@(12), %a1
-       jsr     %a6@(-456)
-       moveml  %sp@+, %a6/%a1
-       rts
-
-| void [-108]Alert([d7]long alertNum,[a5]char *flags)
-|
-Alert:
-       moveml  %d7/%a5-%a6, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d7
-       moveal  %sp@(20), %a5
-       jsr     %a6@(-108)
-       moveml  %sp@+, %a6-%a5/%d7
-       rts
diff --git a/Xisop/src/ports/amiga/boot/bootf/bootf_script.ld b/Xisop/src/ports/amiga/boot/bootf/bootf_script.ld
deleted file mode 100644 (file)
index b422db9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-OUTPUT_FORMAT("binary", "binary", "binary")
-OUTPUT_ARCH(m68k)
-
-ENTRY(_start)
-
-SECTIONS {
-       . = 0x0020b660;
-       .text : {
-               *(.text)
-               *(.rodata)
-               *(.data)
-               *(.bss)
-       }
-}
diff --git a/Xisop/src/ports/amiga/boot/clean.sh b/Xisop/src/ports/amiga/boot/clean.sh
deleted file mode 100755 (executable)
index 79f30ca..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.2 2004/01/20 20:56:20 mmondor Exp $
-
-. ../../../generic_makedefs.sh
-
-show $L_RM image.bin image.o init.o
-show $L_RM tools/aosbblock tools/dumpkern tools/config
-show $L_RM bootf/bootf_s.o bootf/bootf_c.o bootf/bootf.o bootf/bootf.bin
-show $L_RM bootf/kern.bin xisop.adf
diff --git a/Xisop/src/ports/amiga/boot/config.h b/Xisop/src/ports/amiga/boot/config.h
deleted file mode 100644 (file)
index 537e947..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $Id: config.h,v 1.1 2004/01/20 20:56:20 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Until proper memory auto-detection is made, this file contains the general
- * information needed to setup the supervisor stack and kernel image location,
- * as well as the available RAM.
- * This currently assumes that 4 megs of FAST RAM are located from
- * 0x00200000 to 0x005fffff (Card 1, Zorro II), and that 2 megs of CHIP RAM
- * are found from 0x00001000 to 0x001fffff.
- * All these numbers should be a multiple of 4096 bytes.
- */
-
-
-
-/* CONFIGURATION */
-
-/* Size of kernel image to read from disk, in bytes */
-#define KERNSIZE       65536
-
-/* Size of kernel supervisor stack, in bytes */
-#define STACKSIZE      8192
-
-/* Boundaries of FAST RAM */
-#define FMEM_START     0x00200000
-#define FMEM_END       0x00600000
-
-/* Boundaries of CHIP RAM */
-#define CMEM_START     0x00001000
-#define CMEM_END       0x00200000
-
-
-/* These are useful results, used by boot/bootf/bootf_c.c, boot/init.c
- * and boot/tools/config.c
- */
-#define STACKADDR      (FMEM_END - STACKSIZE)
-#define KERNADDR       (STACKADDR - KERNSIZE)
-#define FPOOLADDR      (FMEM_START)
-#define FPOOLSIZE      (KERNADDR - FMEM_START - 1)
-#define CPOOLADDR      (CMEM_START)
-#define CPOOLSIZE      (CMEM_END - CMEM_START - 1)
diff --git a/Xisop/src/ports/amiga/boot/image_script.ld b/Xisop/src/ports/amiga/boot/image_script.ld
deleted file mode 100644 (file)
index 8ee2279..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-OUTPUT_FORMAT("binary", "binary", "binary")
-OUTPUT_ARCH(m68k)
-
-ENTRY(_start)
-
-SECTIONS {
-       .text : {
-               *(.text)
-               *(.rodata)
-               *(.data)
-               *(.bss)
-       }
-}
diff --git a/Xisop/src/ports/amiga/boot/init.c b/Xisop/src/ports/amiga/boot/init.c
deleted file mode 100644 (file)
index 1e59866..0000000
+++ /dev/null
@@ -1,590 +0,0 @@
-/* $Id: init.c,v 1.7 2004/01/20 21:26:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This code entry point consist of _start() which is called by the boot
- * loader. We setup the supervisor stack pointer and then jump to _init(),
- * which sets up the various port-specifics for Xisop, and finally launches
- * Xisop itself calling main(). See the Xisop documentation for more
- * information on what port-specific code has to provide in it's
- * initialization and support.h.
- */
-
-
-
-#include <common/types.h>
-#include <processors/m68k/support.h>
-#include <ports/amiga/support.h>
-#include <common/kernel/main.h>
-#include <common/kernel/memory.h>
-#include <common/kernel/exception.h>
-#include <common/kernel/syscall.h>
-#include <common/kernel/task.h>
-#include <common/kernel/port.h>
-
-#include "config.h"
-
-
-
-/* Entry point */
-void _start(u_int32_t *, size_t);
-
-/* Our initialization functions */
-static void _init(void);
-static void _disable_interrupts(void);
-static void _stop_floppy_motor(void);
-static void _init_memory(void);
-static void _init_syscalls(void);
-static void _enable_keyboard_interrupt(void);
-static void _enable_vblank_interrupt(void);
-static void _init_scheduler(void);
-static void _init_screen(void);
-
-/* C exception handlers */
-void _icatch1(u_int16_t);
-void _icatch2(u_int16_t);
-void _icatch3(u_int16_t);
-void _icatch4(u_int16_t);
-void _icatch5(u_int16_t);
-void _tcatch(int);
-void _ecatch(int);
-
-
-/* Port-specific port-initialization, to attach our port-specific shared
- * libraries and launch our port-specific tasks
- */
-struct initmsg {
-    message_t node;
-    u_int16_t color;
-};
-
-struct taskarg {
-    u_int16_t color;
-    u_int32_t rounds;
-};
-
-static int _task_color_server(void *, void *);
-static int _task_color_client(void *, void *);
-static void _keyboard_hook(hookid_t, int, void *);
-void _panic(u_int16_t);
-
-
-
-/* Used to ensure that only the first exception occurs */
-static _rlock_t elock;
-
-
-
-/* The role of this function is to go in supervisor mode, set the supervisor
- * stack, then call init().
- */
-void _start(u_int32_t *ssp, size_t sz) {
-    _supervisor(ssp, sz, _init);
-    /* NOTREACHED */
-}
-
-
-/* Main port-specific initialization */
-static void _init(void)
-{
-    /* So that ecatch() cannot recurse */
-    _rlock_init(&elock);
-
-    _disable_interrupts();
-    _stop_floppy_motor();
-
-    memory_init();             /* MI function */
-    _init_memory();
-
-    facilities_init();
-
-    _init_exceptions();
-
-    _init_syscalls();
-
-    _enable_keyboard_interrupt();
-    _enable_vblank_interrupt();
-    _init_scheduler();
-    _init_screen();
-
-    /* It is necessary to call this other MI function now, which internally
-     * will enable interrupts when safe to do so, which should have been
-     * disabled all along initialization.
-     */
-    xisop_init();
-
-    /* We finally can switch to usermode and jump to MI main().
-     * _usermode() m68k-specific function uses 1024 bytes on the
-     * current supervisor stack to create a user stack, and jumps to
-     * the specified function in user mode using that small stack.
-     */
-    _usermode(main);
-
-    /* NOTREACHED */
-}
-
-
-static void _disable_interrupts(void)
-{
-    /* Turn off scheduling, interrupts and DMA channels */
-    Forbid();
-    /* Disable interrupts */
-    _splhigh();
-    CUSTOM->INTENA = INTENA_CLRALL;
-    CUSTOM->INTREQ = INTREQ_CLRALL;
-    /* Disable DMA */
-    CUSTOM->DMACON = DMACON_CLRALL;
-    /* Disable CIA interrupt generation */
-    CIA_A->ICR = CIA_ICR_CLRALL;
-    CIA_B->ICR = CIA_ICR_CLRALL;
-}
-
-
-static void _stop_floppy_motor(void)
-{
-    /* Stop floppy0 drive motor */
-    CIA_B->PRB &= ~CIAB_PRB_FLOP0;     /* Select */
-    CIA_B->PRB |= CIAB_PRB_FMOTOR;     /* Command */
-}
-
-
-static void _init_memory(void)
-{
-    mchunk_t *mchunk;
-
-    /* Initialize memory system, facilities_init() needs this to be done.
-     * XXX Some effort should be made to better detect the available memory,
-     * but at least it's easy to fix for each system type right now.
-     * The file to modify consists of ../config.h
-     */
-    mchunk = mchunk_init((void *)FPOOLADDR, FPOOLSIZE);
-    mchunk_attach(_MEM_FAST, mchunk);
-    mchunk = mchunk_init((void *)CPOOLADDR, CPOOLSIZE);
-    mchunk_attach(_MEM_CHIP, mchunk);
-}
-
-
-static void _init_syscalls(void)
-{
-    CUSTOM->INTENA = INT_SETCLR | INT_SOFT;
-}
-
-
-static void _enable_keyboard_interrupt(void)
-{
-    /* Enable keyboard interrupts */
-    CIA_A->CRA = CIA_CRA_START | CIA_CRA_INMODE;
-    CIA_A->ICR = CIA_ICR_SETCLR | CIA_ICR_SERDONE;
-    CUSTOM->INTENA = INT_SETCLR | INT_CIAA;
-}
-
-
-static void _enable_vblank_interrupt(void)
-{
-    /* Enable vertical blank interrupt */
-    CUSTOM->INTENA = INT_SETCLR | INT_VBLANK;
-}
-
-
-/* Enable CIA-B TimerA interrupt for scheduler, which has high priority */
-static void _init_scheduler(void)
-{
-    u_int8_t *p;
-    u_int16_t v;
-
-    /* Evaluate latch value to use for scheduler frequency */
-    v = (u_int16_t)(CIA_COUNTSPEED / SCHEDTIMER_HZ);
-    p = (u_int8_t *)&v;
-    /* Stop timer and set latch */
-    CIA_B->CRA = 0x00;
-    CIA_B->TAHI = p[0];
-    CIA_B->TALO = p[1];
-    /* Start and order to load latch value, in contiguous mode */
-    CIA_B->CRA = CIA_CRA_START | CIA_CRA_LOAD;
-    CIA_B->ICR = CIA_ICR_SETCLR | CIA_ICR_TIMA0;
-    /* Enable CIA-B interrupts */
-    CUSTOM->INTENA = INT_SETCLR | INT_CIAB;
-}
-
-
-/* Setup our Amiga Xisop console screen */
-/* XXX I have two choices here. I could use a 16 color screen and emulate
- * ANSI-BBS colors, or just use a two color one and use my very small fonts.
- * in the second case, I could still support a few control codes.
- */
-static void _init_screen(void)
-{
-    u_int16_t s;
-
-    /* I need to allocate/initialize a bitmap/bitplane, as well as
-     * chip memory for the copper list.
-     */
-    s = asplvblank();
-    /* Screen size and position configuration */
-    CUSTOM->DDFSTRT = 0x3C;
-    CUSTOM->DDFSTOP = 0xD4;
-    CUSTOM->DIWSTRT = 0x2C81;
-    CUSTOM->DIWSTOP = 0xF4C1;
-    CUSTOM->CLXCON = 0x0000;
-    /* Enable bitplane and copper DMA */
-    CUSTOM->DMACON = DMACON_SETCLR | DMACON_BLITTER /*| DMACON_COPPER*/;
-    asplx(s);
-}
-
-
-/* These consist of the various interrupt handlers corresponding to each
- * of the 6 maskable hardware interrupt levels. Using _spl*() one can set the
- * current task level which may not be interrupted by every lower level.
- * <intreq> may be used to evaluate the cause of the interrupt.
- */
-
-/* ARGSUSED */
-void _icatch1(u_int16_t intreq)
-{
-    _ipl_t x;
-
-    x = _spl1();
-    if (intreq & INT_SOFT) {
-       /* Software interrupt */
-    }
-    if (intreq & INT_FLOPBLCK) {
-       /* Floppy disk block done interrupt */
-       facility_exechooks(_FACILITY_FLOPPYBLOCK, 0);
-    }
-    if (intreq & INT_SERTBE) {
-       /* Serial RS-232 trasmit buffer empty interrupt */
-       facility_exechooks(_FACILITY_SERIALTBE, 0);
-    }
-    _splx(x);
-}
-
-void _icatch2(u_int16_t intreq)
-{
-    _ipl_t x;
-
-    x = _spl2();
-    if (intreq & INT_CIAA) {
-       /* CIA-A or expansion bus pin 19 interrupt */
-       u_int8_t icrmask = CIA_A->ICR;
-
-       /* CIA-A TimerA available.
-        * CIA-A TimerB used for keyboard.
-        * CIA-A TOD counter available.
-        */
-       if (icrmask & CIA_ICR_TIMB0) {
-           /* CIA-A TimerB reached 0. If used in continuous we only need
-            * to react, otherwise we also should reload a latch value back.
-            * This counts at a rate of 715909/second for NTSC and
-            * 709379/second for PAL.
-            */
-           facility_exechooks(_FACILITY_CIATIMB0, 0);
-       }
-       if (icrmask & CIA_ICR_SERDONE) {
-           /* Keyboard intput interrupt */
-           u_int8_t c;
-
-           c = CIA_A->SDR;
-           facility_exechooks(_FACILITY_KEYBOARD, (int)c);
-       }
-    }
-    _splx(x);
-}
-
-void _icatch3(u_int16_t intreq)
-{
-    _ipl_t x;
-
-    x = _spl3();
-    if (intreq & INT_COPPER) {
-       /* Copper processor generated interrupt */
-       facility_exechooks(_FACILITY_COPPER, 0);
-    }
-    if (intreq & INT_VBLANK) {
-       /* Vertical blank (raster) interrupt */
-       facility_exechooks(_FACILITY_VBLANK, 0);
-    }
-    if (intreq & INT_BLITRDY) {
-       /* Blitter done/ready interrupt */
-       facility_exechooks(_FACILITY_BLITTERREADY, 0);
-    }
-    _splx(x);
-}
-
-/* ARGSUSED */
-void _icatch4(u_int16_t intreq)
-{
-    _ipl_t x;
-
-    x = _spl4();
-    if (intreq & INT_AUDIO0) {
-       /* DMA done for audio channel 0 interrupt */
-       facility_exechooks(_FACILITY_AUDIO, 0);
-    }
-    if (intreq & INT_AUDIO1) {
-       /* DMA done for audio channel 1 interrupt */
-       facility_exechooks(_FACILITY_AUDIO, 1);
-    }
-    if (intreq & INT_AUDIO2) {
-       /* DMA done for audio channel 2 interrupt */
-       facility_exechooks(_FACILITY_AUDIO, 2);
-    }
-    if (intreq & INT_AUDIO3) {
-       /* DMA done for audio channel 3 interrupt */
-       facility_exechooks(_FACILITY_AUDIO, 3);
-    }
-    _splx(x);
-}
-
-/* ARGSUSED */
-void _icatch5(u_int16_t intreq)
-{
-    _ipl_t x;
-
-    x = _spl5();
-    if (intreq & INT_SERRBF) {
-       /* Serial RS-232 read buffer full interrupt */
-       facility_exechooks(_FACILITY_SERIALRBF, 0);
-    }
-    if (intreq & INT_FLOPSYNC) {
-       /* Floppy disk sync pattern found interrupt */
-       facility_exechooks(_FACILITY_FLOPPYSYNC, 0);
-    }
-    _splx(x);
-}
-
-/* Level 6 handled by assembly code */
-
-
-/* And generic C trap handler to catch remaining trap vectors (0 and 1 are
- * used by the system calls and _yield(), respectively.
- */
-void _tcatch(int vector)
-{
-    _ipl_t x;
-
-    x = _splhigh(); /* XXX */
-    facility_exechooks(_FACILITY_TRAP, vector);
-    _splx(x);
-}
-
-
-/* A hack to display the exception vector number using raster lines */
-void _ecatch(int vector)
-{
-    static u_int16_t ecolors[2] = {0x0F00, 0x0A00};
-    register bool col = FALSE;
-
-    if (_rlock_try(&elock)) {
-       _splhigh();
-       for (;;) {
-           register int i;
-
-           for (i = 0; i < vector; i++) {
-               CUSTOM->COLOR[0] = ecolors[col];
-               ldelay(2);
-               CUSTOM->COLOR[0] = 0x0000;
-               ldelay(2);
-           }
-           ldelay(8);
-           col = !col;
-       }
-    }
-    for (;;)
-       _idle();
-}
-
-
-
-/* Function we supply to Xisop which calls it to allow us to initialize
- * our port-specific shared libraries and tasks.
- */
-void _port_init(void)
-{
-    register task_t *task;
-
-    if ((task = task_alloc(_task_color_server, NULL, NULL, 0, 4096, TF_KERNEL))
-           != NULL)
-       task_start(task);
-    else
-       _panic(0x0F00); /* Red */
-}
-
-
-
-/* These are our port-specific tasks */
-
-/* ARGSUSED */
-static int _task_color_server(void *res, void *args)
-{
-    port_t *port;
-
-    /* Create our public port */
-    if ((port = port_create("COLOR")) != NULL) {
-       struct taskarg targ[3];
-       task_t *task;
-       hookid_t kbdhook;
-
-       /* Setup an interrupt handler (only for fun) */
-       kbdhook = hook_attach(_FACILITY_KEYBOARD, 10, 0, _keyboard_hook, NULL);
-
-       /* Start our tasks. As these require our port to communicate through,
-        * note that we created it first.
-        */
-       targ[0].color = 0x00F0;
-       targ[0].rounds = 6000;
-       if ((task = task_alloc(_task_color_client, NULL, &targ[0], 0, 4096,
-                       TF_SHARED)) != NULL)
-           task_start(task);
-       targ[1].color = 0x00C0;
-       targ[1].rounds = 4000;
-       if ((task = task_alloc(_task_color_client, NULL, &targ[1], 0, 4096,
-                       TF_SHARED)) != NULL)
-           task_start(task);
-       targ[2].color = 0x0090;
-       targ[2].rounds = 2000;
-       if ((task = task_alloc(_task_color_client, NULL, &targ[2], 0, 4096,
-                       TF_SHARED)) != NULL)
-           task_start(task);
-
-       /* Main loop. All we do is listen for requests via our port, in the
-        * form of messages. When we get one, display the requested color,
-        * and reply. This task should be in STATE_WAIT most of the time,
-        * and only awakens to answer requests then goes back to sleep.
-        */
-       for (;;) {
-           port_t *ports[] = {
-               port
-           };
-           register struct initmsg *msg = NULL;
-
-           /* Black to show that we are sleeping */
-           CUSTOM->COLOR[0] = 0x0000;
-           ldelay(1);
-           if ((port_wait(ports, 1, NULL)) == port) {
-               /* We could use while () here instead of if (), however this
-                * gives a better demonstration. When the screen eventually
-                * gets purple, all tasks are sleeping (init, reaper and
-                * this task, since our three children have died already).
-                * If we use while (), we never go in sleep mode, since there
-                * are several feeders and they are of equal priority than
-                * us.
-                */
-               if ((msg = (struct initmsg *)port_get(port)) != NULL) {
-                   CUSTOM->COLOR[0] = msg->color;
-                   if (!port_reply((message_t *)msg))
-                       _panic(0x0F00); /* Red */
-               }
-           } else
-               _panic(0x0FF0); /* Yellow */
-       }
-
-       port = port_destroy(port);
-    }
-
-    _panic(0x0FFF);    /* White */
-    /* NOTREACHED */
-    return 0;
-}
-
-
-/* ARGSUSED */
-static int _task_color_client(void *res, void *args)
-{
-    port_t *rport;
-
-    /* Create our reply port */
-    if ((rport = port_create(NULL)) != NULL) {
-       port_t *sport;
-
-       /* Locate task_init()'s public port */
-       if ((sport = port_find("COLOR")) != NULL) {
-           struct initmsg msg;
-           port_t *ports[] = {
-               rport
-           };
-           struct taskarg *targ = args;
-           register u_int32_t rounds = targ->rounds;
-
-           msg.color = targ->color;
-           /* Send coloring requests via the public COLOR port.
-            * For each request we wait for a reply, and then continue.
-            * This task runs most of the time, only sleeping when waiting
-            * for a result from the slave task.
-            */
-           for (;rounds > 0; rounds--) {
-               if (port_send(sport, rport, (message_t *)&msg)) {
-                   if ((port_wait(ports, 1, NULL)) == rport) {
-                       /* Just get rid of messages since we don't need to
-                        * verify a result code.
-                        */
-                       port_flush(rport);
-                   } else
-                       _panic(0x0FF0); /* Yellow */
-               } else
-                   _panic(0x0F00);     /* Red */
-           }
-       }
-
-       rport = port_destroy(rport);
-    }
-
-    return 0;
-}
-
-
-/* Used in the case of a fatal error we catch */
-void _panic(u_int16_t color)
-{
-    sched_disable();
-    sys_int_disable();
-    for (;;) {
-       CUSTOM->COLOR[0] = color;
-       ldelay(2);
-       CUSTOM->COLOR[0] = 0x0000;
-       ldelay(2);
-    }
-    /* NOTREACHED */
-}
-
-
-/* Mainly used as a test for now */
-/* ARGSUSED */
-static void _keyboard_hook(hookid_t hookid, int reason, void *udata)
-{
-    register u_int16_t col = 0;
-
-    /* Just display a color corresponding to the keyboard code */
-    col |= reason; col <<= 8; col |= reason;
-    CUSTOM->COLOR[0] = col;
-}
diff --git a/Xisop/src/ports/amiga/boot/make.sh b/Xisop/src/ports/amiga/boot/make.sh
deleted file mode 100755 (executable)
index 820e10d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.2 2004/01/20 20:56:20 mmondor Exp $
-
-. ../../../makedefs.sh
-
-# Create tools
-show $L_CC -Wall -o tools/aosbblock tools/aosbblock.c
-show $L_CC -Wall -o tools/dumpkern tools/dumpkern.c
-show $L_CC -Wall -o tools/config tools/config.c
-KERNADDR=$(tools/config)
-
-# Create kernel image
-show $C_COMPC -I$SRCDIR init.c
-A=`$L_LS ../../../common/kernel/ar/*.a ../ar/*.a ../../../processor/ar/*.a ../../../common/kernlib/ar/*.a`
-show $C_LD -nostdlib -e _start -Ttext $KERNADDR -o image.o init.o $A
-show $C_LD -T image_script.ld -Ttext $KERNADDR -nostdlib -o image.bin init.o $A
-
-# Create bootblock loader
-show $C_COMPS -I$SRCDIR -o bootf/bootf_s.o bootf/bootf_s.s
-show $C_COMPC -I$SRCDIR -o bootf/bootf_c.o bootf/bootf_c.c
-show $C_LD -nostdlib -r -Ttext 0x0020b660 -o bootf/bootf.o bootf/bootf_s.o bootf/bootf_c.o
-show $C_LD -T bootf/bootf_script.ld -nostdlib -o bootf/bootf.bin bootf/bootf.o
-show tools/aosbblock bootf/bootf.bin
-
-# Create bootable floppy image
-show $L_CAT bootf/bootf.bin image.bin >bootf/kern.bin
-show $L_DD if=/dev/zero of=xisop.adf bs=901120 count=1
-show tools/dumpkern xisop.adf bootf/kern.bin
-
-$L_ECHO ===
-$L_ECHO The floppy image should be $SRCDIR/ports/amiga/boot/xisop.adf
-$L_ECHO ===
diff --git a/Xisop/src/ports/amiga/boot/tools/aosbblock.c b/Xisop/src/ports/amiga/boot/tools/aosbblock.c
deleted file mode 100644 (file)
index 95cbeae..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $Id: aosbblock.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* 
- * Fixes a bootblock to be 1024 bytes in size, and sets it's AmigaOS checksum
- */
-
-
-
-#include <sys/types.h>
-#include <stdio.h>
-
-
-
-int main(int, char **);
-u_int32_t checksum(u_int32_t *, int);
-
-
-
-int main(int argc, char **argv)
-{
-    FILE *fh;
-    u_int32_t lblock[256];
-    int i;
-    char *block = (char *)lblock;
-
-    if (argc == 2) {
-
-       if ((fh = fopen(argv[1], "rb"))) {
-           /* First make sure to 0 pad block, then load block */
-           for (i = 0; i < 256; i++)
-               lblock[i] = 0;
-           fread(block, 1, 1024, fh);
-           fclose(fh);
-       } else {
-           printf("could not open file \"%s\" for reading\n", argv[1]);
-           exit(-1);
-       }
-
-       /* Calculate block checksum and fix it */
-       lblock[1] = 0;
-       lblock[1] = htonl(0xFFFFFFFF - checksum(lblock, 256));
-
-       /* Write back file over old one */
-       if ((fh = fopen(argv[1], "wb"))) {
-           fwrite(block, 1, 1024, fh);
-           fclose(fh);
-       } else {
-           printf("could not open file \"%s\" for writing\n", argv[1]);
-           exit(-1);
-       }
-
-    } else {
-       printf("usage: aosbblock <file>\n");
-       exit(-1);
-    }
-
-    exit(0);
-}
-
-
-u_int32_t checksum(u_int32_t *block, int size)
-{
-    u_int32_t sum, lastsum;
-    int i;
-
-    for (sum = 0, i = 0; i < size; i++) {
-       lastsum = sum;
-       sum += ntohl(block[i]);
-       if (sum < lastsum)
-           ++sum;
-    }
-
-    return sum;
-}
diff --git a/Xisop/src/ports/amiga/boot/tools/config.c b/Xisop/src/ports/amiga/boot/tools/config.c
deleted file mode 100644 (file)
index 116feca..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $Id: config.c,v 1.1 2004/01/20 20:56:20 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This program is useful to know the proper address to use in image_script.ld
- * and make.sh for building the kernel image.
- */
-
-
-
-#include <stdio.h>
-#include "../config.h"
-
-
-
-int main(void);
-
-
-
-int main(void)
-{
-    printf("0x%08x\n", KERNADDR);
-    /*
-    printf("Supervisor stack location (0x%08x bytes): 0x%08x\n",
-           STACKSIZE, STACKADDR);
-    printf("Kernel image location (0x%08x bytes): 0x%08x\n",
-           KERNSIZE, KERNADDR);
-    printf("Usable multipurpose RAM: (0x%08x bytes) 0x%08x\n",
-           POOLSIZE, POOLADDR);
-     */
-
-    return 0;
-}
diff --git a/Xisop/src/ports/amiga/boot/tools/dumpkern.c b/Xisop/src/ports/amiga/boot/tools/dumpkern.c
deleted file mode 100644 (file)
index b39abe0..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $Id: dumpkern.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* Simple program to allow to dump a kernel image over an existing file
- * (ususally to serve as a virtual floppy for bochs or to create
- * floppy image files), without changing the size of the file.
- */
-
-
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-
-
-
-#define BUFSIZE        4096
-
-
-
-int main(int, char **);
-
-
-
-int main(int argc, char **argv)
-{
-    if (argc == 3) {
-       int ffd, kfd;
-
-       if ((ffd = open(argv[1], O_RDWR)) != -1) {
-           if ((kfd = open(argv[2], O_RDONLY)) != -1) {
-               char buf[BUFSIZE];
-               size_t len;
-
-               while ((len = read(kfd, buf, BUFSIZE)) > 0)
-                   if ((write(ffd, buf, len)) != len) {
-                       fprintf(stderr, "Error writing\n");
-                       break;
-                   }
-               close(kfd);
-           } else fprintf(stderr, "Cannot open kernel file '%s'\n", argv[2]);
-           close(ffd);
-       } else fprintf(stderr, "Cannot open disk file '%s'\n", argv[1]);
-    } else fprintf(stderr, "Usage: dumpkern <file> <kernel>\n");
-
-    exit(0);
-}
diff --git a/Xisop/src/ports/amiga/clean.sh b/Xisop/src/ports/amiga/clean.sh
deleted file mode 100755 (executable)
index 7058be2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../generic_makedefs.sh
-
-show $L_RM support_s.o support_c.o ar/*.a
diff --git a/Xisop/src/ports/amiga/make.sh b/Xisop/src/ports/amiga/make.sh
deleted file mode 100755 (executable)
index 9d58b03..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../makedefs.sh
-
-show $C_COMPS -I$SRCDIR support_s.s
-show $C_COMPC -I$SRCDIR support_c.c
-show $C_AR ar/support.a support_s.o support_c.o
-show $C_RANLIB ar/support.a
diff --git a/Xisop/src/ports/amiga/makedefs.sh b/Xisop/src/ports/amiga/makedefs.sh
deleted file mode 100644 (file)
index b1eef0c..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-
-# $Id: makedefs.sh,v 1.2 2003/12/27 00:01:55 mmondor Exp $
-
-# These are various defaults which are used for the building process.
-# Change as required, and don't forget to create the ./port and ./processor
-# symbolic links to their respective directory.
-
-# Local non-cross building tools
-L_AR='ar qS'
-L_AS='as'
-L_CC='gcc'
-L_LD='ld'
-L_NM='nm'
-L_OBJDUMP='objdump'
-L_RANLIB='ranlib'
-L_STRIP='strip'
-L_CAT='cat'
-L_DD='dd'
-
-# Cross building tools (set to same values as L_* if wanted)
-C_PREFIX='/usr/src/tools/bin'
-C_AR="$C_PREFIX/m68k--netbsdelf-ar qS"
-C_AS="$C_PREFIX/m68k--netbsdelf-as"
-C_CC="$C_PREFIX/m68k--netbsdelf-gcc"
-C_LD="$C_PREFIX/m68k--netbsdelf-ld"
-C_NM="$C_PREFIX/m68k--netbsdelf-nm"
-C_OBJDUMP="$C_PREFIX/m68k--netbsdelf-objdump"
-C_RANLIB="$C_PREFIX/m68k--netbsdelf-ranlib"
-C_STRIP="$C_PREFIX/m68k--netbsdelf-strip"
-
-# Other general purpose tools
-L_RM='rm -f'
-L_LN='ln -s'
-L_SED='sed'
-L_ECHO='echo'
-L_LS='ls'
-
-# Command to compile a C module using the cross-compiler
-#C_COMPC="$C_CC -Wall -ffreestanding -nostdinc -m68000 -O2 -fno-function-cse -fomit-frame-pointer -c"
-C_COMPC="$C_CC -Wall -ffreestanding -nostdinc -m68000 -O2 -fno-function-cse -fomit-frame-pointer -c"
-# And to compile an assembly module using the cross-assembler
-C_COMPS="$C_CC -Wall -ffreestanding -nostdinc -m68000 -c"
-
-show()
-{
-       # Only output to stderr, not stdout
-       $L_ECHO "$@" >&2
-       $@
-}
-
-# Useful to compile all .c and .s files in a directory to .o modules
-# $1 = directory
-buildlib()
-{
-       for i in `$L_LS $1/*.s 2>/dev/null`; do
-               DEST=`$L_ECHO $i | $L_SED 's/\.s/\.o/'`
-               show $C_COMPS -I$SRCDIR -o $DEST $i
-       done
-       for i in `$L_LS $1/*.c 2>/dev/null`; do
-               DEST=`$L_ECHO $i | $L_SED 's/\.c/\.o/'`
-               show $C_COMPC -I$SRCDIR -o $DEST $i
-       done
-}
-
-# Deletes all .o files in a directory
-# $1 = directory
-cleanlib()
-{
-       show $L_RM $1/*.o
-}
diff --git a/Xisop/src/ports/amiga/support.h b/Xisop/src/ports/amiga/support.h
deleted file mode 100644 (file)
index bdd609b..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/* $Id: support.h,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* 
- * This code was not derived from original AmigaOS headerfiles, but rather
- * made comparing informations from various books I already had at home,
- * such as "Mapping the Amiga", "La Bible de l'Amiga", and "Amiga Intern".
- *
- * Matt
- */
-
-
-
-#ifndef AMIGA_SUPPORT_H
-#define AMIGA_SUPPORT_H
-
-
-
-#include <common/types.h>
-
-
-
-/* Adapt this as required for NTSC or PAL Amigas */
-
-/* CIA TimerA and TimerB count this amount of ticks per second */
-/* NTSC */
-/*#define CIA_COUNTSPEED 715909*/
-/* PAL */
-#define CIA_COUNTSPEED 709379
-
-
-
-/* The Amiga has two CIA chips, each CIA supports two 8-bit parallel ports
- * and one serial port. Each CIA chip also has two timers. Amiga also has
- * various custom chips (Agnus, Denise, Paula, Ramsey, the copper parallel
- * coprocessor)...
- *
- * The use of the CIA timers and counters is as follows:
- * - CIA-A TOD counter available
- * - CIA-A TimerA used for keyboard timing
- * - CIA-A TimerB available
- * - CIA-B TOD counter available
- * - CIA-B TimerA available, we use it for the Xisop scheduler interrupt.
- * - CIA-B TimerB available
- *
- * Xisop kernel itself may not need to use all those registers, however
- * devices may, and will be able to use this same headerfile.
- */
-
-#define CIA_A  ((volatile CIA *)0x00BFE001)
-#define CIA_B  ((volatile CIA *)0x00BFD000)
-#define CUSTOM ((volatile CUST *)0x00DFF000)
-
-
-/* Each of the two CIAs have this structure (8520 chip as mapped in Amiga) */
-typedef struct CIA {
-    volatile u_int8_t PRA;     /* Parallel port register A */
-    u_int8_t pad1[255];
-    volatile u_int8_t PRB;     /* Parallel port register B */
-    u_int8_t pad2[255];
-    volatile u_int8_t DDRA;    /* Parallel port A data direction register */
-    u_int8_t pad3[255];
-    volatile u_int8_t DDRB;    /* Parallel port B data direction register */
-    u_int8_t pad4[255];
-    volatile u_int8_t TALO;    /* Timer A lower 8 bits */
-    u_int8_t pad5[255];
-    volatile u_int8_t TAHI;    /* Timer A upper 8 bits */
-    u_int8_t pad6[255];
-    volatile u_int8_t TBLO;    /* Timer B lower 8 bits */
-    u_int8_t pad7[255];
-    volatile u_int8_t TBHI;    /* Timer B upper 8 bits */
-    u_int8_t pad8[255];
-    volatile u_int8_t E_LSB;   /* Event counter bits 0-7 */
-    u_int8_t pad9[255];
-    volatile u_int8_t E_MID;   /* Event counter bits 8-15 */
-    u_int8_t pad10[255];
-    volatile u_int8_t E_MSB;   /* Event counter bits 16-23 */
-    u_int8_t pad11[255 + 256];
-    volatile u_int8_t SDR;     /* Serial port data register */
-    u_int8_t pad12[255];
-    volatile u_int8_t ICR;     /* Interrupt control register */
-    u_int8_t pad13[255];
-    volatile u_int8_t CRA;     /* Control register A */
-    u_int8_t pad14[255];
-    volatile u_int8_t CRB;     /* Control register B */
-    u_int8_t pad15[255];
-} CIA;
-
-/* Here are defined common CIA register bits for code clarity */
-#define CIA_ICR_TIMA0  (1 << 0)
-#define CIA_ICR_TIMB0  (1 << 1)
-#define CIA_ICR_TODALRM        (1 << 2)
-#define CIA_ICR_SERDONE        (1 << 3)
-#define CIA_ICR_SIGFLAG        (1 << 4)
-#define CIA_ICR_CIAINT (1 << 7)
-#define CIA_ICR_SETCLR (1 << 7)
-#define CIA_ICR_CLRALL 0x7F
-
-#define CIA_CRA_START  (1 << 0)
-#define CIA_CRA_PBON   (1 << 1)
-#define CIA_CRA_OUTMODE        (1 << 2)
-#define CIA_CRA_RUNMODE        (1 << 3)
-#define CIA_CRA_LOAD   (1 << 4)
-#define CIA_CRA_INMODE (1 << 5)
-#define CIA_CRA_SPMODE (1 << 6)
-
-#define CIA_CRB_START  (1 << 0)
-#define CIA_CRB_PBON   (1 << 1)
-#define CIA_CRB_OUTMODE        (1 << 2)
-#define CIA_CRB_RUNMODE        (1 << 3)
-#define CIA_CRB_LOAD   (1 << 4)
-#define CIA_CRB_INMODE (1 << 5 | 1 << 6)
-#define CIA_CRB_ALARM  (1 << 7)
-
-/* These are Amiga-specific and are different for each of the two CIAs */
-#define CIAA_PRA_MOVL  (1 << 0)        /* Memory overlay bit */
-#define CIAA_PRA_LED   (1 << 1)        /* Pwr LED & aud low pass filt stat */
-#define CIAA_PRA_FCHNG (1 << 2)        /* Floppy disk change */
-#define CIAA_PRA_FRONLY        (1 << 3)        /* Floppy read-only */
-#define CIAA_PRA_FTRK0 (1 << 4)        /* Floppy disk track 0 */
-#define CIAA_PRA_FRDY  (1 << 5)        /* Floppy disk ready for commands */
-#define CIAA_PRA_FIRE0 (1 << 6)        /* Button 1 Port 1 pressed */
-#define CIAA_PRA_FIRE1 (1 << 7)        /* Button 1 port 2 pressed */
-
-#define CIAA_PRB_CDATA 0xFF            /* Centronics data pins/bits */
-
-#define CIAB_PRA_PBUSY (1 << 0)        /* Centronics BUSY */
-#define CIAB_PRA_POUT  (1 << 1)        /* Centronics paper out */
-#define CIAB_PRA_PSEL  (1 << 2)        /* Centronics select */
-#define CIAB_PRA_SDSR  (1 << 3)        /* RS-232 Data Set Ready */
-#define CIAB_PRA_SCTS  (1 << 4)        /* RS-232 Clear To Send */
-#define CIAB_PRA_SDCD  (1 << 5)        /* RS-232 Carrier Detect */
-#define CIAB_PRA_SRTS  (1 << 6)        /* RS-232 Request To Send */
-#define CIAB_PRA_SDTR  (1 << 7)        /* RS-232 Data Terminal Ready */
-
-#define CIAB_PRB_FHSTEP        (1 << 0)        /* Floppy head step */
-#define CIAB_PRB_FHDIR (1 << 1)        /* Floppy head direction */
-#define CIAB_PRB_FSIDE (1 << 2)        /* Floppy side */
-#define CIAB_PRB_FLOP0 (1 << 3)        /* Select Floppy drive 0 */
-#define CIAB_PRB_FLOP1 (1 << 4)        /* Select Floppy drive 1 */
-#define CIAB_PRB_FLOP2 (1 << 5)        /* Select Floppy drive 2 */
-#define CIAB_PRB_FLOP3 (1 << 6)        /* Select Floppy drive 3 */
-#define CIAB_PRB_FMOTOR        (1 << 7)        /* Floppy motor status */
-
-
-/* Useful union to represent 32-bit address split into two 16-bit registers */
-typedef union AADDR {
-    struct {
-       void *addr;             /* Always 32-bit on m68k */
-    } full;
-    struct {
-       u_int16_t addr_h;       /* Bits 16-31 */
-       u_int16_t addr_l;       /* Bits 0-15 */
-    } parial;
-} AADDR;
-
-/* Each of the 4 native 8-bit Amiga channels are controled with this */
-typedef struct AUDCHAN {
-    AADDR AUDLC;       /* Address of audio data */
-    u_int16_t AUDLEN;  /* Length of audio data */
-    u_int16_t AUDPER;  /* Period duration */
-    u_int16_t AUDVOL;  /* Channel volume */
-    u_int16_t AUDDAT;  /* Audio data (to D/A converter) */
-    u_int16_t pad1[2]; /* Unused */
-} AUDCHAN;
-
-/* Sprite information */
-typedef struct SPR {
-    u_int16_t SPRPOS;  /* Sprite start position (vert. and horiz.) */
-    u_int16_t SPRCTL;  /* Control register and vertical stop */
-    u_int16_t SPRDATA; /* Data register A (to RGB output) */
-    u_int16_t SPRDATB; /* Data register B (to RGB output) */
-} SPR;
-
-
-/* And, the Amiga custom chips registers. */
-typedef struct CUST {
-    u_int16_t BLTDDAT; /* Blitter output data (Blitter to RAM) */
-    u_int16_t DMACONR; /* Read DMA control register */
-    u_int16_t VPOSR;   /* MSB of vertical position */
-    u_int16_t VHPOSR;  /* Vertical and horizontal beam position */
-    u_int16_t DSKDATR; /* Dist read data (disk to RAM) */
-    u_int16_t JOY0DAT; /* Joystick/Mouse position game port 0 */
-    u_int16_t JOY1DAT; /* Joystick/Mouse position game port 1 */
-    u_int16_t CLXDAT;  /* Collision register */
-    u_int16_t ADKCONR; /* Read audio/disk control register */
-    u_int16_t POT0DAT; /* Read potentiometer game port 0 */
-    u_int16_t POT1DAT; /* Read potentiometer game port 1 */
-    u_int16_t POTGOR;  /* Read potentiometer port data */
-    u_int16_t SERDATR; /* Read serial port and status */
-    u_int16_t DSKBYTR; /* Read disk data byte and status */
-    u_int16_t INTENAR; /* Read interrupt enable */
-    u_int16_t INTREQR; /* Read interrupt request */
-    AADDR DSKPTR;      /* Disk DMA address */
-    u_int16_t DSKLEN;  /* Disk DMA block length */
-    u_int16_t DSKDAT;  /* Disk write data (RAM to disk) */
-    u_int16_t REFPTR;  /* Refresh counter */
-    u_int16_t VPOSW;   /* Write MSB of vertical beam position */
-    u_int16_t VHPOSW;  /* Write vertical and horizontal beam position */
-    u_int16_t COPCON;  /* Copper control register */
-    u_int16_t SERDAT;  /* Write serial data and stop bits */
-    u_int16_t SERPER;  /* Serial port control register and baud rate */
-    u_int16_t POTGO;   /* Write potentiometer port data and start bit */
-    u_int16_t JOYTEST; /* Write in both mouse counters */
-    u_int16_t STREQU;  /* Horizontal sync with VBlank and equal frame */
-    u_int16_t STRVBL;  /* Horizontal sync wuth vertical blank */
-    u_int16_t STRHOR;  /* Horizontal synchronization signal */
-    u_int16_t STRLONG; /* Long horizontal line marker */
-    /* Following can also be accessed by the copper processor if COPCON=1 */
-    u_int16_t BLTCON0; /* Blitter control register 0 */
-    u_int16_t BLTCON1; /* Blitter control register 1 */
-    u_int16_t BLTAFWM; /* Mask for first data word from A */
-    u_int16_t BLTALWM; /* Mask for last data word from A */
-    AADDR BLTCPTR;     /* Address of source data C */
-    AADDR BLTBPTR;     /* Address of source data B */
-    AADDR BLTAPTR;     /* Address of source data A */
-    AADDR BLTDPTR;     /* Address of destination data D */
-    u_int16_t BLTSIZE; /* Start bit and size of blitter window */
-    u_int16_t BLTCON0L;        /* Like BLTCON0, bits 0-7 */
-    u_int16_t BLTSIZEV;        /* Windth of blitter window */
-    u_int16_t BLTSIZEH;        /* Height of blitter window */
-    u_int16_t BLTCMOD; /* Blitter modulo for source data C */
-    u_int16_t BLTBMOD; /* Blitter modulo for source data B */
-    u_int16_t BLTAMOD; /* Blitter modulo for source data A */
-    u_int16_t BLTDMOD; /* Blitter modulo for destination data D */
-    u_int16_t pad1[4]; /* Unused */
-    u_int16_t BLTCDAT; /* Blitter source data register C */
-    u_int16_t BLTBDAT; /* Blitter source data register B */
-    u_int16_t BLTADAT; /* Blitter source data register A */
-    u_int16_t pad2[3]; /* Unused */
-    u_int16_t DENISEID;        /* Chip identification from Denise */
-    u_int16_t DSKSYNC; /* Disk sync pattern */
-    /* The following registers can always be written to by the Copper */
-    AADDR COP1LPTR;    /* Address of first copper list */
-    AADDR COP2LPTR;    /* Address of second copper list */
-    u_int16_t COPJMP1; /* Jump to start of first copper list */
-    u_int16_t COPJMP2; /* Jump to start of second copper list */
-    u_int16_t COPINS;  /* Copper command register */
-    u_int16_t DIWSTRT; /* Upper left corner of display window */
-    u_int16_t DIWSTOP; /* Lower right corner of display window */
-    u_int16_t DDFSTRT; /* Start of bitplane DMA (horiz. pos.) */
-    u_int16_t DDFSTOP; /* End of bitplane DMA (horiz. pos.) */
-    u_int16_t DMACON;  /* Write DMA control register */
-    u_int16_t CLXCON;  /* Write collision control register */
-    u_int16_t INTENA;  /* Write interrupt enable */
-    u_int16_t INTREQ;  /* Write interrupt request */
-    u_int16_t ADKCON;  /* Audio, disk abd UART control register */
-    AUDCHAN AUDCH[4];  /* Four digital audio channels */
-    AADDR BPLPTR[6];   /* Six bitplane addresses */
-    u_int16_t pad3[4]; /* Unused */
-    u_int16_t BPLCON0; /* Bitplane control register 0 */
-    u_int16_t BPLCON1; /* Bitplane control register 1 (scroll values) */
-    u_int16_t BPLCON2; /* Bitplane control register 2 (priority control) */
-    u_int16_t BPLCON3; /* Bitplane control register 3 */
-    u_int16_t BPL1MOD; /* Bitplane modulo for uneven planes */
-    u_int16_t BPL2MOD; /* Bitplane modulo for even planes */
-    u_int16_t pad4[2]; /* Unused */
-    u_int16_t BPLDAT[6];/* Bitplane data (to RGB output) */
-    u_int16_t pad5[2]; /* Unused */
-    AADDR SPRDATPTR[8];        /* Sprite data registers */
-    SPR SPR[8];                /* Sprite control registers */
-    u_int16_t COLOR[32];/* Color pallete registers (color table) */
-    u_int16_t HTOTAL;  /* Clock count per line (VARBEAM=1) */
-    u_int16_t HSSTOP;  /* H-sync stop position */
-    u_int16_t HBSTRT;  /* H-blank start position */
-    u_int16_t HBSTOP;  /* H-blank stop position */
-    u_int16_t VTOTAL;  /* Number of lines per picture */
-    u_int16_t VSSTOP;  /* V-sync stop line */
-    u_int16_t VBSTRT;  /* V-blank start line */
-    u_int16_t VBSTOP;  /* V-blank stop line */
-    u_int16_t SPRHSTRT;        /* UHRES sprite start line */
-    u_int16_t SPRHSTOP;        /* UHRES sprite stop line */
-    u_int16_t BPLHSTRT;        /* UHRES bitplane start line */
-    u_int16_t BPLHSTOP;        /* UHRES bitplane stop line */
-    u_int16_t HHPOSW;  /* Write DUAL-mode column counter */
-    u_int16_t HHPOSR;  /* Read DUAL-mode column counter */
-    u_int16_t BEAMCON0;        /* Raster beam control register */
-    u_int16_t HSSTRT;  /* H-sync start position */
-    u_int16_t VSSTRT;  /* V-sync start position */
-    u_int16_t HCENTER; /* H-pos. of V-sync in interlace mode */
-    u_int16_t DIWHIGH; /* Screen window, upper bits for start/stop */
-    u_int16_t BPLHMOD; /* UHRES bitplane modulo */
-    AADDR SPRHPTR;     /* UHRES sprite pointer */
-    AADDR BPLHPTR;     /* UHRES bitplane pointer */
-    u_int16_t pad6[7]; /* Unused */
-} CUST;
-
-/* And again some bits definitions for code clarity */
-#define DMACON_AUDIO0  (1 << 0)
-#define DMACON_AUDIO1  (1 << 1)
-#define DMACON_AUDIO2  (1 << 2)
-#define DMACON_AUDIO3  (1 << 3)
-#define DMACON_AUDIO   (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3)
-#define DMACON_FLOPPY  (1 << 4)
-#define DMACON_SPRITE  (1 << 5)
-#define DMACON_BLITTER (1 << 6)
-#define DMACON_COPPER  (1 << 7)
-#define DMACON_BITPLANE        (1 << 8)
-#define DMACON_MASTER  (1 << 9)
-#define DMACON_PRIORITY        (1 << 10)
-#define DMACON_ZEROS   (1 << 13)
-#define DMACON_BLITTING        (1 << 14)
-#define DMACON_SETCLR  (1 << 15)
-#define DMACON_CLRALL  0x07FF
-
-#define ADKCON_0MODVOL1        (1 << 0)
-#define ADKCON_1MODVOL2        (1 << 1)
-#define ADKCON_2MODVOL3        (1 << 2)
-#define ADKCON_3OFF    (1 << 3)
-#define ADKCON_0MODPER1        (1 << 4)
-#define ADKCON_1MODPER2        (1 << 5)
-#define ADKCON_2MODPER3 (1 << 6)
-#define ADKCON_3OFF2   (1 << 7)
-#define ADKCON_FLOP_GCR        (1 << 8)
-#define ADKCON_GCR_SYNC        (1 << 9)
-#define ADKCON_SYNC    (1 << 10)
-#define ADKCON_UARTBRK (1 << 11)
-#define ADKCON_FLOP_MFM        (1 << 12)
-#define ADKCON_SETCLR  (1 << 15)
-
-/* Most of these are shared by INTREQ, INTREQR, INTENA, INTENAR */
-#define INT_SERTBE     (1 << 0)
-#define INT_FLOPBLCK   (1 << 1)
-#define INT_SOFT       (1 << 2)
-#define INT_CIAA       (1 << 3)
-#define INT_COPPER     (1 << 4)
-#define INT_VBLANK     (1 << 5)
-#define INT_BLITRDY    (1 << 6)
-#define INT_AUDIO0     (1 << 7)
-#define INT_AUDIO1     (1 << 8)
-#define INT_AUDIO2     (1 << 9)
-#define INT_AUDIO3     (1 << 10)
-#define INT_AUDIO      (1 << 7 | 1 << 8 | 1 << 9 | 1 << 10)
-#define INT_SERRBF     (1 << 11)
-#define INT_FLOPSYNC   (1 << 12)
-#define INT_CIAB       (1 << 13)
-#define INT_LEVEL6     (1 << 14)       /* INTREQR */
-#define INT_MASTER     (1 << 14)       /* INTENA */
-#define INT_SETCLR     (1 << 15)       /* INTENA & INTREQ */
-#define INTENA_CLRALL  0x3FFF
-#define INTREQ_CLRALL  0x7FFF
-
-
-
-
-/* Stuff we need to initialize before calling Xisop's main() */
-
-/*
-#define        MEMF_CHIP       0x0001
-#define MEMF_FAST      0x0002
-
-void *OpenLibrary(char *, long);
-void CloseLibrary(void *);
-long AvailMem(long);
-void *AllocMem(long, long);
-void *AllocAbs(long, void *);
-void FreeMem(void *, long);
-void Permit(void);
-void Enable(void);
-void *SuperState(void);
-void UserState(void *);
-
-void jdelay(u_int32_t);
-u_int32_t atime(void);
-*/
-void ldelay(u_int32_t);
-
-void Alert(long, void *);
-void Forbid(void);
-void Disable(void);
-void _supervisor(u_int32_t *, size_t, void (*)(void));
-
-/* Set priority level */
-u_int16_t asplvblank(void);
-u_int16_t asplsched(void);
-/* Set priority level exit */
-void asplx(u_int16_t);
-
-
-
-/* Things we export for Xisop
- * --------------------------
- */
-
-
-/* Memory management */
-
-/* Our preferred page size. As Xisop does not support MMU, any size which is
- * resonable and a multiple of 16 can be used.
- */
-#define _PAGE_SIZE     4096
-
-/* Definitions we need for mpool_t */
-#define _MPOOLS                7
-#define _MPOOLSTART    16
-#define _MPOOLSTEP     1
-
-/* Memory types we setup */
-enum _memtypes {
-       _MEM_FAST = 0,
-       _MEM_CHIP,
-       _MEM_MAX
-};
-
-/* Scheduler timer rate */
-#define SCHEDTIMER_HZ  200     /* 4 times the vertical blank rate for now */
-
-/* Interrupt facilities we provide */
-enum _facilities {
-    _FACILITY_SCHEDTIMER = 0,
-    _FACILITY_VBLANK,
-    _FACILITY_FLOPPYSYNC,
-    _FACILITY_FLOPPYBLOCK,
-    _FACILITY_SERIALRBF,
-    _FACILITY_SERIALTBE,
-    _FACILITY_AUDIO,
-    _FACILITY_BLITTERREADY,
-    _FACILITY_COPPER,
-    _FACILITY_CIATIMB0,
-    _FACILITY_KEYBOARD,
-    _FACILITY_TRAP,
-    _FACILITY_MAX
-};
-
-
-/* Functions we provide */
-void _init_exceptions(void);
-void _syscall(u_int32_t, void *, void *);
-void _yield(void *);
-void _port_init(void);
-void _panic(u_int16_t);        /* XXX */
-
-
-
-#endif
diff --git a/Xisop/src/ports/amiga/support_c.c b/Xisop/src/ports/amiga/support_c.c
deleted file mode 100644 (file)
index 71aee29..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $Id: support_c.c,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <common/types.h>
-#include "support.h"
-
-
-
-/* These functions are similar to the _spl()/_splx() and spl()/splx() ones
- * although they work directly with the Amiga hardware INTENA register,
- * thus only disabling the specified interrupt (rather than setting a level).
- * XXX Problem with this is that it's absolutely architecture-dependant.
- * The general purpose spl() functions should be common to the various hardware
- * Xisop supports. Hmm but the devices will be architecture dependant as well;
- * unless kernel provides some basics to access some common things like
- * RS-232 and console I/O.
- */
-
-u_int16_t asplvblank(void)
-{
-    u_int16_t old;
-
-    old = CUSTOM->INTENAR;
-    CUSTOM->INTENA = INT_VBLANK;
-
-    return old;
-}
-
-/* Note: also prevents other CIA-B interrupts meanwhile */
-u_int16_t asplsched(void)
-{
-    u_int16_t old;
-
-    old = CUSTOM->INTENAR;
-    CUSTOM->INTENA = INT_CIAB;
-
-    return old;
-}
-
-void asplx(u_int16_t old)
-{
-    CUSTOM->INTENA = old | INT_SETCLR;
-}
diff --git a/Xisop/src/ports/amiga/support_s.s b/Xisop/src/ports/amiga/support_s.s
deleted file mode 100644 (file)
index 4f54c6e..0000000
+++ /dev/null
@@ -1,865 +0,0 @@
-/* $Id: support_s.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include "support.h"
-
-
-| exec.library base
-ExecBase =     0x0004
-| Various Amiga custom chips registers
-VPOSR  =       0x00DFF004
-VHPOSR =       0x00DFF006
-TODHI  =       0x00BFEA01
-TODMID =       0x00BFE901
-TODLO  =       0x00BFE801
-INTREQR        =       0x00DFF01E
-INTREQ =       0x00DFF09C
-INTENAR        =       0x00DFF01C
-INTENA =       0x00DFF09A
-COLOR0 =       0x00DFF180
-CIA_ICR        =       0x00BFDD00
-
-
-.globl Alert, Forbid, Disable, AvailMem, AllocMem, AllocAbs, FreeMem
-.globl _supervisor, _init_exceptions, _syscall, _yield
-.globl jdelay, ldelay, atime
-
-.text
-
-
-| AmigaOS minimal library. We include here the various functions which the
-| kernel initialization may need.
-
-
-| void [-108]Alert([d7]long alertNum,[a5]char *flags)
-|
-Alert:
-       moveml  %d7/%a5-%a6, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d7
-       moveal  %sp@(20), %a5
-       jsr     %a6@(-108)
-       moveml  %sp@+, %a6-%a5/%d7
-       rts
-
-
-| void [-132]Forbid(void)
-|
-Forbid:
-       movel   %a6, %sp@-
-       moveal  ExecBase:w, %a6
-       jsr     %a6@(-132)
-       moveal  %sp@+, %a6
-       rts
-
-
-/*
-| void [-120]Disable(void)
-|
-Disable:
-       movel   %a6, %sp@-
-       moveal  ExecBase:w, %a6
-       jsr     %a6@(-120)
-       moveal  %sp@+, %a6
-       rts
-
-
-| [d0]long = [-216]Availmem([d1]long reqs)
-|
-AvailMem:
-       moveml  %a6/%d1, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(12), %d1
-       jsr     %a6@(-216)
-       moveml  %sp@+, %d1/%a6
-       rts
-
-
-| [d0]void * = [-198]AllocMem([d0]long bytes, [d1]long reqs)
-|
-AllocMem:
-       moveml  %a6/%d0-%d1, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d0
-       movel   %sp@(20), %d1
-       jsr     %a6@(-198)
-       moveal  %d0, %a0
-       moveml  %sp@+, %d1-%d0/%a6
-       rts
-
-
-| [d0]void * = [-204]AllocAbs([d0]long bytes, [a1]void *addr)
-|
-AllocAbs:
-       moveml  %a1/%a6/%d0, %sp@-
-       moveal  ExecBase:w, %a6
-       movel   %sp@(16), %d0
-       moveal  %sp@(20), %a1
-       jsr     %a6@(-204)
-       moveal  %d0, %a0
-       moveml  %sp@+, %d0/%a6/%a1
-       rts
-
-
-| void [-210]FreeMem([a1]memptr, [d0]bytesize)
-|
-FreeMem:
-       moveml  %a1/%a6/%d0, %sp@-
-       moveal  ExecBase:w, %a6
-       moveal  %sp@(16), %a1
-       movel   %sp@(20), %d0
-       jsr     %a6@(-210)
-       moveml  %sp@+, %d0/%a6/%a1
-       rts
-*/
-
-
-| void _supervisor(u_int32_t *sp, size_t sz, void (*func)(void))
-| Allows to gain m68k supervisor access, and sets up the supervisor stack
-| pointer to the specified address. The supplied entry point function is
-| then called. It is expected to never return, we thus don't need to worry
-| about the registers we modify, except for A7/SSP.
-|
-_supervisor:
-       moveal  %sp@(4), %a1    | SSP to set
-       movel   %sp@(8), %d1    | Size to add
-       moveal  %sp@(12), %a2   | Function to call
-       moveal  ExecBase:w, %a6
-       jsr     %a6@(-150)      | AmigaOS SuperState() exec.library call
-       moveal  %a1, %a7        | Set SSP
-       addal   %d1, %a7        | Jump to end of stack buffer
-       jsr     %a2@            | Call famous function
-       rts                     | Should never be reached.
-
-
-| void _init_exceptions(void)
-| Called from C to initialize interrupts, traps and exception vectors
-|
-_init_exceptions:
-       clrl    _interrupt_depth
-       bsrw    trap_init
-       bsrw    int_init
-       bsrw    except_init
-       rts
-
-
-| Other Amiga-specific assembler routines. The following deal with exceptions,
-| traps and interrupts.
-
-
-| void trap_init(void)
-| Setup our 15 trap vectors
-|
-trap_init:
-       moveml  %a0/%a1, %sp@-
-       moveal  #0x80, %a0
-       lea     %pc@(trap_catch0), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch1), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch2), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch3), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch4), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch5), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch6), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch7), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch8), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch9), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch10), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch11), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch12), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch13), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(trap_catch14), %a1
-       movel   %a1, %a0@
-       moveml  %sp@+, %a1/%a0
-       rts
-
-
-| And our trap handlers
-
-| This trap is special as it handles the backend for the _syscall() function
-| which prototype is as follows:
-| void _syscall(u_int32_t code, void *res, void *args)
-| _syscall() just puts the arguments onto d0, a0 and a1 registers, and causes
-| a trap 0. Our purpose is to copy those arguments on the supervisor
-| stack, call _scatch(), free our arguments from the supervisor stack and
-| return from the exception. The _syscall() caller will free it's own arguments
-| from the user stack.
-|
-trap_catch0:
-       addql   #1, _interrupt_depth
-
-       | Backup registers on supervisor stack
-       | _syscall backed up d0 and a0-a1 as it modifies them to store the
-       | registers for us.
-       |
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-
-       | Move registers which _syscall() setup for us into the stack and
-       | call void _scatch(u_int32_t, void *, void *).
-       |
-       movel   %a1, %sp@-
-       movel   %a0, %sp@-
-       movel   %d0, %sp@-
-       bsrl    _scatch
-       lea     %sp@(12), %sp   | faster than addl #12, %sp
-
-       | Restore registers we backed up
-       |
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-
-
-| This trap is also special in that it triggers an immediate context switch.
-| Used to implement _yield(). It is implemented very similarly to the scheduler
-| timer interrupt handler which forces task preemption.
-|
-trap_catch1:
-       addql   #1, _interrupt_depth
-
-       | First save SR and change it so that we be uninterruptible
-       |
-       movew   %sr, %sp@-
-       movew   #0x2700, %sr
-
-       | Save current CPU context to root->curctx
-       |
-       movel   %a0, %sp@-              | Save A0 internally as we need it
-       movel   %usp, %a0
-       movel   %a0, %sp@-              | And USP
-       lea     root, %a0               | Load root->curctx _ctx_t *
-       moveal  %a0@(44), %a0
-       lea     %a0@(70), %a0           | Position now after struct's SR
-
-       | Save SR, predecrementing. Normally stored at %sp@, but we saved
-       | 10 bytes in the stack, and are using %sp@(10).
-       movew   %sp@(10), %a0@-
-       | Save PC from SS, which is normally stored at %sp@(2), but we saved
-       | 10 bytes in the stack, so are using %sp@(12).
-       movel   %sp@(12), %a0@-         | Save PC, from SS
-       moveml  %a1-%a6/%d0-%d7, %a0@-  | Save A6-A1, D7-D0
-       movel   %sp@+, %a0@-            | Save USP/A7 from backup
-       movel   %sp@+, %a0@-            | Save A0 from backup
-
-       | Now call schedule(), passing the supplied argument we were passed
-       |
-       movel   _yieldparam, %sp@-
-       bsrl    schedule
-       addql   #4, %sp
-
-       | Load context from root->curctx, which may have changed
-       |
-       lea     root, %a0               | Load root->curctx _ctx_t *
-       moveal  %a0@(44), %a0
-       addql   #4, %a0                 | Skip A0 for now as we use it
-       movel   %a0@+, %a1
-       movel   %a1, %usp               | Restore USP/A7
-       moveml  %a0@+, %d7-%d0/%a6-%a1  | Restore D0-D7, A1-A6
-       | Load PC from context and save in SP. Normally it would be %sp@(2)
-       | but there remains 2 bytes we saved in the stack and are using %sp@(4)
-       movel   %a0@+, %sp@(4)          | PC
-       | Restore SR, making sure that supervisor mode bit is set. Normally
-       | stored at %sp@, but we saved 2 bytes on the stack, so %sp@(2).
-       movew   %a0@, %sp@(2)
-       moveal  %a0@(-68), %a0          | Restore A0
-
-       | Restore normal SR
-       |
-       movew   %sp@+, %sr
-
-       | Return from exception, but to PC we loaded
-       |
-       subql   #1, _interrupt_depth
-       rte
-
-
-| These trap handlers consist of a backend for the C _tcatch() function.
-|
-trap_catch2:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     0
-       braw    1f
-trap_catch3:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     1
-       braw    1f
-trap_catch4:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     2
-       braw    1f
-trap_catch5:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     3
-       braw    1f
-trap_catch6:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     4
-       braw    1f
-trap_catch7:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     5
-       braw    1f
-trap_catch8:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     6
-       braw    1f
-trap_catch9:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     7
-       braw    1f
-trap_catch10:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     8
-       braw    1f
-trap_catch11:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     9
-       braw    1f
-trap_catch12:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     10
-       braw    1f
-trap_catch13:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     11
-       braw    1f
-trap_catch14:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     12
-1:
-       | Call our C function: void _tcatch(int);
-       |
-       bsrl    _tcatch
-       addql   #4, %sp
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-
-
-
-| C frontend to catch interrupts. Because of the way Amiga works with INTREQ
-| it is important that they verify and reset their cause bits. This is easily
-| done when dispatching all interrupt levels to a main single C function, with
-| the interrupt level passed as an argument, and leave it do all the work.
-| This is what was previously done here. However, leaving the C function do
-| all the work implied wasting some CPU cycles. For instance, the level is
-| already known via the handler being called, when we still let the C code
-| perform that condition checking again. Moreover, INTREQ handling wasn't
-| particularly optimized properly (using GCC 2.95.3 with m68k output).
-| As some interrupt levels may be generated very frequently it is best to
-| optimize this as much as possible.
-| So we separated the handlers and let the assembler frontend handle INTREQ.
-| For most interrupt handlers, We call a C function handler per interrupt
-| level:
-|    void _icatch<n>(u_int16_t intreqmask)
-| where <intreqmask> is obtained from INTREQR, and we make sure to reset
-| the bits of the mask in INTREQ. It would also be possible to add some more
-| assembly here if wanted to serve special interrupts faster, like RS-232 I/O.
-| NOTE: GCC requires a 32-bit stack entry even for a 16-bit argument.
-
-
-| void int_init(void)
-| Setup our 6 interrupt vectors. Amiga does not use m68k interrupt level 7
-| and they are non-maskable (and hence are of no use to us anyways).
-|
-int_init:
-       moveml  %a0-%a1, %sp@-
-       moveal  #0x64, %a0
-       lea     %pc@(int_catch1), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(int_catch2), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(int_catch3), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(int_catch4), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(int_catch5), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(int_catch6), %a1
-       movel   %a1, %a0@
-       moveml  %sp@+, %a1-%a0
-       rts
-
-
-| These handlers call the various C _icatch<n>() functions
-int_catch1:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       movew   INTREQR, %sp@-
-       clrw    %sp@-
-       bsrl    _icatch1
-       addql   #4, %sp
-       movew   #0x0007, INTREQ
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-int_catch2:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       movew   INTREQR, %sp@-
-       clrw    %sp@-
-       bsrl    _icatch2
-       addql   #4, %sp
-       movew   #0x0008, INTREQ
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-int_catch3:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       movew   INTREQR, %sp@-
-       clrw    %sp@-
-       bsrl    _icatch3
-       addql   #4, %sp
-       movew   #0x0070, INTREQ
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-int_catch4:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       movew   INTREQR, %sp@-
-       clrw    %sp@-
-       bsrl    _icatch4
-       addql   #4, %sp
-       movew   #0x0780, INTREQ
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-int_catch5:
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       movew   INTREQR, %sp@-
-       clrw    %sp@-
-       bsrl    _icatch5
-       addql   #4, %sp
-       movew   #0x1800, INTREQ
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-
-
-| This interrupt handler is special as it also comports CIAB timer A interrupt,
-| which is used by Xisop for the preeptive scheduler. We thus handle it
-| especially, entirely in assembly.
-| Unlike for other interrupt levels, we not just simply save and restore all
-| registers. We store the current context into root->curctx, call schedule(),
-| then load the context from root->curctx.
-| This executes on the Supervisor Stack, and the User Stack Pointer as such
-| is not modified except in context switches.
-|
-int_catch6:
-       addql   #1, _interrupt_depth
-
-       | Raise level to 7
-       |
-       movew   %sr, %sp@-
-       movew   #0x2700, %sr
-
-       | Save D0 as we need it
-       |
-       movel   %d0, %sp@-
-
-       | if (!(intreq & INT_CIAB)) goto 1
-       |
-       movew   INTREQR, %d0
-       btst    #13, %d0
-       beqs    1f
-
-       | if (icrmask & CIA_ICR_TIMA0) goto 2
-       |
-       moveb   CIA_ICR, %d0
-       btst    #0, %d0
-       bnes    2f
-1:
-       | Not the CIAB Timer A interrupt, Restore D0 and end
-       |
-       movel   %sp@+, %d0
-       braw    4f
-2:
-       | Restore D0 and continue
-       |
-       movel   %sp@+, %d0
-
-       | Tasks are expected to not run in supervisor mode.
-        | We have syscalls (including sys_call() one allowing to execute
-       | arbitrary code in supervisor mode), and public interrupt facilities
-       | (to which they can attach hooks) for them which should suffice.
-       | Moreover, system calls are uninterruptible by the scheduler when
-       | running.
-
-       | Store current user context into root->curctx buffer
-       |
-       movel   %a0, %sp@-              | Save A0 internally as we need it
-       movel   %usp, %a0
-       movel   %a0, %sp@-              | And USP
-       lea     root, %a0               | Load root->curctx _ctx_t *
-       moveal  %a0@(44), %a0
-       lea     %a0@(70), %a0           | Position now after struct's SR
-       | Save SR, predecrementing. Normally stored at %sp@, but we saved
-       | 10 bytes in the stack, and are using %sp@(10).
-       movew   %sp@(10), %a0@-
-       | Save PC from SS, which is normally stored at %sp@(2), but we saved
-       | 10 bytes in the stack, so are using %sp@(12).
-       movel   %sp@(12), %a0@-         | Save PC, from SS
-       moveml  %a1-%a6/%d0-%d7, %a0@-  | Save A6-A1, D7-D0
-       movel   %sp@+, %a0@-            | Save USP/A7 from backup
-       movel   %sp@+, %a0@-            | Save A0 from backup
-
-       | Execute _FACILITY_SCHEDTIMER hooks
-       |
-       clrl    %sp@-
-       pea     0                       | _FACILITY_SCHEDTIMER
-       bsrl    facility_exechooks
-       addql   #8, %sp
-
-       | The following ensures to only perform a context switch if not
-       | currently executing a system call trap or other interrupt. The
-       | reason we need this is that the scheduler interrupt has a very
-       | high priority (6), which can actually interrupt most other
-       | exception handlers.
-       |
-       | if (_interrupt_depth != 1) goto 3
-       |
-       cmpil   #1, _interrupt_depth
-       bnes    3f
-
-       | Call schedule(), which internally handles scheduling, and can
-       | modify root->curctx and root->curtask
-       |
-       pea     0
-       bsrl    schedule
-       addql   #4, %sp
-
-3:
-       | Load back root->curctx into the current user CPU context
-       |
-       lea     root, %a0               | Load root->curctx _ctx_t *
-       moveal  %a0@(44), %a0
-       addql   #4, %a0                 | Skip A0 for now as we use it
-       movel   %a0@+, %a1
-       movel   %a1, %usp               | Restore USP/A7
-       moveml  %a0@+, %d7-%d0/%a6-%a1  | Restore D0-D7, A1-A6
-       | Load PC from context and save in SP. Normally it would be %sp@(2)
-       | but there remains 2 bytes we saved in the stack and are using %sp@(4)
-       movel   %a0@+, %sp@(4)          | PC
-       | Restore SR, making sure that supervisor mode bit is set. Normally
-       | stored at %sp@, but we saved 2 bytes on the stack, so %sp@(2).
-       movew   %a0@, %sp@(2)
-       moveal  %a0@(-68), %a0          | Restore A0
-
-4:
-       | Exit point
-       |
-       | Reset INTREQ like for other levels interrupt handlers
-       |
-       movew   #0x2000, INTREQ
-
-       | Restore Interrupt Priority Level
-       |
-       movew   %sp@+, %sr
-
-       | Return using the %sp@(2) address from SS
-       |
-       subql   #1, _interrupt_depth
-       rte
-
-
-
-| void except_init(void)
-| Setup special exception handlers.
-|
-except_init:
-       moveml  %a0-%a1, %sp@-
-       moveal  #0x8, %a0
-       lea     %pc@(except_catch1), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch2), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch3), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch4), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch5), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch6), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch7), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch8), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch9), %a1
-       movel   %a1, %a0@+
-       lea     %pc@(except_catch10), %a1
-       movel   %a1, %a0@
-       moveal  #0x3c, %a0
-       lea     %pc@(except_catch11), %a1
-       movel   %a1, %a0@
-       moveal  #0x60, %a0
-       lea     %pc@(except_catch12), %a1
-       movel   %a1, %a0@
-       moveal  #0x7c, %a0
-       lea     %pc@(except_catch13), %a1
-       movel   %a1, %a0@
-       moveml  %sp@+, %a1-%a0
-       rts
-
-
-| Our exception handlers. Internally calling _ecatch() C function.
-|
-except_catch1: | Bus error
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     1
-       braw    1f
-except_catch2: | Address error
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     2
-       braw    1f
-except_catch3: | Illegal operation
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     3
-       braw    1f
-except_catch4: | Division by zero
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     4
-       braw    1f
-except_catch5: | CHK
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     5
-       braw    1f
-except_catch6: | TRAPV
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     6
-       braw    1f
-except_catch7: | Privilege violation
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     7
-       braw    1f
-except_catch8: | Trace
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     8
-       braw    1f
-except_catch9: | Line A Emu
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     9
-       braw    1f
-except_catch10:        | Line F Emu
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     10
-       braw    1f
-except_catch11:        | Uninitialized interrupt vector
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     11
-       braw    1f
-except_catch12:        | Unjustified interrupt vector
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     12
-       braw    1f
-except_catch13: | NMI ?
-       addql   #1, _interrupt_depth
-       moveml  %d0-%d7/%a0-%a6, %sp@-
-       pea     13
-1:
-       | Call our C function: void _ecatch(int);
-       bsrl    _ecatch
-       addql   #4, %sp
-       moveml  %sp@+, %a6-%a0/%d7-%d0
-       subql   #1, _interrupt_depth
-       rte
-
-
-
-| void _syscall(int function, void *res, void *args)
-| C interface to Xisop syscalls. Because of the C prototype, the three
-| arguments are already pushed unto the user stack before calling _syscall().
-| We thus place them into registers d0, a0 and a1, and cause a trap 0,
-| which resumes execution at trap_catch0 in supervisor mode.
-|
-_syscall:
-       | Save registers we modify
-       moveml  %d0/%a0-%a1, %sp@-
-
-       | Prepare arguments
-       movel   %sp@(16), %d0
-       moveal  %sp@(20), %a0
-       moveal  %sp@(24), %a1
-       | Poof! Through the gate
-       trap    #0
-
-       | Restore registers
-       moveml  %sp@+, %a1-%a0/%d0
-       rts
-
-
-| void _yield(task_t *)
-| Allows a task to immediately return control to the scheduler, allowing
-| other tasks some CPU time immediately. The optional task_t pointer argument
-| permits to suggest a task to run soon again to the scheduler, and should
-| consist of another STATE_READY task.
-| We use a special static buffer to hold this value because we do not want
-| to taint the registers before the context gets saved. Moreover, if we tried
-| to save and restore registers from the stack, we probably would be stealing
-| bytes from the stack of another task which probably was preempted rather than
-| interrupted using _yield() the last time.
-| I tried pushing the argument on the stack and having the other side check
-| it in via the User Stack Pointer, but it failed for some reason.
-|
-_yield:
-       | Use a static buffer since we're not supposed to modify any registers
-       | and that we can't save them on the stack since at return we won't
-       | have the same stack, obviously.
-       movel   %sp@(4), _yieldparam
-       trap    #1
-       rts
-
-
-
-| These consist of various delay functions. These are not particularly
-| useful in multitasking environments since they hug the CPU in loops,
-| but are great for testing purposes.
-
-
-/*
-| void jdelay(long jiffies)
-| Waits until completion of the current frame (vblank), 1/60th of a second
-| for NTSC and 1/50th for PAL, by checking current hardware raster position.
-| Not ideal as using an interrupt, but works. j stands for jiffy, a frame.
-|
-jdelay:
-       moveml  %d0-%d1, %sp@-
-       movel   %sp@(12), %d0
-1:
-       movel   VPOSR, %d1              | Read both VPOSR and VHPOSR at once
-       andil   #0x0001FF00, %d1        | Mask out the vertical beam position
-       bnes    1b
-       dbf     %d0, 1b
-       moveml  %sp@+, %d1-%d0
-       rts
-*/
-
-
-| void ldelay(long lines)
-| Similar to the above function but waits approximately for the start of the
-| next video raster line.
-|
-ldelay:
-       moveml  %d0-%d1, %sp@-
-       movel   %sp@(12), %d0
-1:     movew   VHPOSR, %d1
-       andiw   #0x000F, %d1
-       bnes    1b
-       dbf     %d0, 1b
-       moveml  %sp@+, %d1-%d0
-       rts
-
-
-*/
-| Time related functions.
-
-
-| u_int32_t atime(void)
-| Obtains current time in 50/60Hz resolution, from CIA-A TOD counter
-|
-atime:
-       clrl    %d0
-       moveb   TODHI, %d0
-       lsll    #4, %d0
-       lsll    #4, %d0
-       moveb   TODMID, %d0
-       lsll    #4, %d0
-       lsll    #4, %d0
-       moveb   TODLO, %d0
-       rts
-*/
-
-
-.data
-.align 4
-
-| This counter is used to count the depth of interrupts, so that the scheduler
-| interrupt, which runs at a very high priority, only switches state if the
-| depth is 1. All interrupt and trap handlers increase this variable at
-| startup and decrease it at exit.
-|
-_interrupt_depth:
-       .long   0
-
-| This consists of the parameter which is passed to _yield(), because we cannot
-| save registers on the stack and expect the same values to be loaded back
-| after causing trap #1, because obviously the context (and SP) may have
-| changed.
-|
-_yieldparam:
-       .long   0
diff --git a/Xisop/src/processors/i386/make.sh b/Xisop/src/processors/i386/make.sh
deleted file mode 100755 (executable)
index 0772960..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../makedefs.sh
-
-show $C_COMPS -I$SRCDIR support.s
-show $C_COMPS udivsi3.s
-show $C_COMPS mulsi3.s
-show $C_AR ar/support.a support.o udivsi3.o mulsi3.o
-show $C_RANLIB ar/support.a
diff --git a/Xisop/src/processors/i386/support.h b/Xisop/src/processors/i386/support.h
deleted file mode 100644 (file)
index 380c7ea..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* $Id: support.h,v 1.3 2004/01/30 07:01:24 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef PROCESSOR_I386_H
-#define PROCESSOR_I386_H
-
-
-
-#include <common/types.h>
-
-
-
-#define _LITTLE_ENDIAN
-
-typedef struct _ctx {
-    void *esp, *ebp, *eip;             /* eip == PC, esp = stack top */
-    u_int32_t eax, ebx, ecx, edx;
-    u_int32_t esi, edi;
-    u_int32_t eflags;
-    u_int32_t es, fs, gs, ds;
-} volatile _ctx_t;
-
-typedef volatile int32_t       _lock_t;
-typedef int32_t                        _rlock_t;
-
-
-
-void _lock_init(_lock_t *);
-void _lock_acquire(_lock_t *);
-void _lock_release(_lock_t *);
-bool _lock_try(_lock_t *);
-bool _lock_available(_lock_t *);
-
-void _rlock_init(_rlock_t *);
-void _rlock_acquire(_rlock_t *);
-void _rlock_release(_rlock_t *);
-bool _rlock_try(_rlock_t *);
-bool _rlock_available(_rlock_t *);
-
-u_int16_t _bswap16(u_int16_t);
-u_int32_t _bswap32(u_int32_t);
-
-void _ctx_init(_ctx_t *, u_int32_t *, size_t, void *);
-
-void _idle(void);
-
-
-
-#endif
diff --git a/Xisop/src/processors/i386/support.s b/Xisop/src/processors/i386/support.s
deleted file mode 100644 (file)
index 34b4564..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* $Id: support.s,v 1.4 2004/01/30 07:29:14 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-.globl _spl, _splx
-.globl _lock_init, _lock_acquire, _lock_try, _lock_available, _lock_release
-.globl _rlock_init, _rlock_acquire, _rlock_try, _rlock_release, _rlock_available
-.globl _ctx_init
-.globl setjmp, longjmp
-.globl _idle
-.globl _bswap16, _bswap32
-
-.text
-
-
-/* _spl_t _spl(_spl_t) _spl_t = ?XXX?
-*/
-_spl:
-/*XXX*/
-       ret
-
-
-_lock_init:
-       mov     0x4(%esp,1), %eax
-       movl    $0x0, (%eax)
-       ret
-
-_lock_acquire:
-       mov     0x4(%esp,1), %edx
-       mov     $0x1, %eax
-       lea     0x0(%esi), %esi
-1:     xchg    %eax, (%edx)
-       test    %eax, %eax
-       jne     1b
-       ret
-
-_lock_release:
-       mov     0x4(%esp,1), %eax
-       movl    $0x0, (%eax)
-       ret
-
-_lock_try:
-       mov     0x4(%esp,1), %edx
-       mov     $0x1, %eax
-       xchg    %eax, (%edx)
-       test    %eax, %eax
-       je      1f
-       xor     %eax, %eax
-       ret
-1:     mov     $0x1, %eax
-       ret
-
-_lock_available:
-       mov     0x4(%esp,1), %eax
-       cmpl    $0x0, (%eax)
-       je      1f
-       xor     %eax, %eax
-       ret
-1:     mov     $0x1, %eax
-       ret
-
-
-_rlock_init:
-       mov     0x4(%esp,1), %eax
-       movl    $0x0, (%eax)
-       ret
-
-_rlock_acquire:
-       mov     0x4(%esp,1), %eax
-       incl    (%eax)
-       ret
-
-_rlock_release:
-       mov     0x4(%esp,1), %eax
-       decl    (%eax)
-       ret
-
-_rlock_try:
-       mov     0x4(%esp,1), %eax
-       incl    (%eax)
-       cmpl    $0x1, (%eax)
-       je      1f
-       decl    (%eax)
-       xor     %eax, %eax
-       ret
-1:     mov     $0x1, %eax
-       ret
-
-_rlock_available:
-       mov     0x4(%esp,1), %eax
-       cmpl    $0x0, (%eax)
-       je      1f
-       xor     %eax, %eax
-       ret
-1:     mov     $0x1, %eax
-       ret
-
-
-_bswap16:
-       mov     0x4(%esp,1), %eax
-       ror     $0x8, %ax
-       ret
-
-_bswap32:
-       mov     0x4(%esp,1), %eax
-       ror     $0x8, %ax
-       ror     $0x10, %eax
-       ror     $0x8, %ax
-       ret
-
diff --git a/Xisop/src/processors/m68k/clean.sh b/Xisop/src/processors/m68k/clean.sh
deleted file mode 100755 (executable)
index 63982c8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# $Id: clean.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../generic_makedefs.sh
-
-cleanlib math
-show $L_RM support.o ar/support.a
diff --git a/Xisop/src/processors/m68k/make.sh b/Xisop/src/processors/m68k/make.sh
deleted file mode 100755 (executable)
index 20a99e2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-# $Id: make.sh,v 1.1 2003/10/26 21:19:57 mmondor Exp $
-
-. ../../makedefs.sh
-
-show $C_COMPS -I$SRCDIR support.s
-buildlib math
-show $C_AR ar/support.a support.o math/*.o
-show $C_RANLIB ar/support.a
diff --git a/Xisop/src/processors/m68k/math/README b/Xisop/src/processors/m68k/math/README
deleted file mode 100644 (file)
index 74461b6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Some math functions are required by GCC m68k compiled code. Those were obtained
-from the NetBSD kernel m68k library and adapted. Their BSD license file headers
-were unchanged, however.
diff --git a/Xisop/src/processors/m68k/math/divsi3.s b/Xisop/src/processors/m68k/math/divsi3.s
deleted file mode 100644 (file)
index 8c8aa40..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: divsi3.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matthew Fredette.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-.globl __divsi3
-
-
-
-| NB: this requires that __udivsi3 preserve %a0:
-__divsi3:
-       movel   %sp@(4), %d1    | load the dividend
-       bpls    1f
-       negl    %sp@(4)         | store abs(dividend)
-1:     movel   %sp@(8), %d0    | load the divisor
-       bpls    2f
-       negl    %sp@(8)         | store abs(divisor)
-2:     eorl    %d1, %d0
-       bpls    3f              | branch if sgn(divisor) == sgn(dividend)
-       moveal  %sp@+, %a0      | pop return address
-       pea     %pc@(Lret)      | push our return address
-3:     jmp     __udivsi3
-Lret:  negl    %d0             | negate quotient
-       jmp     %a0@
diff --git a/Xisop/src/processors/m68k/math/modsi3.s b/Xisop/src/processors/m68k/math/modsi3.s
deleted file mode 100644 (file)
index b042612..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* $Id: modsi3.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matthew Fredette.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-.globl __modsi3
-
-
-
-| NB: this requires that __udivsi3 preserve %a0 and return
-| the modulus in %d1:
-__modsi3:
-       moveal  %sp@+, %a0      | pop return address
-       movel   %sp@(4), %d1    | load the divisor
-       bpls    1f
-       negl    %sp@(4)         | store abs(divisor)
-1:     movel   %sp@, %d0       | load the dividend
-       pea     %pc@(Lret)      | push our return address
-       bpls    2f
-       negl    %sp@(4)         | store abs(dividend)
-       subql   #2, %sp@        | adjust return address
-2:     jmp     __udivsi3
-       negl    %d1             | negate modulus
-Lret:  movel   %d1, %d0        | move modulus into %d0
-       jmp     %a0@
diff --git a/Xisop/src/processors/m68k/math/mulsi3.s b/Xisop/src/processors/m68k/math/mulsi3.s
deleted file mode 100644 (file)
index a4cb7c8..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $Id: mulsi3.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matthew Fredette.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-.globl __mulsi3
-
-__mulsi3:
-       movew   %sp@(6), %d0
-       moveal  %d0, %a0        | save B
-       muluw   %sp@(8), %d0    | %d0 holds B * C
-       movew   %sp@(10), %d1
-       moveal  %d1, %a1        | save D
-       muluw   %sp@(4), %d1    | %d1 holds A * D
-       addw    %d1, %d0        | %d0 holds (B * C) + (A * D)
-       swap    %d0
-       clrw    %d0             | %d0 holds ((B * C) + (A * D)) << 16
-       exg     %a0, %d0        | restore B
-       movel   %a1, %d1        | restore D
-       muluw   %d1, %d0        | %d0 holds B * D
-       addl    %a0, %d0        | final result
-       rts
diff --git a/Xisop/src/processors/m68k/math/udivsi3.s b/Xisop/src/processors/m68k/math/udivsi3.s
deleted file mode 100644 (file)
index 3c3d1da..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $Id: udivsi3.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matthew Fredette.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-.globl __udivsi3
-
-__udivsi3:
-       movel   %d2, %sp@-      | save %d2
-       movel   %sp@(12), %d0   | load divisor
-       movel   %sp@(8), %d1    | load dividend
-
-| first, we divide the divisor and dividend by two until 
-| the divisor fits into 16 bits:
-1:     cmpil   #0x10000, %d0
-       bcss    2f
-       lsrl    #1, %d0
-       lsrl    #1, %d1
-       bras    1b
-2:
-
-| now we can do the divide.  to avoid overflow, we have to 
-| do the divide in two parts, high and low, and add the 
-| results together:
-       movew   %d1, %d2        | save low(dividend)
-       clrw    %d1
-       swap    %d1             | %d1 = dividend >> 16
-       divuw   %d0, %d1        | do the high divide
-       moveal  %d1, %a1        | save high divide result
-       movew   %d2, %d1        | concat(remainder, low(dividend))
-       divuw   %d0, %d1        | do the low divide
-       movel   %a1, %d0        | recover high divide result
-       swap    %d0
-       clrw    %d0             | %d0 = finished high divide result
-       andil   #0xffff, %d1    | %d1 = finished low divide result
-       addl    %d1, %d0        | %d0 = quotient guess
-
-| the quotient we have so far is only a guess.  the divide we 
-| did above was really the divide of some dividendB by some 
-| divisorB, where the following hold:
-|
-| (dividend - divisor) <= dividendB <= dividend
-| (divisor / 2) < divisorB <= divisor
-|
-| so our guess quotient cannot be less than our real desired
-| quotient.  however, it might be one too big.
-|
-| to adjust this quotient, we multiply it by the original 
-| divisor and subtract the result from the original dividend.  
-| if the result is nonnegative, our guessed quotient was 
-| correct, and the subtraction result is our remainder.  
-| if the result is negative, our guessed quotient was one 
-| too big, and the subtraction result plus the original 
-| divisor is our remainder.
-|
-| as in mulsi3, we have to do the multiply in stages to avoid 
-| overflow:
-
-       movel   %sp@(12), %d2   | load divisor
-       swap    %d2
-       movel   %d0, %d1
-       muluw   %d2, %d1        | high(divisor) * low(guess)
-       moveal  %d1, %a1        | save high(divisor) * low(guess)
-       swap    %d2
-       movel   %d0, %d1
-       swap    %d1
-       muluw   %d2, %d1        | low(divisor) * high(guess)
-       addl    %a1, %d1
-       swap    %d1
-       clrw    %d1             | %d1 = finished high multiply result
-       moveal  %d2, %a1        | save original divisor
-       muluw   %d0, %d2        | low(guess) * low(divisor)
-       addl    %d1, %d2        | %d2 = guess * divisor
-       
-       movel   %sp@(8), %d1    | load original dividend
-       subl    %d2, %d1        | subtract
-       bccs    3f
-       subql   #1, %d0         | adjust quotient
-       addl    %a1, %d1        | adjust remainder
-3:     movel   %sp@+, %d2      | restore %d2
-       rts
diff --git a/Xisop/src/processors/m68k/math/umodsi3.s b/Xisop/src/processors/m68k/math/umodsi3.s
deleted file mode 100644 (file)
index 37898cf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id: umodsi3.s,v 1.1 2003/10/26 21:19:57 mmondor Exp $ */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matthew Fredette.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-.globl __umodsi3
-
-
-
-| NB: this requires that __udivsi3 preserve the %a0
-| register, and that it returns the modulus in %d1:
-__umodsi3:
-       moveal  %sp@+, %a0      | pop the return address
-       jsr     __udivsi3
-       movel   %d1, %d0        | move the modulus into %d0
-       jmp     %a0@            | return
diff --git a/Xisop/src/processors/m68k/support.h b/Xisop/src/processors/m68k/support.h
deleted file mode 100644 (file)
index 4afe2a3..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $Id: support.h,v 1.6 2004/06/03 05:44:05 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Derived from informations from the "Mise en oeuvre du 68000" book.
- * The spl name was inspired from NetBSD SPL(9) man page. The code for
- * these is in support.s
- */
-
-
-
-#ifndef PROCESSOR_M68K_H
-#define PROCESSOR_M68K_H
-
-
-
-#include <common/types.h>
-
-
-
-/* Definitions for optimizations and network byte order support */
-#define _ARCH_BIG_ENDIAN
-#define _ARCH_INT_BITS 32
-/*#define _ARCH_LOWCACHE*/
-/*#define _ARCH_USEINDEXING*/
-
-
-
-/* Abstract datatypes we must provide */
-
-/* A CPU context which can also hold the state of user tasks.
- * Also used as buffer area for setjmp()/longjmp() functions.
- * Note that USP (User Stack Pointer) is actually SP/A7, as seen
- * from supervisor code, which SP/A7 stack is set to SSP (Supervisor
- * Stack Pointer). This means that from supervisor code the special
- * usp related instructions must be used to manipulate the current
- * user stack pointer, but that from userspace this simply is sp which
- * can be manipulated without supervisor access (like in setjmp()/longjmp()).
- */
-typedef struct _ctx {
-    void *a0, *usp;
-    u_int32_t d0, d1, d2, d3, d4, d5, d6, d7;
-    void *a1, *a2, *a3, *a4, *a5, *a6;
-    void *pc;
-    u_int16_t sr;
-    u_int16_t padding;
-} volatile _ctx_t;
-
-/* A simple lock */
-typedef volatile u_int8_t      _lock_t;
-/* A recursive lock */
-typedef int32_t                        _rlock_t;
-
-/* An interrupt priority level context */
-typedef u_int16_t              _ipl_t;
-
-
-
-/* Set interrupt level control functions */
-_ipl_t _spl(u_int16_t);
-#define _spl0()                _spl(0x2000)
-#define _spl1()                _spl(0x2100)
-#define _spl2()                _spl(0x2200)
-#define _spl3()                _spl(0x2300)
-#define _spl4()                _spl(0x2400)
-#define _spl5()                _spl(0x2500)
-#define _spl6()                _spl(0x2600)
-#define _spl7()                _spl(0x2700)
-#define _splhigh()     _spl(0x2700)
-void _splx(_ipl_t);
-
-/* Atomic locking functions. These are SMP safe. */
-void _lock_init(_lock_t *);
-void _lock_acquire(_lock_t *);
-void _lock_release(_lock_t *);
-bool _lock_try(_lock_t *);
-bool _lock_available(_lock_t *);
-
-/* Atomic recursive locking functions. The same number of release operations
- * must be performed for the lock to become available again, and there can
- * be any number of concurrent lockers.
- */
-void _rlock_init(_rlock_t *);
-void _rlock_acquire(_rlock_t *);
-void _rlock_release(_rlock_t *);
-bool _rlock_try(_rlock_t *);
-bool _rlock_available(_rlock_t *);
-
-/* Efficient byte order conversion functions */
-u_int16_t _bswap16(u_int16_t);
-u_int32_t _bswap32(u_int32_t);
-
-/* Function to create a new CPU context for a task */
-void _ctx_init(_ctx_t *, u_int32_t *, size_t, void *);
-
-/* Function to put the CPU in idle mode until next interrupt occurs.
- * Restricted to supervisor mode.
- */
-void _idle(void);
-
-/* Useful to call Xisop main() from port-specific initialization code */
-void _usermode(int (*)(void));
-
-
-
-#endif
diff --git a/Xisop/src/processors/m68k/support.s b/Xisop/src/processors/m68k/support.s
deleted file mode 100644 (file)
index 990d9a0..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/* $Id: support.s,v 1.4 2004/01/30 07:08:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-.globl _spl, _splx
-.globl _lock_init, _lock_acquire, _lock_try, _lock_available, _lock_release
-.globl _rlock_init, _rlock_acquire, _rlock_try, _rlock_release, _rlock_available
-.globl _bswap16, _bswap32
-.globl _ctx_init
-.globl setjmp, longjmp
-.globl _idle, _usermode
-
-.text
-
-
-| _spl_t _spl(_spl_t)                  _spl_t == u_int16_t
-|
-_spl:  movew   %sr, %d0
-       movew   %sp@(6), %sr
-       rts
-
-
-| void _splx(_spl_t oldstate)
-|
-_splx: movew   %sp@(6), %sr
-       rts
-
-
-| void _lock_init(_lock_t *lock)       _lock_t == u_int8_t
-| Used to create/init new locks
-|
-_lock_init:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       clrb    %a0@
-       moveal  %sp@+, %a0
-       rts
-
-
-| void _lock_acquire(_lock_t *lock)
-| Blocks current CPU in a loop until lock is obtained
-|
-_lock_acquire:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-1:     tas     %a0@
-       bnes    1b
-       moveal  %sp@+, %a0
-       rts
-
-
-| bool _lock_try(_lock_t *lock)
-| Attempts to obtain lock, but returns immediately with TRUE/FALSE result
-|
-_lock_try:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       tas     %a0@
-       beqs    1f
-       clrl    %d0
-       moveal  %sp@+, %a0
-       rts
-1:
-       moveq   #1, %d0
-       moveal  %sp@+, %a0
-       rts
-
-
-| bool _lock_available(_lock_t *lock)
-| Returns 1/TRUE if the lock is currently free, or 0/FALSE if it is locked.
-| Note that this should not be used to attempt to obtain the lock using two
-| steps (see _lock_try() above for this). It is useful to simply know if
-| it is locked, nothing else. Useful for the scheduler on/off switch.
-|
-_lock_available:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       btst    #7, %a0@
-       bnes    1f
-       moveq   #1, %d0
-       moveal  %sp@+, %a0
-       rts
-1:
-       clrl    %d0
-       moveal  %sp@+, %a0
-       rts
-
-
-| void _lock_release(_lock_t *lock)
-| Releases a previously acquired lock
-|
-_lock_release:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       clrb    %a0@
-       moveal  %sp@+, %a0
-       rts
-
-
-| void _rlock_init(_rlock_t *rlock)    _rlock_t = int32_t
-| Initializes a recursive lock
-|
-_rlock_init:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       clrl    %a0@
-       moveal  %sp@+, %a0
-       rts
-
-
-| void _rlock_acquire(_rlock_t *rlock)
-| Acquires the lock, recursively
-|
-_rlock_acquire:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       addql   #1, %a0@
-       moveal  %sp@+, %a0
-       rts
-
-
-| void _rlock_release(_rlock_t *rlock)
-| Releases the lock. _rlock_acquire() and _rlock_release() instances must pair
-| for the lock to eventually be available again.
-|
-_rlock_release:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       subql   #1, %a0@
-       moveal  %sp@+, %a0
-       rts
-
-
-| bool _rlock_try(_rlock_t *rlock)
-| Atomically acquires the lock like _rlock_acquire(), but returns TRUE if
-| we then are the only locker. Otherwise, releases the lock back and return
-| FALSE. Obviously, if we are the only locker, the _rlock_t counter will be
-| one (1). This allows to perform an atomic
-| _rlock_available() + _rlock_acquire() pair.
-|
-_rlock_try:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       moveq   #1, %d0
-       addql   #1, %a0@
-       cmpl    %a0@, %d0
-       beqs    1f
-       subql   #1, %a0@
-       clrl    %d0
-1:     moveal  %sp@+, %a0
-       rts
-
-
-| bool _rlock_available(_rlock_t *rlock)
-| Returns TRUE if the lock is available, or if FALSE if there are any lockers.
-|
-_rlock_available:
-       movel   %a0, %sp@-
-       moveal  %sp@(8), %a0
-       clrl    %d0
-       cmpl    %a0@, %d0
-       bnes    1f
-       moveq   #1, %d0
-1:     moveal  %sp@+, %a0
-       rts
-
-
-| u_int16_t _bswap16(u_int16_t)
-| Swaps the order of the two bytes held in the supplied 16-bit word
-|
-_bswap16:
-       movew   %sp@(6), %d0
-       rorw    #8, %d0
-       rts
-
-
-| u_int32_t _bswap32(u_int32_t)
-| Reverses the order of the four bytes held in the supplied 32-bit word
-| First cause a 16-bit byte swap, then perform a 16-bit word swap within the
-| 32-bit word, and then perform another 16-bit byte swap.
-|
-_bswap32:
-       movel   %sp@(4), %d0
-       rorw    #8, %d0
-       swap    %d0
-       rorw    #8, %d0
-       rts
-
-
-| void _ctx_init(_ctx_t *, u_int32_t *sp, size_t sz, void *pc)
-| Creates a new CPU context which will use specified SP and PC pointers.
-| Note that SP must be pointing at end of stack area, as it grows upwards.
-|
-_ctx_init:
-       moveml  %a0/%d0, %sp@-  | Save a0/d0
-       moveal  %sp@(12), %a0   |               _ctx_t *
-       clrl    %a0@+           | A0
-       movel   %sp@(16), %a0@  | A7/USP        u_int32_t *
-       movel   %sp@(20), %d0   |               size_t
-       addl    %d0, %a0@+      | A7/USP
-       clrl    %a0@+           | D0
-       clrl    %a0@+           | D1
-       clrl    %a0@+           | D2
-       clrl    %a0@+           | D3
-       clrl    %a0@+           | D4
-       clrl    %a0@+           | D5
-       clrl    %a0@+           | D6
-       clrl    %a0@+           | D7
-       clrl    %a0@+           | A1
-       clrl    %a0@+           | A2
-       clrl    %a0@+           | A3
-       clrl    %a0@+           | A4
-       clrl    %a0@+           | A5
-       clrl    %a0@+           | A6
-       movel   %sp@(24), %a0@+ | PC            void *
-       clrl    %a0@            | SR + padding
-|      clrw    %a0@+           | SR
-|      clrw    %a0@            | 16-bit 32-bit padding
-       moveml  %sp@+, %d0/%a0  | Restore d0/a0
-       rts
-
-
-| int setjmp(jmp_buf);
-| We can manipulate SP/USP/A7 from user state without problems. We do not need
-| to manipulate SR. We can safely run in usermode.
-| The supplied jmp_buf is actually a pointer to a _ctx_t. We must return 0
-| normally, but must return the value supplied to longjmp() when it is called.
-| To do this, we zero D0, save context to jmp_buf, and return. longjmp() will
-| load that context back and set D0 to the wanted value before returning.
-|
-setjmp:
-       movel   %a0, %sp@-              | Save A0 (4 bytes) to current stack
-       moveal  %sp@(8), %a0            | Pointer to _ctx_t
-       clrl    %d0                     | Default return value to 0
-       lea     %a0@(66), %a0           | Pos now after pc
-       movel   %sp@(6), %a0@-          | PC norm at %sp@(2), we saved 4 bytes
-       moveml  %a1-%a6/%d0-%d7, %a0@-  | Save A6-A1, D7-D0
-       movel   %sp, %a0@               | Save A7/USP (without saved 4 bytes)
-       addql   #4, %a0@-
-       movel   %sp@+, %a0@-            | Restore A0 and save it
-       rts
-
-
-| void longjmp(jmp_buf, int)
-| No need to save registers since we are loading the supplied state.
-| We technically never return, we however make sure to load D0 (which
-| will become setjmp() return value) with the supplied value argument.
-|
-longjmp:
-       moveal  %sp@(4), %a0            | _ctx_t pointer
-       movel   %sp@(8), %d0            | Return value for setjmp()
-       addql   #4, %a0                 | Now at usp
-       moveal  %a0@+, %sp              | Restore context stack pointer
-       addql   #4, %a0                 | Now at d1
-       moveml  %a0@+, %d7-%d1/%a6-%a1  | Load registers from context
-       movel   %a0@, %sp@(2)           | Restore return PC
-       moveal  %a0@(-68), %a0          | Restore A0
-       rts                             | Resume at setjmp() saved PC
-
-
-| void _idle(void)
-| Puts CPU in sleep mode until next interrupt occurs. Useful to not use 100%
-| CPU time and overheat when all tasks are idle. Also saves alot of power
-| on battery powered systems. Restricted to supervisor mode.
-|
-_idle:
-       movew   %sr, %sp@-
-       stop    #0x2000
-       movew   %sp@+, %sr
-       rts
-
-
-| void _usermode(int (*)(void));
-| Useful for port-specific init code to call Xisop main()
-| Permits to switch from supervisor mode to usermode and jump to the specified
-| function. The current supervisor stack is used to setup the user stack (US).
-| The user stack we create is 1024 bytes. Obviously, the SS should have enough
-| room for this. The function we jump to is expected to only perform minor
-| initialization, like to start the first Xisop task, with it's own stack.
-| Used to call Xisop's main() function from init.c
-|
-_usermode:
-       moveal  %sp@(4), %a0    | Address to jump to
-       movel   %sp, %a1
-       lea     %sp@(-1024), %sp
-       movel   %a1, %usp
-       andiw   #0xdfff, %sr    | Switch to usermode
-       jmp     %a0@
diff --git a/site/contributors.html b/site/contributors.html
deleted file mode 100644 (file)
index 42b5895..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: contributors.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Contributors</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html"><em>Contributors</em></a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">MMSoftware Contributors</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-These contributors generally consist of various mmsoftware users across the
-globe who are developing related third-party software, to add features such as
-frontends and configuration tools. They are free to release their software
-under their prefered licenses and conditions. The contributors maintain
-their own software themselves, so bug reports or suggestions should be sent
-directly to them. The content of their section become their own responsibility.
-To obtain sources for the official mmsoftware releases please visit the
-<a href="software.html">software</a> area.
-</p><p>
-I personally thank the contributors for their interest in my projects.
-</p>
-<table border="1" bgcolor="#d0d0f0" width="100%">
-<tr><td align="center">
-<a href="software/contributors/joostendorp/index.html">Jeroen Oostendorp</a>
-</td></tr>
-<tr><td align="center">
-<a href="software/contributors/ddemaggio/index.html">Daniel DeMaggio</a>
-</td></tr>
-<tr><td align="center">
-<a href="software/contributors/aschlett/index.html">Alexander Schlett</a>
-</td></tr>
-<tr><td align="center">
-<a href="software/contributors/jkbentzen/index.html">Jonas Koch Bentzen</a>
-</td></tr>
-<tr><td align="center">
-<a href="software/contributors/vigityan/index.html">Vahram Igityan</a>
-</td></tr>
-</table>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: contributors.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/cvs.html b/site/cvs.html
deleted file mode 100644 (file)
index d5f219a..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: cvs.html,v 1.7 2003/12/10 20:33:58 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - CVS</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html"><em>CVS</em></a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">MMSoftware CVS Repository</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-Note that the CVS repository contains the latest actual development tree
-and should not be used by the general public, it is mostly intended for
-developpers, maintainers and beta-testers. There also can be found some
-software which never have previously been released in the form of an archive.
-</p><p>
-The HTTP cvsweb interface to the CVS repository is no longer available at
-present time. However, read-only public CVS pserver access is provided.
-I highly suggest getting aquainted with the command-line cvs(1) utility
-for best results.
-</p><p>
-Those who want to access the repository via public pserver to access all
-of my BSD-style licensed open source software can use the following command:
-</p><p><font face="times" size="-1">
-% cvs -z6 -d:pserver:anoncvs@cvs.accela.net:/cvsroot co mmondor
-</font></p><p>
-To only obtain the Xisop kernel, <em>mmondor/Xisop</em> may be used as the
-module name. To only retreive the mmsoftware directory,
-<em>mmondor/mmsoftware</em> will be used.</p><p>
-The service is provided using the cvs(1), mmspawnd(8) and mmanoncvs(8)
-utilities as an alternative to the common setup using inetd(8). This
-ensures a secure public pserver setup which cannot affect the original
-repositories or the rest of the system if exploited.
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: cvs.html,v 1.7 2003/12/10 20:33:58 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/donations.html b/site/donations.html
deleted file mode 100644 (file)
index d57d2f1..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: donations.html,v 1.6 2003/06/04 12:17:47 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Donations</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html"><em>Donations</em></a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">Donations to support MMSoftware</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-Free opensource software projects need the support of their users to evolve.
-Programmers spend alot of time trying to make the code efficient, bug-free,
-and user-friendly. In an area where security is a primary concern, like for
-public internet services, the time required to roll safe code is often higher
-than it would be for some other projects. There are design, coding, testing,
-debugging, and auditing sessions. And at times even restructuring when
-required to allow the software to be more manageable for the forthcoming new
-features it should integrate.
-</p><p>
-There are many ways one can use to support the project. One is to help it
-maintain public exposure by providing hosting and bandwidth for a mirror.
-This obviously only should be done on stable connections, it can then become
-useful for people to find a mirror closer to their location, and so that at
-all times at least one mirror remains up if others are ever temporarily down.
-The mmondor.gobot.ca DNS pool of addresses can then be updated once a day,
-verifying the availability and stability of the mirrors. An FTP account or
-other method can be used to mirror the site regularly.
-</p><p>
-Another way is to audit the software against potential security, portability
-issues and bugs, as well as test the software. Beta testers are welcome to
-track the CVS repository tree and to propose diff/patches whenever necessary.
-Also considered a donation is the time other programmers can put in
-contributing third party software related to the projects. Although this may
-not necessarily affect mmsoftware directly, some of that software may be very
-useful for many mmsoftware users.
-</p><p>
-It is also possible to sponsor the work on a particular opensource project or
-feature of one of the existing project by material and/or money donations.
-For example, one may want the software to support another UNIX-style system
-for which the software does not currently work for some reason, and provide
-the necessary hardware and/or software tools to allow to do it.
-</p><p>
-As we are mostly dealing with BSD licensed software it is also possible to
-hire us in order to develop a closed-source implementation with
-custom-specific needs of one of the existing projects. The customer would
-decide whether or not the new branch should eventually be donated, back to the
-main public repository, to fall back under the same BSD-license as well
-(possibly with an advertising clause in the license text).
-</p><p>
-Finally, a thing which is always encouraging and doesn't cost much, is to
-send positive feedback, via email or on freshmeat, about the features you
-enjoy in mmsoftware, if you decide to use it. Gifts are also welcome.
-</p><p>
-We appreciate your contribution to our common goal. We would like to assure
-you that we use it to the best of our efforts to help the project evolve.
-</p><p><font size="-1">
-Matthew Mondor
-</p>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: donations.html,v 1.6 2003/06/04 12:17:47 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/favicon.ico b/site/favicon.ico
deleted file mode 100644 (file)
index dcac835..0000000
Binary files a/site/favicon.ico and /dev/null differ
diff --git a/site/images/CVS.jpg b/site/images/CVS.jpg
deleted file mode 100644 (file)
index 4e382fc..0000000
Binary files a/site/images/CVS.jpg and /dev/null differ
diff --git a/site/images/key.jpg b/site/images/key.jpg
deleted file mode 100644 (file)
index 6b3f9df..0000000
Binary files a/site/images/key.jpg and /dev/null differ
diff --git a/site/images/sigil.jpg b/site/images/sigil.jpg
deleted file mode 100644 (file)
index d6f6ace..0000000
Binary files a/site/images/sigil.jpg and /dev/null differ
diff --git a/site/index.html b/site/index.html
deleted file mode 100644 (file)
index 25f857c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: index.html,v 1.9 2003/09/30 05:34:53 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Main</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<p><td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>Main</em></a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="5">The MMSoftware Project</font><br>
-<a href="http://mmondor.gobot.ca">
-<img border="0" src="images/key.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</a>
-</center>
-<font face="helvetica, arial">
-<p>
-<b>NOTE:</b> The french version is not yet available. Additionally, only
-the master site currently works, mirrors should be up soon.
-</p><p>
-This site provides various opensource <a href="software.html">software</a>
-to anyone who find it useful. The projects mostly were written from scratch by
-Matthew Mondor and released under a BSD-style license, but we also host
-third-party software related to these projects, provided by other
-<a href="contributors.html">contributors</a> worldwide who wanted to make
-their related work freely available.
-</p><p>
-The hosting and bandwidth for the <a href="mirrors.html">mirrors</a> is
-provided by various <a href="donations.html">donators</a> accross the globe.
-Although we attempt to encourage contributors and donators, we try to keep
-this site as free from commercial ads as possible as a convenience to our
-users. The main mmsoftware project <a href="philosophy.html">philosophy</a>
-will describe our goals with more details.
-</p><p>
-Matthew Mondor can be contacted via email at
-<a href="mailto:mmondor@gobot.ca">mmondor@gobot.ca</a> for suggestions,
-contributions, donations, flames, thanks, business and bug reports.
-</p>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<p><table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: index.html,v 1.9 2003/09/30 05:34:53 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/mirrors.html b/site/mirrors.html
deleted file mode 100644 (file)
index ec0583f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: mirrors.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Mirrors</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html"><em>Mirrors</em></a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">MMSoftware Mirrors</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-Here are the current site mirrors and their generous providers, appearing
-in setup chronological order (first setup to last):
-</p>
-<table border="1" bgcolor="#d0d0f0" width="100%">
-<tr><th>Location</th><th>Provider</th><th>URL</th></tr>
-<tr>
-<td align="center">United-States</td>
-<td align="center">Matthew J Backes</td>
-<td align="center"><font size="-1"><a href="http://gobot.accela.net">http://gobot.accela.net</a></font></td>
-</tr><tr>
-<td align="center">Holland</td>
-<td align="center">Jeroen Oostendorp</td>
-<td align="center"><font size="-1"><a href="http://mmondor.oostendorp-ict.nl">http://mmondor.oostendorp-ict.nl</a></font></td>
-</tr><tr>
-<td align="center">Canada</td>
-<td align="center">Ryan Werber</td>
-<td align="center"><font size="-1"><a href="http://mmondor.dynup.net">http://mmondor.dynup.net</a></font></td>
-</tr>
-</table>
-<p>
-If you would like to provide hosting space and bandwidth for a new mirror,
-this would consist of a service donation, please consult the
-<a href="donations.html">donations</a> area for more information about the
-requirements and suggestions.
-</p>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: mirrors.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/new/TODO b/site/new/TODO
deleted file mode 100644 (file)
index 9a13720..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-Because there is a general layout already for the site (left column with
-a main menu, center column with the content for the current page and
-right column for the language menu), I should design something which uses
-templates or such. I did so for the spes project a while back, but which
-dynamically generated the pages, using php.
-
-I want something with which I can simply type a make command for it to
-generate the static html pages. There would be a list of languages and
-for each the process would be automatically repeated, also. For each
-language, a left main menu and right language selection menu would be
-generated, and it's center column contents generated from a template.
-Example of a possible layout:
-
-build/
-build/lang/english
-build/lang/english/menu_main.txt
-build/lang/english/menu_lang.txt
-build/lang/english/page_index.txt
-build/lang/english/page_cvs.txt
-build/lang/english/page_software.txt
-build/lang/english/page_philosophy.txt
-build/lang/english/soft_descriptions.txt
-build/soft_releases.txt
-build/languages.txt
-htdocs/
-
-The files would be generated into htdocs/
-The soft_descriptions.txt file would hold a map of software name->short
-description -> long description, to be used by build/soft_releases.txt in
-lang/page_software.txt .
-build/languages would hold a list of available languages.
-
-The format of the manu_*.txt files would be as follows:
-
-"<Menu title>
-"<Filename>" "<Menu description>"
-
-I.E.
-
-"Sections"
-"index"                "Main"
-"software"     "Software"
-"donations"    "Donations"
-"contributors" "Contributors"
-"philosophy"   "Philosophy"
-"cvs"          "CVS"
-"projects"     "Projects"
-"mirrors"      "Mirrors"
-"contact"      "Contact"
-
-The filename will be suffixed with the language suffix in the htdocs/
-directory, and the file will be generated from the language/page_<filename>.txt
-file.
-
-The format of the languages.txt file would be as follows:
-
-<Suffix> <Directory>
-
-I.E.
-
-en english
-fr french
-ru russian
-
-The format of the page_*.txt files would be standard HTML, but which could
-contain special keywords. The only current special keyword consists of:
-.soft releases
-which should be beginning at the first column, as-is, on a single line.
-This keyword causes the soft_releases.txt file to be parsed with the
-language/soft_descriptions.txt, to create a table of all the available
-software.
-It is possible to do:
-.soft maintained
-.soft unmaintained
-etc.
-
-I also need a special command for mirrors table. And one for links.
-The one for links would automatically append the language suffix and
-html extension...
-
-.link <name> <show>
-.mirrors
-
-A similar system for FAQs:
-
-.faq <name>
-
-
-TODO
-====
-
-- Verify apache multilingual support to use the same convention for
-  page storage...
diff --git a/site/new/build/GNUmakefile b/site/new/build/GNUmakefile
deleted file mode 100644 (file)
index f04011d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# $Id: GNUmakefile,v 1.1 2004/04/30 00:05:53 mmondor Exp $
-
-MMLIBS := $(addprefix ../../../mmsoftware/mmlib/,mmpool.o mmlog.o \
-mmreadcfg.o mmstring.o mmhash.o)
-
-OBJS := mmsite.o
-
-CFLAGS += -Wall -DDEBUG
-
-
-all: mmsite
-
-%.o: %.c
-       cc -c ${CFLAGS} -I. -I../../../mmsoftware/mmlib -o $@ $<
-
-mmsite: $(MMLIBS) $(OBJS)
-       cc -o $@ $(OBJS) -lc $(MMLIBS)
-
-clean:
-       rm -f mmsite $(OBJS) $(MMLIBS)
diff --git a/site/new/build/README b/site/new/build/README
deleted file mode 100644 (file)
index dc99aeb..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-It was chosen to use a simple system based on text files which could be
-used with CVS rather than another type of database to build the site's
-HTML files from. This allows contributors to simply send a diff generated
-by CVS containing their update suggestions and additions. Also, generating
-a static site has advantages, allowing cacheing for efficiency by HTTP
-cache proxies, and easing the task of mirrors updating their copy of the site.
-
-This system makes it easy to maintain the list of available software, as
-well as to translate the site to other languages, while avoiding HTML
-formatting and linking bugs. It also enforces the site's general layout
-through all the site pages. The generated pages are made from an W3C validated
-template for HTML 4.0 Transitional.
-
-The default language causes the pages to have no special suffix, while
-the others will have the short description of the language appended before
-the '.html' extension.
diff --git a/site/new/build/TODO b/site/new/build/TODO
deleted file mode 100644 (file)
index 0832775..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-- Although it is nice to have a few hash tables for fast lookup, some
-  files need to be considered as sequencial lists and will be have to
-  be processed accordingly (using a hash table causes the entries to
-  become in an arbitrary order). Actually, most or all of the base files
-  are lists, while language-specific ones are tables for fast lookup
-  when mapping.
-
-- Work out a system for FAQs similar to the one for software.
-
-- Work out a system for news. This would be nice to announce releases etc
diff --git a/site/new/build/english/faq_mmftpd.txt b/site/new/build/english/faq_mmftpd.txt
deleted file mode 100644 (file)
index 886f552..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# First line consists of FAQ .title
-# Then following are .section <num> <title> for a section,
-# .question <num> <title> for a question. Each can be followed by
-# arbitrary HTML, and an index will be automatically generated.
-#
-.title "Frequently asked questions about mmftpd"
-This FAQ deals with most common problems which first time users encounter.
-.section "Installation"
-This section deals exclusively with mmftpd installation.
-.question "How do I compile mmftpd?"
-Answer to the question
-.question "Another question?"
-Another answer.
-.section "Configuration"
-This section deals with mmftpd configuration.
-.question "Blah??"
-Answer!?
diff --git a/site/new/build/english/faq_mmmail.txt b/site/new/build/english/faq_mmmail.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/faq_mmstatd.txt b/site/new/build/english/faq_mmstatd.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/menu_languages.txt b/site/new/build/english/menu_languages.txt
deleted file mode 100644 (file)
index b7033ae..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# One line per entry, two columns:
-# <language> <description>
-#
-MENU   Languages
-english        English
-french French
diff --git a/site/new/build/english/menu_main.txt b/site/new/build/english/menu_main.txt
deleted file mode 100644 (file)
index ad38d2a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-MENU           Sections
-index          Main
-software       Software
-donations      Donations
-contributors   Contributors
-philosophy     Philosophy
-cvs            CVS
-projects       Projects
-mirrors                Mirrors
-contact                Contact
diff --git a/site/new/build/english/menu_mirrors.txt b/site/new/build/english/menu_mirrors.txt
deleted file mode 100644 (file)
index 6ef947b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# One line per entry, two columns:
-# <name> <description>
-#
-MENU           Mirrors
-canada         Canada
-united-states  United-States
-holland                Holland
diff --git a/site/new/build/english/page_contact.txt b/site/new/build/english/page_contact.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_contributors.txt b/site/new/build/english/page_contributors.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_cvs.txt b/site/new/build/english/page_cvs.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_donations.txt b/site/new/build/english/page_donations.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_index.txt b/site/new/build/english/page_index.txt
deleted file mode 100644 (file)
index 5604f94..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<p><b>NOTE:</b> The French version of this site is not yet available.
-Additionally, only the master site currently works, mirrors should
-be back up eventually.</p>
-<p>This site provides various open source
-.link software software
-to anyone who finds it useful. The projects mostly were written from
-scratch by Matthew Mondor and released under a BSD-style license,
-but we also host third-party software related to these projects,
-provided by other
-.link contributors contributors
-worldwide who wanted to make their related work freely available.</p>
-<p>The hosting and bandwidth for the
-.link mirrors mirrors
-is provided by various
-.link donations donators
-accross the globe. Although we attempt to encourage contributors and
-donators, we try to keep this site as free from commercial ads as
-possible as a convenience to our users. The main mmsoftware project
-.links philosophy philosophy will describe our goals with more details.</p>
-<p>Matthew Mondor can be contacted via email at
-<a href="mailto:mmondor@accela.net">mmondor@accela.net</a> for suggestions,
-contributions, donations, flames, thanks, business and bug reports.</p>
diff --git a/site/new/build/english/page_mirrors.txt b/site/new/build/english/page_mirrors.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_philosophy.txt b/site/new/build/english/page_philosophy.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_projects.txt b/site/new/build/english/page_projects.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/page_software.txt b/site/new/build/english/page_software.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/site/new/build/english/soft_descriptions.txt b/site/new/build/english/soft_descriptions.txt
deleted file mode 100644 (file)
index 3c2bc21..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# Each project is separated by an empty line. The first line of a project
-# consists of it's name, the second line of it's short description, and
-# the following lines, in HTML format, of the long description, ending
-# with an empty line.
-#
-mmftpd
-Unprivileged virtual users FTP server
-Long multiline description follows in HTML, until empty line.
-So it continues...
-And still...
-
-ginseng-ftpd
-blah
-blah
-
diff --git a/site/new/build/mmsite.c b/site/new/build/mmsite.c
deleted file mode 100644 (file)
index 2ef1395..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-/* $Id: mmsite.c,v 1.1 2004/04/30 00:05:53 mmondor Exp $ */
-
-/*
- * Copyright (C) 2003, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This program builds the site in htdocs/. Please read mmsite.8 for more
- * information on the required layout. This is a helper to generate correct
- * HTML, translate the site into multiple languages and build the software
- * and faq indexes and tables, using static pages only. This then allows
- * acceleration using cacheing HTTP proxies and helps to more easily provide
- * a straightforward method for mirror providers.
- */
-
-
-
-/* HEADERS */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <mmtypes.h>
-#include <mmstring.h>
-#include <mmpool.h>
-#include <mmlist.h>
-#include <mmhash.h>
-
-
-
-/* DEFINITIONS */
-
-/* The following system allows to load arbitrary tables from files. The
- * table field is only used for language map to the project descriptions.
- */
-#define COLS_MAX       4
-#define LINE_MAX       256
-
-typedef struct table_node {
-    hashnode_t node;
-    char line[LINE_MAX];
-    char *columns[COLS_MAX];
-    size_t lengths[COLS_MAX];
-    hashtable_t *table;
-} table_node;
-
-/* And for linked lists, where order is necessary */
-typedef struct list_node {
-    node_t node;
-    char line[LINE_MAX];
-    char *columns[COLS_MAX];
-    size_t lengths[COLS_MAX];
-    u_int32_t hash;
-} list_node;
-
-/* The following are definitions helping to use each of our known tables.
- * Let's start with the global ones:
- * --------------------------------
- */
-
-/* table_languages */
-enum columns_languages {
-    LANGUAGES_NAME = 0,
-    LANGUAGES_MAX
-};
-#define LANGUAGES_KEY  LANGUAGES_NAME
-
-/* table_mirrors */
-enum columns_mirrors {
-    MIRRORS_NAME = 0,
-    MIRRORS_URL,
-    MIRRORS_CONTRIBUTOR,
-    MIRRORS_MAX
-};
-#define MIRRORS_KEY    MIRRORS_URL
-
-/* table_pages */
-enum columns_pages {
-    PAGES_NAME = 0,
-    PAGES_MAX
-};
-#define PAGES_KEY      PAGES_NAME
-
-/* table_software */
-enum columns_software {
-    SOFTWARE_CATEGORY = 0,
-    SOFTWARE_DIRECTORY,
-    SOFTWARE_MAX
-};
-#define SOFTWARE_KEY   SOFTWARE_CATEGORY
-
-/* For each of table_software, projects */
-enum columns_projects {
-    PROJECTS_NAME = 0,
-    PROJECTS_STATUS,
-    PROJECTS_VERSION,
-    PROJECTS_MAX
-};
-#define PROJECTS_KEY   PROJECTS_NAME
-
-/* Following are the language-specific tables:
- * ------------------------------------------
- */
-
-/* table_menu_languages */
-enum columns_menu_languages {
-    MENU_LANGUAGES_NAME = 0,
-    MENU_LANGUAGES_DESCR
-};
-
-#define MENU_LANGUAGES_KEY     MENU_LANGUAGES_NAME
-
-/* This structure is hold to hold nodes in project description tables */
-
-#define TDN_PROJECT_MAX        32
-#define TDN_DESCR_S_MAX        256
-#define TDN_DESCR_L_MAX        2048
-
-typedef struct table_descr_node {
-    hashnode_t node;
-    char project[TDN_PROJECT_MAX];
-    char descr_s[TDN_DESCR_S_MAX];
-    char descr_l[TDN_DESCR_L_MAX];
-} table_descr_node;
-
-
-
-/* PROTOTYPES */
-
-int main(void);
-
-static hashtable_t *table_load(const char *, unsigned int, unsigned int);
-static hashtable_t *table_descr_load(const char *);
-static hashtable_t *table_free(hashtable_t *);
-static list_t *list_load(const char *, unsigned int, unsigned int);
-static list_t *list_free(list_t *);
-
-
-
-/* GLOBALS */
-
-static pool_t table_pool, table_descr_pool, list_pool;
-static hashtable_t *table_languages = NULL, *table_descriptions = NULL;
-
-static list_t *list_software = NULL;
-
-
-
-/* CODE */
-
-int main(void)
-{
-    /* First initialize our fast memory management pools */
-    if (!pool_init(&table_pool, malloc, free, sizeof(table_node),
-               65536 / sizeof(table_node), 0, 0)) {
-       (void) fprintf(stderr, "main() - pool_init(table_pool)\n");
-       return EXIT_FAILURE;
-    }
-    if (!pool_init(&table_descr_pool, malloc, free, sizeof(table_descr_node),
-               65536 / sizeof(table_descr_node), 0, 0)) {
-       (void) fprintf(stderr, "main() - pool_init(table_descr_pool)\n");
-       return EXIT_FAILURE;
-    }
-    if (!pool_init(&list_pool, malloc, free, sizeof(list_node),
-               65536 / sizeof(list_node), 0, 0)) {
-       (void) fprintf(stderr, "main() - pool_init(list_pool)\n");
-       return EXIT_FAILURE;
-    }
-
-    /* Load global lists */
-    if ((list_languages = list_load("site_languages.txt", LANGUAGES_MAX,
-                   LANGUAGES_KEY)) == NULL) {
-       (void) fprintf(stderr, "main() - list_load(site_languages.txt)\n");
-       return EXIT_FAILURE;
-    }
-    if ((list_mirrors = list_load("site_mirrors.txt", MIRRORS_MAX,
-                   MIRRORS_KEY)) == NULL) {
-       (void) fprintf(stderr, "main() - list_load(site_mirrors.txt)\n");
-       return EXIT_FAILURE;
-    }
-
-    /* Load required lists */
-    if ((table_languages = table_load("site_languages.txt", LANGUAGES_MAX,
-                   LANGUAGES_KEY)) == NULL) {
-       (void) fprintf(stderr, "main() - table_load(languages)\n");
-       return EXIT_FAILURE;
-    }
-    if ((table_descriptions = table_descr_load(
-                   "english/soft_descriptions.txt")) == NULL) {
-       (void) fprintf(stderr, "main() - table_descr_load(descriptions)\n");
-       return EXIT_FAILURE;
-    }
-    if ((list_software = list_load("site_software.txt", SOFTWARE_MAX,
-                   SOFTWARE_KEY)) == NULL) {
-       (void) fprintf(stderr, "main() - list_load(software)\n");
-       return EXIT_FAILURE;
-    } else {
-       list_node *node;
-
-       for (node = DLIST_TOP(list_software); node != NULL;
-               node = DLIST_NEXT(node))
-           (void) printf("'%s|%s'\n", node->columns[SOFTWARE_CATEGORY],
-                         node->columns[SOFTWARE_DIRECTORY]);
-    }
-
-    {
-       table_node *node;
-
-       if ((node = (table_node *)hashtable_lookup(table_languages,
-                       "english", 7))
-               != NULL)
-           (void) printf("%s\n", node->columns[LANGUAGES_NAME]);
-       else
-           (void) printf("'english' not found!\n");
-    }
-    {
-       table_descr_node *node;
-
-       if ((node = (table_descr_node *)hashtable_lookup(table_descriptions,
-                       "mmftpd", 6)) != NULL) {
-           (void) printf("Project: %s\n", node->project);
-           (void) printf("Descr_s: %s\n", node->descr_s);
-           (void) printf("Descr_l: %s", node->descr_l);
-       } else
-           (void) printf("'mmftpd' not found!\n");
-    }
-
-    table_languages = table_free(table_languages);
-    return EXIT_SUCCESS;
-}
-
-
-/* Loads a hash table from the specified text file which holds one entry
- * per line and <cols> expected columns each. Links each entry to the table
- * using <key> column as the lookup key. Returns the hashtable_t pointer on
- * success, or NULL.
- */
-static hashtable_t *table_load(const char *file, unsigned int cols,
-       unsigned int key)
-{
-    hashtable_t *table = NULL;
-    table_node *node = NULL;
-    FILE *fh;
-
-    if (cols >= COLS_MAX || key >= COLS_MAX) {
-       (void) fprintf(stderr, "table_load(%s) - cols|key >= COLS_MAX!\n",
-                      file);
-       return NULL;
-    }
-
-    if ((fh = fopen(file, "r")) != NULL) {
-       if ((table = malloc(sizeof(hashtable_t))) != NULL) {
-           if (hashtable_init(table, HT_DEFAULT_CAPACITY, HT_DEFAULT_FACTOR,
-                       malloc, free, mm_memcmp, hashtable_hash, TRUE)) {
-               for (;;) {
-                   int i;
-                   size_t len;
-
-                   if (node == NULL && (node = (table_node *)pool_alloc(
-                                   &table_pool, FALSE)) == NULL) {
-                       (void) fprintf(stderr,
-                                      "table_load(%s) - pool_alloc()\n",
-                                      file);
-                       break;
-                   }
-                   if (fgets(node->line, LINE_MAX - 1, fh) == NULL) {
-                       node = (table_node *)pool_free((pnode_t *)node);
-                       break;
-                   }
-                   len = mm_strlen(node->line);
-                   if (len > 0 && node->line[len - 1] == '\n')
-                       len--;
-                   if (len > 0 && node->line[len - 1] == '\r')
-                       len--;
-                   node->line[len] = '\0';
-                   if (*node->line == '#' || *node->line == '\0')
-                       continue;
-                   if (mm_strasplq(node->columns, node->line, cols) != cols) {
-                       (void) fprintf(stderr,
-                                      "table_load(%s) - Invalid line '%s'\n",
-                                      file, node->line);
-                       break;
-                   }
-                   for (i = 0; i < cols; i++)
-                       node->lengths[i] = mm_strlen(node->columns[i]);
-                   node->table = NULL;
-                   if (!hashtable_link(table, (hashnode_t *)node,
-                               node->columns[key], node->lengths[key])) {
-                       (void) fprintf(stderr,
-                                      "table_load(%s) - link key '%s'\n",
-                                      file, node->columns[key]);
-                       break;
-                   }
-                   node = NULL;
-               }
-               if (node != NULL)
-                   table = table_free(table);
-           } else {
-               (void) fprintf(stderr, "table_load(%s) - hashtable_init()\n",
-                              file);
-               free(table);
-               table = NULL;
-           }
-       } else
-           (void) fprintf(stderr, "table_load(%s) - malloc(table)\n",
-                          file);
-       (void) fclose(fh);
-    }
-
-    return table;
-}
-
-/* This function loads another type of file-based table. For each entry,
- * the first line consists of the project name, the second of the short
- * project description, and the following lines of the long description
- * with allowed embedded HTML for emphasis, ending with an empty line.
- */
-static hashtable_t *table_descr_load(const char *file)
-{
-    hashtable_t *table = NULL;
-    table_descr_node *node = NULL;
-    FILE *fh;
-    char line[TDN_DESCR_S_MAX];
-
-    if ((fh = fopen(file, "r")) != NULL) {
-       if ((table = malloc(sizeof(hashtable_t))) != NULL) {
-           if (hashtable_init(table, HT_DEFAULT_CAPACITY, HT_DEFAULT_FACTOR,
-                       malloc, free, mm_memcmp, hashtable_hash, TRUE)) {
-               int field = 0;
-               size_t descr_l_len = 0, project_len = 0;
-
-               for (;;) {
-                   size_t len;
-
-                   if (node == NULL) {
-                       if ((node = (table_descr_node *)pool_alloc(
-                                       &table_descr_pool, FALSE)) == NULL) {
-                           (void) fprintf(stderr,
-                                      "table_descr_load(%s) - pool_alloc()\n",
-                                      file);
-                           break;
-                       }
-                       /* New entry */
-                       field = 0;
-                       descr_l_len = project_len = 0;
-                   }
-                   if (fgets(line, TDN_DESCR_S_MAX - 1, fh) == NULL) {
-                       if (field == 0)
-                           node = (table_descr_node *)pool_free(
-                                   (pnode_t *)node);
-                       else
-                           (void) fprintf(stderr, "table_descr_load(%s) - \
-Incomplete entry for '%s'\n", file, node->project);
-                       break;
-                   }
-                   len = mm_strlen(line);
-                   if (len > 0 && line[len - 1] == '\n')
-                       len--;
-                   if (len > 0 && line[len - 1] == '\r')
-                       len--;
-                   line[len] = '\0';
-                   if (*line == '#' && field == 0)
-                       continue;
-                   if (len == 0) {
-                       /* Empty line, ignore if between two entries,
-                        * consider it as entry termination if we filled
-                        * them all, generate an error otherwise.
-                        */
-                       if (field == 0)
-                           continue;
-                       else if (field == 2) {
-                           /* Link entry and force new entry creation */
-                           if (!hashtable_link(table, (hashnode_t *)node,
-                                       node->project, project_len)) {
-                               (void) fprintf(stderr, "table_descr_load(%s) \
-- hashtable_link(%s)\n", file, node->project);
-                               break;
-                           }
-                           node = NULL;
-                           continue;
-                       } else {
-                           (void) fprintf(stderr, "table_descr_load(%s) - \
-Incomplete entry for '%s'\n", file, node->project);
-                           break;
-                       }
-                   }
-                   if (field == 0) {
-                       /* Project field entry */
-                       if (len > TDN_PROJECT_MAX - 1) {
-                           (void) fprintf(stderr, "table_descr_load(%s) - \
-Project field exceeds %d for '%s'\n", file, TDN_PROJECT_MAX - 1,
-                                       node->project);
-                           break;
-                       }
-                       mm_memcpy(node->project, line, len + 1);
-                       project_len = len;
-                       field = 1;
-                       continue;
-                   } else if (field == 1) {
-                       /* Short description entry */
-                       if (len > TDN_DESCR_S_MAX - 1) {
-                           (void) fprintf(stderr, "table_descr_load(%s) - \
-Short description field exceeds %d for '%s'\n", file, TDN_DESCR_S_MAX - 1,
-                                       node->project);
-                           break;
-                       }
-                       mm_memcpy(node->descr_s, line, len + 1);
-                       field = 2;
-                       continue;
-                   } else if (field == 2) {
-                       /* Long description entry */
-                       if (descr_l_len + len + 1 > TDN_DESCR_L_MAX - 1) {
-                           (void) fprintf(stderr, "table_descr_load(%s) - \
-Long description field exceeds %d for '%s'\n", file, TDN_DESCR_L_MAX - 1,
-                                       node->project);
-                           break;
-                       }
-                       mm_memcpy(&node->descr_l[descr_l_len], line, len);
-                       descr_l_len += len;
-                       node->descr_l[descr_l_len++] = '\n';
-                       continue;
-                   }
-               }
-               if (node != NULL)
-                   table = table_free(table);
-           } else {
-               (void) fprintf(stderr,
-                              "table_descr_load(%s) - hashtable_init()\n",
-                              file);
-               free(table);
-               table = NULL;
-           }
-       } else
-           (void) fprintf(stderr, "table_descr_load(%s) - malloc(table)\n",
-                          file);
-       (void) fclose(fh);
-    }
-
-    return table;
-}
-
-static hashtable_t *table_free(hashtable_t *table)
-{
-    if (table != NULL) {
-       (void) hashtable_destroy(table, TRUE);
-       free(table);
-    }
-
-    return NULL;
-}
-
-
-static list_t *list_load(const char *file, unsigned int cols, unsigned int key)
-{
-    list_t *list = NULL;
-    list_node *node = NULL;
-    FILE *fh;
-
-    if (cols >= COLS_MAX || key >= COLS_MAX) {
-       (void) fprintf(stderr, "list_load(%s) - cols|key >= COLS_MAX!\n",
-                      file);
-       return NULL;
-    }
-
-    if ((fh = fopen(file, "r")) != NULL) {
-       if ((list = malloc(sizeof(list_t))) != NULL) {
-           DLIST_INIT(list);
-           for (;;) {
-               int i;
-               size_t len;
-
-               if (node == NULL && (node = (list_node *)pool_alloc(&list_pool,
-                               FALSE)) == NULL) {
-                   (void) fprintf(stderr,
-                                  "list_load(%s) - pool_alloc()\n",
-                                  file);
-                   break;
-               }
-               if (fgets(node->line, LINE_MAX - 1, fh) == NULL) {
-                   node = (list_node *)pool_free((pnode_t *)node);
-                   break;
-               }
-               len = mm_strlen(node->line);
-               if (len > 0 && node->line[len - 1] == '\n')
-                   len--;
-               if (len > 0 && node->line[len - 1] == '\r')
-                   len--;
-               node->line[len] = '\0';
-               if (*node->line == '#' || *node->line == '\0')
-                   continue;
-               if (mm_strasplq(node->columns, node->line, cols) != cols) {
-                   (void) fprintf(stderr,
-                                  "list_load(%s) - Invalid line '%s'\n",
-                                  file, node->line);
-                   break;
-               }
-               for (i = 0; i < cols; i++)
-                   node->lengths[i] = mm_strlen(node->columns[i]);
-               node->hash = hashtable_hash(node->columns[key],
-                       node->lengths[key]);
-               DLIST_APPEND(list, (node_t *)node);
-               node = NULL;
-           }
-           if (node != NULL)
-               list = list_free(list);
-       } else
-           (void) fprintf(stderr, "list_load(%s) - malloc(list)\n",
-                          file);
-       (void) fclose(fh);
-    }
-
-    return list;
-}
-
-static list_t *list_free(list_t *list)
-{
-    if (list != NULL) {
-       node_t *node, *tnode;
-
-       for (node = DLIST_TOP(list); node != NULL; node = tnode) {
-           tnode = DLIST_NEXT(node);
-           (void) pool_free((pnode_t *)node);
-       }
-       free(list);
-    }
-
-    return NULL;
-}
diff --git a/site/new/build/mmsite.conf b/site/new/build/mmsite.conf
deleted file mode 100644 (file)
index 586b8b5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# General configuration options about the site
-
-TITLE          "Matthew Mondor's Software Site"
-BGCOLOR                #f0f0ff
-TEXT           #000000
-LINK           #3535c5
-VLINK          #700080
-MENU_BGCOLOR   #d0d0f0
-MENU_TEXT      #000066
-FONT           "helvetica, arial"
-HTDOCS         ../htdocs
-DEFAULT_LANG   en
diff --git a/site/new/build/site_faq.txt b/site/new/build/site_faq.txt
deleted file mode 100644 (file)
index ad51485..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# One FAQ entry per line, one column:
-# <faq>
-#
-mmftpd
-mmmail
-mmstatd
diff --git a/site/new/build/site_languages.txt b/site/new/build/site_languages.txt
deleted file mode 100644 (file)
index 27884a1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# One language description per line, one column:
-# <language>
-#
-english
-french
diff --git a/site/new/build/site_mirrors.txt b/site/new/build/site_mirrors.txt
deleted file mode 100644 (file)
index 8e6834f..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# One line per entry, three columns:
-# <name> <URL> <provider>
-#
-canada         http://mmondor.dynup.net/               "Ryan Werber"
-united-states  http://gobot.accela.net/                "Matthew J Backes"
-holland                http://mmondor.oostendorp-ict.nl/       "Jeroen Oostendorp"
diff --git a/site/new/build/site_pages.txt b/site/new/build/site_pages.txt
deleted file mode 100644 (file)
index 8d18ccc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# One entry per line, one column:
-# <name>
-#
-index
-software
-donations
-contributors
-philosophy
-cvs
-projects
-mirrors
-contact
diff --git a/site/new/build/site_software.txt b/site/new/build/site_software.txt
deleted file mode 100644 (file)
index 19c965c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# Each software category, one entry per line, two columns:
-# <category> <location>
-#
-stable         software/stable
-development    software/devl
-old            software/old
diff --git a/site/new/build/soft_development.txt b/site/new/build/soft_development.txt
deleted file mode 100644 (file)
index 8f9ebe9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# One project per line, three columns per project:
-# <projname> <status> <version>
-#
-mmftpd devl 1.0
diff --git a/site/new/build/soft_old.txt b/site/new/build/soft_old.txt
deleted file mode 100644 (file)
index 0874594..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# One project per line, three columns per project:
-# <projname> <status> <version>
-#
-ginseng-ftpd   devl 1.0
diff --git a/site/new/build/soft_stable.txt b/site/new/build/soft_stable.txt
deleted file mode 100644 (file)
index 0874594..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# One project per line, three columns per project:
-# <projname> <status> <version>
-#
-ginseng-ftpd   devl 1.0
diff --git a/site/philosophy.html b/site/philosophy.html
deleted file mode 100644 (file)
index bb21770..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: philosophy.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Philosophy</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html"><em>Philosophy</em></a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">Philosophy behind mmsoftware</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-Several primary goals were the basis to write my suite of public internet
-services. One consisted of a challenge to learn UNIX APIs deeply at the time
-I decided to write my own. This is no longer the case, but probably that the
-most driving factor still has to do with my need to run such services.
-</p><p>
-Of course there exists a variety of solutions for each of the standard
-protocols. However, most of them seemed historical, based on code which made
-it though the years through extreme amounts of patching and kludges. This
-generally results in solutions which are hard to configure, and have gone
-though a long history of security-related issues. Most of them even support
-obsolete protocols, or experimental ones which never have been widely used.
-</p><p>
-Moreover, several of them were subject to strict licensing issues. Writing
-my own software I have the full rights to do whatever I want with it, as
-well as eventually distribute closed-source special editions commercially.
-But I didn't want to be the only one to be able to do this, hence I decided
-to release my software under a BSD-style license (Berkeley Source Distribution
-license), allowing others to modify it and distribute it under source or
-binary form as wanted, only requireing them to add an aknowledgement to their
-product documentation:
-</p><p><font face="times">
-&nbsp;&nbsp;This product includes software written by Matthew Mondor.
-</font></p><p>
-It however obviously is encouraged to report to me the various bug fixes
-or enhancement patch so that the main publicly available tree also evolve.
-</p><p>
-Considering security aspects, most traditional UNIX internet services software
-ran as the superuser, and required standard UNIX users to be added for each
-remote user. I strongly beleive that most administrators enjoy being able to
-only create virtual users rather than real UNIX shell ones for each of their
-users. My daemons therefore only allow virtual users. Moreover, none of them
-require to run as the superuser after their initial startup.  Most of them
-have support for chroot(2) as well, for administrators who need it.
-</p><p>
-These are public services afterall. I personally use them to contribute
-software and services which are often free of charge, and would find it quite
-discouraging if my services were exploited and servers virtually destroyed.
-I think that many administrators are in the same position and would like to
-run safe services.
-</p><p>
-Special care is taken when writing this software to avoid memory leaks (which
-could be a threat to service uptime and autonomy), and to check every
-error condition possible. As the services should remain up, system resources
-error conditions are treated in a safe way; The current operation is cancelled
-to not execute code which requires these new resources to be allocated,
-previous allocated ones are released if any (but not all) were obtained for
-the current operation as well, and the service keeps running as usual. This
-also implies using I/O operations which can timeout where required. Also,
-libc functions with uncertain delay periods get executed by an asynchroneous
-parallel system when userspace threading systems are used, to prevent locking
-the main process, allowing service to remain fluid among the multiple
-simultaneous connections being served. Some effort was also made to keep the
-code clean.
-</p><p>
-C was chosen to write these for several reasons. I am well used to it, having
-used it for many years, was a primary one. A second worthwhile reason is that
-the UNIX, POSIX and BSD APIs are intended for C programs. It is also possible
-for the programmer to optimize C code decently rather than only relying on
-compiler effeciency to do it, gaining speed advantage without having to use
-less maintainable and unportable assembly. When well written, C programs are
-also portable. C++ could have suited, but would result in generally less
-efficient code. I also like to control my own use of memory useage, object
-allocation and garbage collection, hence it was not worth it to use C++.
-Where possible, ANSI-C compliance is observed.
-</p><p>
-Matthew Mondor
-</p>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br>
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: philosophy.html,v 1.5 2003/06/04 12:17:47 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/projects.html b/site/projects.html
deleted file mode 100644 (file)
index 199eeb2..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: projects.html,v 1.6 2003/06/04 12:17:47 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Projects</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html">Software</a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html"><em>Projects</em></a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="4">Various Projects and Background</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-Here first follows an overview of my computer-related background
-</p><p>
-A brief overview of my computer-related background: I touched my first computer
-at the age of 8, an Apple][+, on which I immediately wanted to code games,
-mostly of the text type. I then learned 6802 assembly, as AppleSoft BASIC was
-pretty much useless, and Z80 assembly, which was available through a
-bridgeboard. I then wrote disk utilities (backup, data retreival).
-</p><p>
-I then at my great joy had my first Amiga when I was 15, on which I first used
-mildly AmigaBASIC. Of course a year later I was learning C, and using the RKMS
-wrote AstralPortal (Voice/Fido/Data Modem software) in the few following years.
-I then did some 2d vector graphics using 68000 assembly, C and sometimes
-BlitzBasic (which accepted direct assembly instructions and had nice blit
-routines. Some playing with ARexx was then done. The last thing I developed
-on Amiga was audio sample manipulation and compression utilities in C, along
-with a programmable binaural/hemisync braintrainer, and some custom GUI
-library. Another latest project was a control server which allowed several
-RS232 terminals to be synchronized with a main multitasking server application
-with abstract tty-specific code translation. What a great box that was.
-</p><p>
-Then finally, I decided to get an i386DX/40/8megs although it was already
-deprecated, and started doing some Turbo-C and 8088 assembly on MS-DOS,
-and wrote trivial 2d 8-bit functions library along with a graphic
-block-oriented editor for game programming. Some scrolling, sprite and
-collision code was added, and it was a ready system to write games, but none
-were ever written using it, but demos. As I always was avoiding windows since,
-but had to at least confront it for a while, I finally bought an AMD-K6-2/450
-and learned some Win32 API, tried various compilers with GUI frontends. I
-unfortunately was pretty discouraged after a year or so, and was not
-programming anything useful; Until I made a discovery... Linux 2.0.35 (RH6)
-in December 1999.
-</p><p>
-I used RedHat 6 for a few months, getting aquainted with GCC (which fortunately
-had the same base interface than DICE dcc from Matt Dillon which I was using
-on the Amiga). And, glibc info/man pages. Linux finally made me discover that
-a PC could finally be worth it, as much as Amiga was. I soon found that on
-an AmigaOS shell I couldn't remember the commands, erroneously typing unix
-ones. The switch was made. I then tried Debian Potato, which of course made
-me forget RH for good, and eventually did my own distribution, Ginseng, a
-security and server related distribution. Between Debian and Ginseng I started
-to write a few meaningful TCP server-oriented utilities. I then discovered
-NetBSD.
-</p><p>
-Obviously I then had found my ideal OS, which I am still heavily using today
-on all my systems. I finally was free from glibc, which was everyday getting
-more bloated without true additionnal functionallity.
-I tried other BSD variants and was more convinced that NetBSD still was my
-choice. My current publically available software was written using it.
-Current projects include mmmail, which is now being totally redesigned from
-scratch (for v2), mmftpd, Xisop (a portable non-SMP multitasking preemptive
-microkernel similar to AmigaOS), an arbitrary math library and C-like
-simplified tokernizer/interpretor language for secure distributed network
-clients, along with their distributed server counterpart. I mostly emphasize
-my projects on security (good tactics as running virtual services as
-non-privileged users, encryption, etc are useful).
-</p><p>
-I also use and test various tunnelling/VPN solutions, am working on a secure
-NFS alternative, and various work-related projects. I try to eventually
-provide easy solutions to common administration nightmares such as sendmail
-administration, localized central data servers and similar tasks. Some work
-has also been done on a state-persistant secure HTTP authentication protocol
-where unique cookies are exchanged between each page under SSL, and their
-origin/expiration verified on the server-side, possibly that an ssl-httpd will
-eventually become available for safe remote administration of mmmail, mmftpd
-and other server daemons I write.
-</p><p>
-I often don't mind to redesign existing systems, re-invent them or be
-inspired by their concepts, when a happy result can be obtained afterwards.
-Other non-computer related interests exist, including swimming, martial
-arts, meditation (often a necessity for relaxation), international foods,
-microbrewered and rare dark, rich beers, especially the stout type.
-Writing also has always been a great passion all my life, from adventure
-novels (unpublished) to technical documentation (some only has been made
-available publically). And music. What a great way to express soul states,
-composing and producing various music types, especially Fusion-Jazz remains
-a never-ending story.
-</p><p>
-Matt
-</p>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: projects.html,v 1.6 2003/06/04 12:17:47 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/site/software.html b/site/software.html
deleted file mode 100644 (file)
index 7781a2a..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html><head>
-<!--   $Id: software.html,v 1.15 2003/12/12 15:58:39 mmondor Exp $
-       Copyright (c) 2002-2003 Matthew Mondor,  ALL RIGHTS RESERVED.
--->
-<title>Matthew Mondor's Software Site - Software</title>
-<link rel="shortcut icon" href="/favicon.ico">
-</head>
-
-<!-- Begin -->
-<body bgcolor="#f0f0ff" text="#000000" link="#3535c5" vlink="#700080">
-<table border="0" cellspacing="5" cellpadding="5" width="100%">
-<tbody><tr>
-
-<!-- Left column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Sections</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<p><font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html">Main</a>&nbsp;<br>
-&nbsp;<a href="software.html"><em>Software</em></a>&nbsp;<br>
-&nbsp;<a href="donations.html">Donations</a>&nbsp;<br>
-&nbsp;<a href="contributors.html">Contributors</a>&nbsp;<br>
-&nbsp;<a href="philosophy.html">Philosophy</a>&nbsp;<br>
-&nbsp;<a href="cvs.html">CVS</a>&nbsp;<br>
-&nbsp;<a href="projects.html">Projects</a>&nbsp;<br>
-&nbsp;<a href="mirrors.html">Mirrors</a>&nbsp;<br>
-&nbsp;<a href="mailto:mmondor@gobot.ca">Contact</a>&nbsp;<br>
-</font></td></tr></tbody></table>
-<br><img src="images/sigil.jpg" alt="Image Copyright (c) 2002-2003, Matthew Mondor">
-</td></p>
-
-<!-- Middle column -->
-<td valign="top">
-<center>
-<font face="helvetica, arial" size="5">The Software</font><br>
-</center>
-<font face="helvetica, arial">
-<p>
-This page contains the various official mmsoftware sources. The third-party
-software provided by the contributors can be found in the
-<a href="contributors.html">contributors</a> area. Access to the current
-official mmsoftware sources CVS repository is available (via pserver). Details
-about CVS can be found under the <a href="cvs.html">CVS</a> section. It is
-also possible to obtain the source archives of the old releases for reference
-only, in the software archive: <a href="software/">software/</a>.
-</p><p><center><b>Featured software:</b></center></p><p>
-This software is actively maintained and in constant development. This also
-means that bug reports are taken into consideration as fast as
-possible and new version released accordingly, shortly after bug discovery,
-when a suitable solution has been implemented to solve the issue.
-</p>
-</font>
-<table border="1" bgcolor="#d0d0f0" width="100%">
-<font face="helvetica, arial">
-<tr>
-<th><a href="software/devl/mmftpd-0.0.17.tgz">mmftpd</a></th>
-<td align="center">0.0.17</td>
-<td align="center">Devl</td>
-<td align="center">
-<a href="software/misc/mmftpd-changelog.txt">ChangeLog</a></td>
-<td align="center">
-<a href="software/devl/mmftpd-0.0.17.tgz.md5.txt">MD5</a></td>
-</tr>
-<tr><td align="center" colspan="5">
-Unprivileged virtual users FTP server
-</td></tr>
-<tr><td bgcolor="#c6e0e0" colspan="5"><font face="helvetica, arial" size="-1">
-<p>
-mmftpd was written from scratch from the ground up, and consists of a
-featureful yet very security-aware FTP server. It is released under the
-terms and conditions of the BSD license with advertizing clause to keep
-credits to the author. It ensures to run under a single unprivileged user,
-and provides FTP virtual users, as opposed to traditional UNIX/system ones,
-which each appear jailed in their home directory using extensive path sanity
-checking. It optionally also can chroot(2) at program startup for the whole
-service and all users to be setup under a real alternative root jail.
-Runs great on BSD and Linux systems and is fairly small in size. Well
-documented via UNIX manual pages.
-</p><p>
-The server can limit the connection rate from an address and also has
-bandwidth traffic shaping capabilities for both control and data ports,
-on a per-connection and global basis. It also can limit the connections
-on several factors (maximum number of addresses, number of allowed
-connections per address and how many simultaneous connections from the same
-FTP user to accept). Client hostname resolving is optional for speed, and
-is performed using asynchroneous methods when enabled.
-</p><p>
-For each FTP user a number of permission parameters can be customized,
-including the maximum upload and download speed, umask, rights to
-change umask, upload, modify, maximum home directory tree size (even safe
-among multiple simultaneous connections of the same user). Various techniques
-were implemented to prevent common Denial Of Service attempts.
-</p><p>
-Various statistics are reliably maintained using the mmstat facility,
-and the administrator can set the verbosity of wanted events and statistics
-to be output via syslog. Moreover it uses efficient custom I/O buffering
-around filedescriptors for speed. Users are stored in a configuration file
-with their permissions, using native crypt(3) password hashes
-(both MD5 and DES), so that it is possible to create virtual mmftpd users
-from system ones using the same password hashes. The server options are
-configured via a second configuration file.
-</font></td></tr>
-</table><br><table border="1" bgcolor="#d0d0f0" width="100%">
-<th><a href="software/devl/mmmail-0.0.23.tgz">mmmail</a></th>
-<td align="center">0.0.23</td>
-<td align="center">Devl</td>
-<td align="center">
-<a href="software/misc/mmmail-changelog.txt">ChangeLog</a></td>
-<td align="center">
-<a href="software/devl/mmmail-0.0.23.tgz.md5.txt">MD5</a></td>
-</tr>
-<tr><td align="center" colspan="5">
-Unprivileged virtual SMTP+POP3 server suite using MySQL
-</td></tr>
-<tr><td bgcolor="#c6e0e0" colspan="5"><font face="helvetica, arial" size="-1">
-<p>
-mmmail was written from scratch from the ground up, and consists of a
-suite of SMTP and POP3 servers which can fully run under a unprivileged
-user. It is released under the terms and conditions of the BSD license with
-advertizing clause to keep credits to the author. It provides virtual mail
-users, contrary to traditional UNIX/system ones. It optionally supports
-chroot(2) at program startup to enclose itself into a jail. It runs great
-on both BSD and Linux systems and is fairly small in size. Well documented
-via UNIX manual pages.
-</p><p>
-The servers can limit their clients connection rate on a per-address basis,
-and also support bandwidth traffic shaping capabilities in both directions
-(connection-specific and global ones). It also can limit the connections
-on several factors (maximum number of addresses, number of allowed
-connections per address and how many simultaneous connections from the same
-POP3 user to accept). Client hostname resolving is optional for speed, and
-is performed using asynchroneous methods when enabled. Moreover, the
-administrator may decide weither to check for HELO and/or MAIL MX DNS
-records before accepting SMTP mail from a client. Use of HELO may be
-disabled or enforced. Various techniques were implemented to prevent common
-Denial Of Service attempts.
-</p><p>
-For each mail user/password pair can exist several email addresses at several
-virtual hosts, and aliasing is supported to map unexisting addresses to others,
-even optionally using wildcard pattern matching. The administrator can also
-set the address and/or hostname masks through which mail with empty FROM
-address is sent. Each mailbox can be set customizeable quotas (mailbox total
-size and total number of messages). All storage (users, mailboxes, and mail
-itself) uses MySQL, which permits a global database server to be used, even
-remotely. A persistant connection is established and maintained with the
-server by each daemon, and re-established if ever necessary.
-</p><p>
-Various statistics are reliably maintained using the mmstat facility,
-and the administrator can set the verbosity of wanted events and statistics
-to be output via syslog. Moreover it uses efficient custom I/O buffering
-around filedescriptors for speed. Each daemon is configured through it's
-own configuration file. User password hashes are stored in native crypt(3)
-format (both MD5 and DES work) so it is possible to translate system users
-to mmmail virtual ones keeping the same hash.
-Also, mmpop3d supports unstandard POP3 PAGE command (better than TOP) which
-was especially implemented for human POP3 clients.
-</p><p>
-Unfortunately, support for relaying will only be added for mmmail2, a future
-re-implementation of mmmail which also should support multiple authentication
-and storage methods, as well as many other features including IMAP.
-If you are interested in knowing more about mmmail2 ongoing engineering
-(diagrams and documentation), and to make suggestions, you can download this
-<a href="software/devl/mmmail-design.pdf">mmmail-design.pdf</a> document.
-</td></tr>
-</table><br>
-<table border="1" bgcolor="#d0d0f0" width="100%">
-<th><a href="software/devl/mmstatd-0.0.8.tgz">mmstatd</a></th>
-<td align="center">0.0.8</td>
-<td align="center">Devl</td>
-<td align="center">
-<a href="software/misc/mmstatd-changelog.txt">ChangeLog</a></td>
-<td align="center">
-<a href="software/devl/mmstatd-0.0.8.tgz.md5.txt">MD5</a></td>
-</tr>
-<tr><td align="center" colspan="5">
-Statistics maintenance server daemon and client library
-</td></tr>
-<tr><td bgcolor="#c6e0e0" colspan="5"><font face="helvetica, arial" size="-1">
-<p>
-mmstatd was originally written for mmftpd and mmmail to asynchroneously
-maintain statistical counters in an efficient manner. I however also
-release it separately as it is used by some other people in their projects.
-These include an IRC network services system which although using db4 for
-most data storage uses mmstat(3) library for various statistics counters.
-</p><p>
-It does not require any additional libraries, and provides a simple API
-for applications to either update counters or query statistics. The update
-requests are done using an AF_LOCAL/UNIX datagram to the mmstatd service's
-log socket, similarly to the way syslog(3) works. Statistics are queried
-via an AF_LOCAL/UNIX stream on another mmstatd socket. Permissions for access
-to both sockets can be different.
-</p><p>
-The service consists of a librarian and logger. The logger accumulates
-requests filling a recovery log, while the librarian processes those logs
-asynchroneously and syncs the disk database with them from time to time.
-In case of a crash, the recovery logs which weren't synchronized yet to
-disk are used to recover from the crash. Provided with it is a utility
-to query and update statistics from the shell as well.
-</td></tr>
-</table><br><p><center><b>Unmaintained software:</b></center></p>
-<p>
-This section contains software which works but which I am no longer
-maintaining. These are Linux-specific and are getting old. I keep them
-here because a fair amount of people find these handy and download
-them.
-</p>
-<table border="1" bgcolor="#d0d0f0" width="100%">
-<th><a href="software/stable/mmtcpfwd-0.1.0.tar.gz">mmtcpfwd</a></th>
-<td align="center">0.1.0</td>
-<td align="center">Stable</td>
-<td align="center">
-<a href="software/misc/mmtcpfwd-changelog.txt">ChangeLog</a></td>
-<td align="center">
-<a href="software/stable/mmtcpfwd-0.1.0.tar.gz.md5.txt">MD5</a></td>
-</tr>
-<tr><td align="center" colspan="5">
-Port forwarder, MASQ fake identd and FTP proxy for Linux
-</td></tr>
-<tr><td bgcolor="#c6e0e0" colspan="5"><font face="helvetica, arial" size="-1">
-<p>
-Written from scratch, consists of a superserver daemon made of two parts,
-one process running as the superuser (to perform tasks like modifying
-firewall rules) and the other running as an unprivileged user performing
-all the work. This privilege separation system is quite effective for
-a secure setup. Linux 2.2 specific (can work with 2.4+ but without the
-transparent proxying support). Released under the terms of the GPL
-(GNU Public License).
-</p><p>
-mmtcpfwd provides transparent TCP/IP connection proxying from a MASQ enabled
-gateway to other machines, including FTP connections, via a special userspace
-passive FTP connections proxy supporting PASV, LPSV and EPSV, and masking the
-actual FTP server LAN address by supplying the gateway's address instead.
-Supports SMP where hardware permits. Uses a main configuration file to
-configure all it's parameters. Also provides an optional random UNIX-ident
-protocol daemon, allowing masqueraded connections behind the gateway to
-use services requireing identd to run.
-</p><p>
-For each forwarded port, a non-privileged process is setup to listen to
-and forward multiple connections to their configured destination. This
-destination can consist of a remote or local host, and it is possible to
-make it resolve IP address by hostname or to specify absolute IP addresses
-for speed.
-</p><p>
-Several interesting techniques are implemented to counter Denial of Service
-attacks: Total number of forwarded simultanious connections per port can be
-set, as well as per address. Also permits to deny automatically an IP address
-overflowing connections with a threshold, in which case each active connection
-from that address are cleanly closed before applying the firewall deny rule,
-executing a command of our choice. Allows to fake services like portsentry to
-immediately DENY an IP address that connects, sending a configurable message
-before closing and applying the DENY rule. Can also automatically undeny IP
-addresses of offendants after a certain amount of minutes, or indefinitely.
-As many IP addresses to never deny as we want can be specified.
-</p><p>
-Uses syslog logging, to keep log of connections/bytes transfered, elapsed
-time, etc... Hostnames can be resolved or not, on a per-port basis.
-Supports kernel's IP Transparent Proxying support to fake client's IP address
-when forwarding. Aimed towards security as much as possible.
-Fairly small, executable around 30k only.
-</p>
-</font></td></tr>
-</table><br><table border="1" bgcolor="#d0d0f0" width="100%">
-<th><a href="software/devl/ginseng-ftpd-1.6.tar.gz">ginseng-ftpd</a></th>
-<td align="center">1.6</td>
-<td align="center">Devl</td>
-<td align="center">
-<a href="software/misc/ginseng-ftpd-changelog.txt">ChangeLog</a></td>
-<td align="center">
-<a href="software/devl/ginseng-ftpd-1.6.tar.gz.md5.txt">MD5</a></td>
-</tr>
-<tr><td align="center" colspan="5">
-Security-enhanced Linux ftpd based on bsd-ftpd (NetBSD)
-</td></tr>
-<tr><td bgcolor="#c6e0e0" colspan="5"><font face="helvetica, arial" size="-1">
-<p>
-This server originally consisted of a port of BSD-FTPd to Linux, and various
-custom features were added which I personally needed at the time. Since I
-wrote mmftpd which much better suits my needs I no longer maintain
-ginseng-ftpd. It's still available though, for people who need to run FTP
-services with real users (where security is generally not that much of a
-concern). An FTP server allowing use of standard UNIX system users obviously
-required to run as the superuser. Run mmftpd if you need better security.
-Was released under the terms of the BSD license.
-</p><p>
-I here describe a list of the various changes that I made on the original
-BSD-FTPd code: The popular recently discovered single-byte vulnerability of
-bsd-ftpd was fixed, some better sanity checking around seteuid(),
-setegid() and fork() was added. Was fixed against the recursive LIST/NLST
-problems which alot of FTP servers are vulnerable to, including BSD-FTPd
-at the time. Now only requires a single configuration file (/etc/ftpusers)
-for all account options, and users MUST be present in it to be allowed
-FTP access (contrary to traditional behavior). The configuration file now
-uses one user per line, and one column per user configurable option.
-</p><p>
-Support for read-only accounts, umask specification and homedir total size
-limits on a per/user basis and number of connections per user was added,
-note that the tree size quotas are only safe if only one simultaneous logins
-of that user are allowed. Shared memory and semaphores would have been
-required otherwise which would have strongly impacted performance.
-This is not the case for mmftpd where threads are used and quotas are
-safe no matter what. The server was modified to only accept to be launched
-by the superuser.
-</p><p>
-The following command switches/parameters were added when starting the
-daemon: -q to not display ftpd type/version to clients, -n to not resolve
-hostnames for speed, -x to allow masquerading actual LAN IP address to
-0.0.0.0 for passive replies (not that not all clients will work, I
-recommend using mmtcpfwd passive FTP proxying to masquerade those to
-the actual gateway's IP address instead, where all clients will work.
-Finally, -q was added to specify which port to listen to.
-</p>
-</font></td></tr>
-</table>
-</font>
-</td>
-
-<!-- Right column -->
-<td valign="top" bgcolor="#d0d0f0">
-<font face="helvetica, arial" color="#000066"><b>Languages</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="index.html"><em>English</em></a>&nbsp;<br>
-&nbsp;<a href="index_fr.html">French</a>&nbsp;<br>
-</font></td></tr></tbody></table></p>
-<p><font face="helvetica, arial" color="#000066"><b>Mirrors</b></font><br>
-<table border="0" cellspacing="4" cellpadding="2"><tbody><tr><td>
-<font face="helvetica, arial" size="-1">
-&nbsp;<a href="http://mmondor.dynup.net/index.html">Canada</a>&nbsp;<br>
-&nbsp;<a href="http://gobot.accela.net/index.html"><nobr>United-States</nobr></a>&nbsp;<br>
-&nbsp;<a href="http://mmondor.oostendorp-ict.nl/index.html">Holland</a>&nbsp;<br
->
-</font></td></tr></tbody></table></td></p>
-
-<!-- End -->
-</tr><tr><td valign="bottom" align="left" colspan="3">
-<font face="helvetica, arial" size="-2">
-$Id: software.html,v 1.15 2003/12/12 15:58:39 mmondor Exp $<br>
-This site Copyright (c) 2002-2003, Matthew Mondor, ALL RIGHTS RESERVED.
-</font></td></tr></tbody></table>
-</body></html>
diff --git a/tests/entropy/README b/tests/entropy/README
deleted file mode 100644 (file)
index 96844b5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Attempts to generate enough rnd(4) entropy on NetBSD systems using
-CGD for encrypted swap.  Using it on a laptop.
-
-This implentation uses pseudo-random reads on a hard disk device
-in order to hopefully cause the rnd(4) device (which is among other
-devices fed by the wd* and sd* devices) to be fed entropy caused
-by unstability features of the heads.
-
-The program can be launched before starting the encrypted builds,
-then mounting the wanted CGD devices can be made, which shouldn't
-cause a lockup anymore while cgdconfig(8) creates random the
-cryptography keys with /dev/random.  The program can then be killed.
diff --git a/tests/entropy/entropy_disk.c b/tests/entropy/entropy_disk.c
deleted file mode 100644 (file)
index fc5f154..0000000
+++ /dev/null
@@ -1,629 +0,0 @@
-/* $Id: entropy_disk.c,v 1.6 2007/02/15 21:17:31 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006 Pulsar-Zone, Reg.
- * All rights reserved.
- *
- * Written by Matthew Mondor for Pulsar-Zone, Reg.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed for the NetBSD Project by
- *      Pulsar-Zone, Reg.
- * 4. The name of Pulsar-Zone, Reg. may not be used to endorse
- *    or promote products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY PULSAR-ZONE, REG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL PULSAR-ZONE, REG
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Strategy:
- *
- * 1) First obtain wd* or sd* devices using sysctl(3) which could be used to
- *    produce entropy.  Error and exit if no such devices can be used.
- * 2) Report our PID and detach, allowing SIGTERM to kill us.
- * 3) In an endless loop, read various arbitrary blocks of random lenghts and
- *    at random positions from random disks.  We take care to toggle the
- *    reading direction often enough to give the heads an opportunity to seek
- *    in both directions.
- * 4) Upon receiving a SIGTERM signal, close the disk devices and exit.
- *
- * To obtain rather decent random values, we use the 4.2BSD random(3) PRNG
- * but seed it using /dev/urandom.  This prevents sucking up too much entropy
- * from rnd(4), which we're designed to fill rather than waste, afterall.
- * We periodically reseed the PRNG with /dev/urandom during the main loop as
- * well.
- *
- * XXX Consider using arc4random(3) instead.  However, possible problems could
- * occur using it:  it could void rnd(4) entropy, especially that at least
- * 1024 bytes of the arcfour keystream should be discarded to be random
- * enough.
- *
- * XXX Possibly add an option to tell the daemon to automatially exit after a
- * certain number of seconds or minutes elapsed.  We would use setitimer(2)
- * to receive a SIGALRM, acting the same as for SIGTERM upon its reception.
- *
- * XXX Make lseek(2)/read(2) errors silent via compile time option to not
- * disclose any information in case of disk problems for a final version of
- * this program.
- */
-
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/queue.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-/*
- * Minimum block size to read (could be disk dependent but it doesn't matter
- * much for this task.
- */
-#define BLOCK_SIZE     16384
-/*
- * Maximum number of BLOCK_SIZE blocks to read in a single read(2)
- */
-#define BLOCK_MULTIPLE 16
-/*
- * Minimum and maximum number of reads to perform in a single direction before
- * switching direction.  If these are too low the disk head thrashing could be
- * excessive.
- */
-#define DIRECTION_MIN  256
-#define DIRECTION_MAX  4096
-/*
- * Minimum and maximum reseeding of PRNG from urandom(4) frequency (in reads).
- * If we set these this too low, the entropy we're trying to accumulate in
- * rnd(4) is sucked out as we create it, causing us to loop indefinitely for
- * nothing.
- */
-#define RESEED_MIN     32
-#define RESEED_MAX     256
-
-enum direction {
-       DIR_FORWARD = 0,
-       DIR_BACKWARDS = 1
-};
-
-typedef struct drive_entry {
-       SLIST_ENTRY(drive_entry) chain;
-       char            *name;
-       off_t           max, pos;
-       int             fd;
-       int             dir, dircnt;
-} disk_t;
-
-SLIST_HEAD(slisthead, drive_entry);
-
-#define BALIGN_CEIL(v, s)      ((((size_t)(v)) + (s) - 1) / (s) * (s))
-
-
-
-int                    main(int, char **);
-
-static int             prng_init(void);
-static void            prng_reseed(void);
-static void            prng_close(void);
-static void            signal_handler(int);
-static int             detach(const char *);
-static void            disk_open(const char *);
-static int             disks_open(void);
-static void            disks_close(void);
-static void            *buffer_alloc(size_t);
-static void            buffer_free(void *, size_t);
-
-
-
-static char            *pidfile = "/var/run/entropy_disk.pid";
-static int             maxdisks = 4;
-
-static struct slisthead        disks_list = SLIST_HEAD_INITIALIZER(drive_entry);
-static int             ndisks = 0;
-static disk_t          **disks_array = NULL;
-
-static int             urandom = -1;
-static int             reseed = 0;
-
-static size_t          pagesize = 0;
-
-static int             run = 1;
-
-
-
-int
-main(int argc, char **argv)
-{
-       char    c;
-       void    *readbuf;
-       int     ret = EXIT_FAILURE;
-
-       setprogname(argv[0]);
-
-       /* Parse commad line arguments */
-       while ((c = getopt(argc, argv, "p:n:?")) != -1) {
-               switch (c) {
-               case 'p':
-                       pidfile = optarg;
-                       break;
-               case 'n':
-                       maxdisks = strtol(optarg, NULL, 10);
-                       if (maxdisks < 1 || maxdisks > 100) {
-                               (void) fprintf(stderr,
-                                   "<maxdisks> must be between 1 and 100\n");
-                               return EXIT_FAILURE;
-                       }
-                       break;
-               case '?':
-                       /* FALLTHROUGH */
-               default:
-                       (void) fprintf(stderr,
-                           "Usage: %s [-p <pidfile>] [-n <maxdisks>]\n",
-                           getprogname());
-                       return EXIT_FAILURE;
-               }
-               argc -= optind;
-               argv += optind;
-       }
-
-       /*
-        * Initialization
-        */
-       if (prng_init() != 0)
-               return EXIT_FAILURE;
-
-       if (disks_open() != 0)
-               return EXIT_FAILURE;
-
-       if ((readbuf = buffer_alloc(BLOCK_SIZE * BLOCK_MULTIPLE)) == NULL)
-               goto end;
-       if (detach(pidfile) != 0)
-               goto end;
-
-       /* Main loop */
-       while (run) {
-               disk_t          *e;
-               int             blocks;
-               unsigned long   diff;
-
-               /* Choose a disk */
-               e = disks_array[random() % ndisks];
-
-               /* Choose a block size */
-               blocks = random() % BLOCK_MULTIPLE;
-
-               /*
-                * Choose a position relative to a previous one and doesn't
-                * exceed e->max (which already accounts for the block size
-                * and is already BLOCK_SIZE aligned).  Our new position must
-                * also be BLOCK_SIZE aligned.
-                */
-               diff = BALIGN_CEIL(random() % (e->max / DIRECTION_MIN),
-                   BLOCK_SIZE);
-               if (e->dir == DIR_BACKWARDS) {
-                       if ((e->pos -= diff) < 0)
-                               e->dir = DIR_FORWARD;
-               }
-               if (e->dir == DIR_FORWARD)
-                       e->pos = BALIGN_CEIL((e->pos + diff) % (e->max + 1),
-                           BLOCK_SIZE);
-               if (--e->dircnt < 0) {
-                       e->dir = (e->dir == DIR_FORWARD ?
-                           DIR_BACKWARDS : DIR_FORWARD);
-                       e->dircnt = DIRECTION_MIN +
-                           (random() % (DIRECTION_MAX - DIRECTION_MIN));
-               }
-
-               /* Seek and read block(s) */
-               if (lseek(e->fd, e->pos, SEEK_SET) != -1) {
-                       if (read(e->fd, readbuf, blocks * BLOCK_SIZE) !=
-                           blocks * BLOCK_SIZE)
-                               (void) fprintf(stderr,
-                                   "read(%s, %llu, %u): %s\n",
-                                   e->name, e->pos, blocks * BLOCK_SIZE,
-                                   strerror(errno));
-               } else
-                       (void) fprintf(stderr,
-                           "lseek(%s, %llu): %s\n",
-                           e->name, e->pos, strerror(errno));
-
-               /* Sleep for a slight random delay */
-               (void) usleep(random() % 1000);
-
-               /* Reseed PRNG out of /dev/urandom periodically */
-               prng_reseed();
-       }
-
-       ret = EXIT_SUCCESS;
-       /* FALLTHROUGH */
-
-end:
-       /* Cleanup */
-       if (readbuf != NULL)
-               buffer_free(readbuf, BLOCK_SIZE * BLOCK_MULTIPLE);
-       (void) unlink(pidfile);
-       disks_close();
-       prng_close();
-
-       return ret;
-}
-
-/*
- * Seed 4.2BSD random(3) using rnd(4)'s /dev/urandom
- */
-static int
-prng_init(void)
-{
-       unsigned long   seed;
-
-       if ((urandom = open("/dev/urandom", O_RDONLY)) == -1) {
-               (void) fprintf(stderr,
-                   "open(/dev/urandom): %s\n", strerror(errno));
-               goto err;
-       }
-       if (read(urandom, &seed, sizeof(seed)) != sizeof(seed)) {
-               (void) fprintf(stderr,
-                   "read(/dev/urandom): %s\n", strerror(errno));
-               goto err;
-       }
-
-       srandom(seed);
-       reseed = RESEED_MIN + (random() % (RESEED_MAX - RESEED_MIN));
-
-       return 0;
-
-err:
-       if (urandom != -1) {
-               (void) close(urandom);
-               urandom = -1;
-       }
-
-       return -1;
-}
-
-static void
-prng_reseed(void)
-{
-       unsigned long   seed;
-
-       if (--reseed < 1) {
-               if (read(urandom, &seed, sizeof(seed)) != sizeof(seed)) {
-                       (void) fprintf(stderr,
-                           "read(/dev/urandom): %s\n", strerror(errno));
-               }
-               srandom(seed);
-               reseed = RESEED_MIN + (random() % (RESEED_MAX - RESEED_MIN));
-       }
-}
-
-static void
-prng_close(void)
-{
-
-       if (urandom != -1) {
-               (void) close(urandom);
-               urandom = -1;
-       }
-}
-
-/*
- * Called upon reception of SIGTERM
- */
-static void
-signal_handler(int sig)
-{
-
-       switch (sig) {
-       case SIGTERM:   /* FALLTHROUGH */
-       default:
-               run = 0;
-       }
-}
-
-/*
- * Become a background daemon and write our PID file.
- * Returns 0 on success or -1 on error.
- */
-static int
-detach(const char *pidfile)
-{
-       pid_t                   pid;
-       int                     fd;
-       struct sigaction        act;
-
-       if ((pid = fork()) == -1)
-               return -1;
-       if (pid != 0)
-               exit(EXIT_SUCCESS);
-
-       /* Create PID file */
-       if ((fd = open(pidfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) != -1) {
-               char    str[16];
-
-               (void) snprintf(str, 15, "%d\n", getpid());
-               if (write(fd, str, strlen(str)) == -1 || close(fd) == -1) {
-                       (void) fprintf(stderr,
-                           "Error writing PID file [%s]: %s\n",
-                           pidfile, strerror(errno));
-                       return -1;
-               }
-       } else {
-               (void) fprintf(stderr,
-                   "Error creating PID file [%s]: %s\n",
-                   pidfile, strerror(errno));
-               return -1;
-       }
-
-       /* Be paranoid, redirect our stdio file descriptors to null(4) */
-       (void) setsid();
-       (void) chdir("/");
-       if ((fd = open("/dev/null", O_RDWR)) != -1) {
-               (void) dup2(fd, STDIN_FILENO);
-               (void) dup2(fd, STDOUT_FILENO);
-               /* Keep stderr */
-               if (fd > STDERR_FILENO)
-                       (void) close(fd);
-       }
-
-       /* Set our SIGTERM handler and ignore some signals */
-       act.sa_handler = signal_handler;
-       act.sa_flags = 0;
-       (void) sigemptyset(&act.sa_mask);
-       (void) sigaction(SIGTERM, &act, NULL);
-       act.sa_handler = SIG_IGN;
-       (void) sigaction(SIGTTOU, &act, NULL);
-       (void) sigaction(SIGTTIN, &act, NULL);
-       (void) sigaction(SIGTSTP, &act, NULL);
-
-       return 0;
-}
-
-/*
- * Attempts to open specified disk device and on success adds a new disk_t
- * entry to the disks_list.  Logs any errors to stderr.
- */
-static void
-disk_open(const char *dname)
-{
-       disk_t  *e;
-       char    devname[16];
-
-       if ((e = malloc(sizeof(disk_t))) == NULL) {
-               (void) fprintf(stderr,
-                   "malloc(%d): %s\n", sizeof(disk_t), strerror(errno));
-               goto err;
-       }
-       if ((e->name = strdup(dname)) == NULL) {
-               (void) fprintf(stderr,
-                   "strdup(%d): %s\n", strlen(dname), strerror(errno));
-               goto err;
-       }
-
-       (void) snprintf(devname, 16, "/dev/r%sd", dname);
-       if ((e->fd = open(devname, O_RDONLY)) == -1) {
-               (void) fprintf(stderr,
-                   "open(%s): %s\n", devname, strerror(errno));
-               goto err;
-       }
-
-       /*
-        * Although we could use an ioctl(2) to read the label of the device,
-        * using lseek(2) is simpler.  If it generates head movement, it's all
-        * for the better.
-        */
-       if (lseek(e->fd, 0, SEEK_END) == -1) {
-               (void) fprintf(stderr,
-                   "lseek(%s): %s\n", devname, strerror(errno));
-               goto err;
-       }
-       if ((e->max = lseek(e->fd, 0, SEEK_SET)) == -1) {
-               (void) fprintf(stderr,
-                   "lseek(%s): %s\n", devname, strerror(errno));
-               goto err;
-       }
-       /*
-        * Substract so that any position is valid for reading up to
-        * BLOCK_SIZE * BLOCK_MULTIPLE bytes.  We also ensure that size
-        * is always a multiple of BLOCK_SIZE.
-        */
-       e->max = BALIGN_CEIL(e->max - (BLOCK_SIZE * BLOCK_MULTIPLE),
-           BLOCK_SIZE);
-
-       /* Set a random but valid start position, BLOCK_SIZE aligned. */
-       e->pos = BALIGN_CEIL(((off_t)random() * (off_t)random()) %
-           (e->max + 1), BLOCK_SIZE);
-
-       /* And a random direction/count */
-       e->dir = random() % 2;
-       e->dircnt = DIRECTION_MIN +
-           (random() % (DIRECTION_MAX - DIRECTION_MIN));
-
-       SLIST_INSERT_HEAD(&disks_list, e, chain);
-       ndisks++;
-       return;
-
-err:
-       if (e != NULL) {
-               if (e->name != NULL)
-                       free(e->name);
-               if (e->fd != -1)
-                       (void) close(e->fd);
-               free(e);
-       }
-}
-
-/*
- * Queries sysctl(3) for wd* and sd* drive names and opens the devices.
- * Returns 0 on success or -1 on failure.
- */
-static int
-disks_open(void)
-{
-       int     mib[] = { CTL_HW, HW_DISKNAMES };
-       char    buf[1024], *cptr, *sptr;
-       size_t  size = sizeof(buf);
-
-       /* Query local disks */
-       if (sysctl(mib, 2, buf, &size, NULL, 0) != 0) {
-               (void) fprintf(stderr,
-                   "Error querying sysctl(3) for disk names: %s\n",
-                   strerror(errno));
-               goto err;
-       }
-
-       /* Open for each sd(4) or wd(4) disk reported, up to maxdisks */
-       /* XXX We actually could use strsep(3) easily here as well */
-       for (cptr = buf, ndisks = 0; ndisks < maxdisks; ) {
-               for (; *cptr != '\0' && *cptr == ' '; cptr++) ;
-               if (*cptr == '\0')
-                       break;
-               sptr = cptr;
-               for (; *cptr != '\0' && *cptr != ' '; cptr++) ;
-               if (*cptr == '\0')
-                       break;
-               *cptr++ = '\0';
-               if ((sptr[0] == 's' || sptr[0] == 'w') &&
-                   sptr[1] == 'd')
-                       disk_open(sptr);
-       }
-
-       if (ndisks == 0) {
-               (void) fprintf(stderr,
-                   "No sd(4) or wd(4) disks to generate entropy from\n");
-               goto err;
-       }
-
-       /* Initialize fast index array */
-       if ((disks_array = malloc(sizeof(disk_t *) * ndisks)) == NULL) {
-               (void) fprintf(stderr,
-                   "malloc(%d): %s\n", sizeof(disk_t *) * ndisks,
-                   strerror(errno));
-               goto err;
-       }
-       {
-               int     i = 0;
-               disk_t  *e;
-
-               SLIST_FOREACH(e, &disks_list, chain)
-                       disks_array[i++] = e;
-       }
-
-       return 0;
-
-err:
-       disks_close();
-
-       return -1;
-}
-
-/*
- * Closes any open drive devices if any.
- */
-static void
-disks_close(void)
-{
-       disk_t  *e;
-
-       if (disks_array != NULL)
-               free(disks_array);
-
-       while (!SLIST_EMPTY(&disks_list)) {
-               e = SLIST_FIRST(&disks_list);
-               SLIST_REMOVE_HEAD(&disks_list, chain);
-               if (e->fd != -1)
-                       (void) close(e->fd);
-               if (e->name != NULL)
-                       free(e->name);
-               free(e);
-       }
-
-       ndisks = 0;
-}
-
-/*
- * Allocate a wired memory buffer.
- */
-static void *
-buffer_alloc(size_t size)
-{
-       void    *buf = NULL;
-
-       if (pagesize == 0) {
-               if ((pagesize = (size_t)sysconf(_SC_PAGESIZE)) == -1) {
-                       perror("sysconf(_SC_PAGESIZE)");
-                       goto err;
-               }
-       }
-
-       size = (size_t)BALIGN_CEIL(size, pagesize);
-
-       if ((buf = mmap(NULL, size, PROT_WRITE, MAP_ANON, -1, 0)) ==
-           MAP_FAILED) {
-               (void) fprintf(stderr,
-                   "mmap(%d): %s\n", size, strerror(errno));
-               buf = NULL;
-               goto err;
-       }
-       if (mlock(buf, size) == -1) {
-               perror("mlock()");
-               goto err;
-       }
-       if (madvise(buf, size, MADV_WILLNEED) == -1) {
-               perror("madvise()");
-               goto err;
-       }
-
-       return buf;
-
-err:
-       if (buf != NULL) {
-               (void) munlock(buf, size);
-               (void) munmap(buf, size);
-       }
-
-       return NULL;
-}
-
-/*
- * Free a previously allocated wired buffer.
- */
-static void
-buffer_free(void *buf, size_t size)
-{
-
-       assert(pagesize != 0 && buf != NULL);
-
-       size = (size_t)BALIGN_CEIL(size, pagesize);
-
-       (void) memset(buf, 0, size);
-       (void) munlock(buf, size);
-       (void) munmap(buf, size);
-}
diff --git a/tests/js-test/README b/tests/js-test/README
deleted file mode 100644 (file)
index 5922bc8..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-$Id: README,v 1.3 2006/07/22 04:47:43 mmondor Exp $
-
-Note that this was a test tree only.  The current code which is in use
-can be found under /cvsroot/mmondor/mmsoftware/js/
-
-Thanks,
-Matt
diff --git a/tests/js-test/js/copy.js b/tests/js-test/js/copy.js
deleted file mode 100644 (file)
index 49dcc82..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $Id: copy.js,v 1.2 2005/07/01 13:11:08 mmondor Exp $ */
-
-/*
- * Test our read() and write() methods, mapping to unix read(2) and write(2).
- * Seems to be working great so far.
- */
-
-src = '/tmp/src.bin'
-dst = '/tmp/dst.bin'
-
-err = new FD();
-err.set(FD.STDERR_FILENO);
-
-srcfd = new FD();
-dstfd = new FD();
-
-try {
-       srcfd.open(src, FD.O_RDONLY);
-       dstfd.open(dst, FD.O_WRONLY | FD.O_CREAT);
-
-       var data;
-
-       while (data = srcfd.read(16384)) {
-               if (data.length == 0)
-                       break;
-               err.put('Copied ' + data.length + " bytes block\n");
-               dstfd.write(data);
-       }
-
-       srcfd.close();
-       dstfd.fdatasync();
-       dstfd.close();
-} catch (x) {
-       err.put(x + "\n");
-}
-
-err.close();
diff --git a/tests/js-test/js/fd.js b/tests/js-test/js/fd.js
deleted file mode 100644 (file)
index 8e8f998..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $Id: fd.js,v 1.5 2005/02/10 10:34:25 mmondor Exp $ */
-
-var out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-try {
-
-       var fd = new FD();
-
-       {
-               var size;
-
-               fd.open("/tmp/test.txt", FD.O_WRONLY | FD.O_CREAT);
-               size = fd.put("Yo!\n");
-               out.put('Wrote bytes=' + size + ' to file="' + fd.path +
-                   '", fd=' + fd.fd + ', created with mode=' + fd.mode +
-                   "\n");
-               fd.close();
-       }
-
-       {
-               var buf;
-
-               fd.open("/tmp/test.txt", FD.O_RDONLY);
-               while (buf = fd.get())
-                       out.put(buf);
-               fd.close();
-       }
-
-} catch (x) {
-       out.put(x + "\n");
-}
-
-out.put("done\n");
-out.close();
diff --git a/tests/js-test/js/game/objects.js b/tests/js-test/js/game/objects.js
deleted file mode 100644 (file)
index 96fdfe7..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/* $Id: objects.js,v 1.7 2005/11/25 07:38:35 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Primarily written in JavaScript for easy and quick prototyping/testing.
- * May eventually be written in C afterwards if need be, but the game might
- * actually be implemented in JavaScript too depending on future decisions.
- */
-
-/*
- * Simple but rather realistic implementation of items and containers.
- * We observe containers maximum allowed volume and weight, container neck
- * size, as well as expandable containers, such as cloth bags which can expand
- * to eventually fill their parent container too.  We allow nestled
- * containers.  We also add the concept of arbitrary marks which a user might
- * add to objects to differenciate them.  Containers can be open or closed,
- * and obviously need to be open for items to be added/removed from them.
- * We flag containers as such to accept either only solids or liquids, or
- * both.  We could consider flowing sand or salt as a liquid in this case.
- *
- * XXX
- * - For liquids, we might need to provide a special object or flag for them
- *   to be able to have a volume/weight ratio, so that we could perform
- *   actions easily such as fill bottles/bags, etc.
- * - The code dealing with the container parents, weights and expanding volume
- *   containers needs to throughly be tested, both for success and failing
- *   cases of all kinds.
- * - XXX FIXME XXX
- *   When removing items from a container, the container's weight becomes 0,
- *   as well as its volume if it is expandable.
- */
-
-
-
-/*
- * Describes a game item or object.
- */
-
-/* Used so that every item has a unique index ID */
-var unique             = 0;
-
-/* Content types */
-const CT_SOLID         = (1 << 0);
-const CT_LIQUID                = (1 << 1);
-/* And container type flag */
-const CT_EXPAND                = (1 << 2);
-/* If item cannot be taken */
-const CT_FIXED         = (1 << 3);
-
-function Item(name, description, volume, weight, ctype)
-{
-       this.name = name;
-       this.description = description;
-       this.volume = volume;
-       this.weight = weight;
-       this.ctype = ctype;
-
-       this.marks = [];
-
-       this.index = ++unique;
-}
-
-Item.prototype = {
-       isContainer: function()
-       {
-               return false;
-       },
-
-       getVolume: function()
-       {
-               return this.volume;
-       },
-
-       getWeight: function()
-       {
-               return this.weight;
-       },
-
-       mark: function(mark)
-       {
-               this.mark.push(mark);
-       }
-};
-
-
-/*
- * And an object to handle container Items, inheriting the Item object.
- */
-
-const E_OK             = 0;
-const E_TOOLARGE       = "Item too large";
-const E_TOOHEAVY       = "Item too heavy";
-const E_FIXED          = "Item is well fixed and cannot move";
-const E_BADTYPE                = "Item is not of proper type (solid vs liquid)";
-const E_SELF           = "Item could not penetrate itself";
-const E_NONE           = "Item not in container";
-const E_ALREADY                = "Item already in container";
-const E_CLOSED         = "Container is closed";
-
-function ContainerItem(name, description, volume, weight, ctype,
-    con_neck, con_volume_max, con_weight_max, con_ctype)
-{
-       this.base = Item;
-       this.base(name, description, volume, weight, ctype);
-
-       this.con_neck = con_neck;
-       this.con_volume_max = con_volume_max;
-       this.con_weight_max = con_weight_max;
-       this.con_volume_cur = this.con_weight_cur = 0;
-       this.con_ctype = con_ctype;
-
-       this.con_items = {};
-       this.con_items_cnt = 0;
-       this.con_open = false;
-}
-
-ContainerItem.prototype = {
-       isContainer: function()
-       {
-               return true;
-       },
-
-       open: function()
-       {
-               this.con_open = true;
-       },
-
-       close: function()
-       {
-               this.con_open = false;
-       },
-
-       getVolume: function()
-       {
-               /*
-                * Objects which expand, such as bags, need to report proper
-                * volume relating to the volume of the objects they hold.
-                * Objects which do not expand, such as boxes or bottles,
-                * need to always report the same volume.
-                */
-               return ((this.con_ctype & CT_EXPAND) != 0) ?
-                   this.volume + this.con_volume_cur :
-                   this.volume;
-       },
-
-       getWeight: function()
-       {
-               return this.weight + this.con_weight_cur;
-       },
-
-       items: function()
-       {
-               return this.con_items_cnt;
-       },
-
-       add: function(item)
-       {
-               /* We can't accept fixed items */
-               if ((item.ctype & CT_FIXED) != 0)
-                       return E_FIXED;
-
-               /* Can only add items to open container */
-               if (!this.con_open)
-                       return E_CLOSED;
-
-               /* We can't add ourself in :) */
-               if (item.index == this.index)
-                       return E_SELF;
-
-               /* Nor items which are already inside */
-               if (this.con_items[item.index] != undefined)
-                       return E_ALREADY;
-
-               /* We only accept items of proper type */
-               if ((this.con_ctype & item.ctype) == 0)
-                       return E_BADTYPE;
-
-               /* We can only hold objects which are small enough */
-               if (this.con_neck < item.getVolume())
-                       return E_TOOLARGE;
-               if (this.con_volume_cur + item.getVolume() >
-                   this.con_volume_max)
-                       return E_TOOLARGE;
-
-               /* We can only hold objects which are light enough */
-               if (this.con_weight_cur + item.getWeight() >
-                   this.con_weight_max)
-                       return E_TOOHEAVY;
-
-               this.con_volume_cur += item.getVolume();
-               this.con_weight_cur += item.getWeight();
-
-               /*
-                * The weight has to propagate to parent containers.
-                * The volume also has, in the case where containers
-                * are expandable.
-                * We need to observe the maximum allowed volume and weight
-                * of all parent containers as well.
-                * We need to climb through the parents list to do this.
-                * Moreover, we need to actually reverse any changes made
-                * to the parents in case of any volume/weight exceeded.
-                */
-               var err = E_OK;
-               for (var o = this.con_parent; o != undefined;
-                   o = o.con_parent) {
-                       if (o.getWeight() + this.getWeight() >
-                           o.con_weight_max) {
-                               err = E_TOOHEAVY;
-                               break;
-                       }
-                       o.con_weight_cur += this.getWeight();
-                       if ((o.con_ctype & CT_EXPAND) != 0) {
-                               if (o.getVolume() + this.getVolume() >
-                                   o.con_volume_max) {
-                                       err = E_TOOLARGE;
-                                       break;
-                               }
-                               o.con_volume_cur += this.getVolume();
-                       }
-               }
-               if (err != E_OK) {
-                       for (var t = this.con_parent; t != o;
-                           t = t.con_parent) {
-                               t.con_weight -= this.getWeight();
-                               if ((t.con_ctype & CT_EXPAND) != 0)
-                                       t.con_volume_cur -= this.getVolume();
-                       }
-                       if (err == E_TOOLARGE)
-                               o.con_weight_cur -= this.getWeight();
-
-                       this.con_volume_cur -= item.getVolume();
-                       this.con_weight_cur -= item.getWeight();
-
-                       return err;
-               }
-
-               if (item.isContainer())
-                       item.con_parent = this;
-               this.con_items[item.index] = item;
-               this.con_items_cnt++;
-
-               return E_OK;
-       },
-
-       remove: function(item)
-       {
-               /* Can only remove items from open container */
-               if (!this.con_open)
-                       return E_CLOSED;
-
-               /* We can only remove items which are really inside */
-               if (this.con_items[item.index] == undefined)
-                       return E_NONE;
-
-               /*
-                * Climb up our parents containers list to update them
-                */
-               for (var o = this.con_parent; o != undefined;
-                   o = o.con_parent) {
-                       o.con_weight_cur -= this.getWeight();
-                       if ((o.con_ctype & CT_EXPAND) != 0)
-                               o.con_volume_cur -= this.getVolume();
-               }
-
-               if (item.isContainer())
-                       delete item.con_parent;
-               this.con_weight_cur -= item.getWeight();
-               this.con_volume_cur -= item.getVolume();
-               delete this.con_items[item.index];
-               this.con_items_cnt--;
-
-               return E_OK;
-       },
-
-       inventory: function(level)
-       {
-               print(' - ' + level +
-                   ': name=' + this.name +
-                   ' volume=' + this.getVolume() +
-                   ' weight=' + this.getWeight());
-
-               if (!this.con_open)
-                       return 'already_open!';
-
-               level++;
-               for (var i in this.con_items) {
-                       /*
-                       if (this.con_items[i] == undefined)
-                               continue;
-                        */
-                       print(level +
-                           ': name=' + this.con_items[i].name +
-                           ' volume=' + this.con_items[i].getVolume() +
-                           ' weight=' + this.con_items[i].getWeight());
-                       if (this.con_items[i].isContainer())
-                               this.con_items[i].inventory(level);
-               }
-               level--;
-       }
-};
-
-
-
-/*
- * Some testing in order
- */
-
-/* Create an item */
-var i = new Item('a ring', 'the one ring', 5, 5, CT_SOLID);
-
-/* Create a container item */
-var c = new ContainerItem('a bag', 'a soft cloth bag', 5, 5, CT_SOLID,
-    10, 15, 20, CT_SOLID | CT_EXPAND);
-
-/* Create a second container item */
-var c2 = new ContainerItem('another bag', 'another soft cloth bag', 5, 5,
-    CT_SOLID, 10, 15, 20, CT_SOLID | CT_EXPAND);
-
-print();
-c2.inventory(0);
-print();
-
-c.open();
-print(c.add(i));
-c.close();
-c2.open();
-print(c2.add(c));
-c2.close();
-
-c.open();
-c2.open();
-c2.inventory(0);
-c.remove(i);
-c2.remove(c);
-
-print();
-c2.inventory(0);
diff --git a/tests/js-test/js/httpd/httpd.js b/tests/js-test/js/httpd/httpd.js
deleted file mode 100644 (file)
index 0b24dac..0000000
+++ /dev/null
@@ -1,1679 +0,0 @@
-/* $Id: httpd.js,v 1.74 2005/12/17 00:13:12 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Little example showing the versatility of ECMAScript, provided with a
- * custom library for BSD socket support, using SpiderMonkey.
- * This tiny HTTPd allows simultaneous concurrent client connections without
- * using multiple threads or processes.  Must be ran through
- * ../../src/js-server.
- *
- * Configuration options can be found in options.js
- *
- * XXX Possibly that with close var semantics changes or such, we could
- * support Keep-Alive for HTTP/1.1 connections.  This however is not a
- * priority at current time.
- *
- * TODO:
- * - There is a problem if the remote socket closes when we're sending
- *   alot of data, poll(2) apparently doesn't always save us from this
- *   despite checking POLLHUP/POLLERR events.  A SIGPIPE signal is sent
- *   to the process, and we must be able to handle some common signals.
- *   This would also allow an opportunity for applications to register
- *   server cleanup handlers when SIGTERM is received, i.e. to save to
- *   disk in-memory cached data, etc.
- *   We probably should ensure to block the signal when executing the
- *   user function for an occurred signal...
- * - Read http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- *   and see if we meet conformance, adjust as needed.
- * - We might want to check Accept-Language: for multilingual sites...
- * - See what to do for HEAD and PUT
- * - Possibly limit rate of connections per address like I did in
- *   mmftpd/mmsmtpd/mmpop3d/mmspawnd, a requested feature of 3s4i.
- *   If enabling this, it probably should be per-vhost configurable.
- *   I'm not sure HTTP protocol is well suited to this type of limiting,
- *   some testing will be required.
- * - Provide a function to scripts to redirect to another page.
- * - We might want vhost-specific default login page, and provide
- *   an easy means in the server to have non-authenticated users automatically
- *   redirected to that page using server-side magic.  A special session
- *   variable should be used for this, and registered when the user logins.
- * - Similar to the above, but should be special provision for scripts to
- *   easily specify their required access level, which must be met by a
- *   currently logged in user, which is otherwise redirected to an
- *   application-specific page.
- * - Implement logging
- * - It might be nice to implement a minimal database-like facility, where
- *   for performance we could log changes, and only sync to disk once in a
- *   while, discarding obsolete logs...  JSON would be used
- * - Enhance the JS shell to report errors better
- * - We should have support for easy storage and safe export of files,
- *   like I implemented for ascpi.com.  This is useful for instance to
- *   store and post user profile images and related thumbnail, etc.
- */
-
-
-
-/*
- * Server identification
- */
-SERVER_VERSION                 = 'mmondor_js_httpd/0.0.1 (NetBSD)';
-SERVER_CVSID   = '$Id: httpd.js,v 1.74 2005/12/17 00:13:12 mmondor Exp $';
-
-
-
-/*
- * Open standard error FD for diagnostics output
- */
-err = new FD();
-err.set(FD.STDERR_FILENO);
-
-
-
-/*
- * Import needed functionality from external modules, since #include is
- * missing :)
- */
-function file_read(file)
-{
-       var contents = '';
-       var data;
-       var fd;
-
-       try {
-               /*
-                * If we were provided with a filename, rather than a
-                * filedescriptor object, open the filename.  Otherwise,
-                * read from the specified FD.
-                */
-               if (typeof file != 'object') {
-                       fd = new FD();
-                       fd.open(file, FD.O_RDONLY);
-               } else
-                       fd = file;
-       } catch (x) {
-               err.put(x + " at file_read()\n");
-       }
-
-       try {
-               for (;;) {
-                       data = fd.read(65536);
-                       if (data.length == 0)
-                               break;
-                       contents += data;
-               }
-       } catch (x) {
-               err.put(x + " at file_read()\n");
-       }
-
-       fd.close();
-
-       return contents;
-}
-
-try {
-       eval(file_read('options.js'));          /* Configuration */
-} catch (x) {
-       err.put(x + " while reading options file\n");
-       exit();
-}
-eval(file_read('string.js'));          /* startsWith()/endsWith() */
-eval(file_read('ml.js'));              /* MLTag object for HTML generation */
-eval(file_read('root.js'));            /* Root object for virtual chroot(2) */
-
-
-
-/*
- * Client states (enumeration)
- */
-const STATE_TRANSFER_READ      = 1;
-const STATE_TRANSFER_WRITE     = 2;
-
-
-
-/*
- * Quick lookup object from virtual hosts names and aliases to VHost objects
- */
-var vhosts_table = {};
-var default_vhost = undefined;
-
-/*
- * The VHost object
- */
-function VHost(o)
-{
-       /*
-        * A few properties are definitely required
-        */
-       if (o.name == undefined || o.root == undefined)
-               throw ('name and root properties missing from vhost');
-       o.name = o.name.toLowerCase();
-       this.name = o.name;
-
-       if (o.scripts != undefined && o.scripts == true) {
-               this.scripts = true;
-               this.globals = {};
-       }
-
-       /*
-        * Create VHost object
-        */
-       try {
-               this.htdocs_root = new Root(o.root);
-       } catch (x) {
-               throw (x);
-       }
-
-       if (o.charset != undefined)
-               this.charset = o.charset;
-       if (o.session_exp != undefined)
-               this.session_exp = o.session_exp;
-
-       /*
-        * Link object to vhosts table
-        */
-       if (vhosts_table[o.name] != undefined)
-               throw ('Conflicting vhost name: ' + o.name);
-       vhosts_table[o.name] = this;
-
-       if (o.aliases != undefined) {
-               for (i in o.aliases) {
-                       o.aliases[i] = o.aliases[i].toLowerCase();
-                       if (vhosts_table[o.aliases[i]] != undefined)
-                               throw ('Conflicting vhost alias: ' +
-                                   o.aliases[i]);
-                       vhosts_table[o.aliases[i]] = this;
-               }
-       }
-}
-
-
-
-/*
- * The Session object allows to maintain persistent session variables among
- * multiple client queries.  We are using a cookie with the unique session ID
- * to link those queries together into a session.
- */
-
-var o = new FD();
-o.set(FD.STDOUT_FILENO);
-
-var session_randfd = new FD();
-try {
-       session_randfd.open('/dev/urandom', FD.O_RDONLY);
-} catch (x) {
-       err.put(x + " while attempting to open /dev/urandom\n");
-       exit();
-}
-
-var session_charlist = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
-                       'abcdefghijklmnopqrstuvwxyz' +
-                       '0123456789-_';
-
-var sessions_table = {};
-
-/*
- * To be called at regular but spaced intervals,
- * destroys expired session objects.
- */
-function session_gc(time)
-{
-       var i;
-
-       for (i in sessions_table) {
-               if (sessions_table[i].expires <= time)
-                       delete sessions_table[i];
-       }
-}
-
-function Session(time, exp)
-{
-       var rval;
-       var i;
-
-       try {
-               rval = session_randfd.read(options.sess_id_size);
-       } catch (x) {
-               err.put(x + " while attempting to read from /dev/urandom\n");
-       }
-       this.sessid = '';
-       for (i = 0; i < options.sess_id_size; i++)
-               this.sessid +=
-                   session_charlist.charAt(rval.charCodeAt(i) & 0x3f);
-
-       this.variables = {};
-       this.expires = time + exp;
-       sessions_table[this.sessid] = this;
-}
-
-
-
-/*
- * For the mime types database
- */
-
-var mimetypes_table = {};
-
-
-
-/*
- * And our pre-evaluated scripts cache
- */
-var jso_cache = {};
-
-function JSO(path, time, script)
-{
-       this.path = path;
-       this.time = time;
-       this.script = script;
-
-       jso_cache[this.path] = this;
-}
-
-
-
-/*
- * The HTTPReply object allows to cache addHeader() and addContent() requests,
- * and to eventually flush the whole reply to an arbitrary FD afterwards.
- */
-
-/*
- * Constructor
- */
-function HTTPReply(code, desc, type)
-{
-       this.code = code;
-       this.desc = desc;
-       this.headers = [];
-       this.contents = [];
-       this.type = type;
-
-       /*
-        * Insert our standard headers.
-        */
-       this.gmttime = (new Date()).toGMTString();
-       this.headers.push('Date: ' + this.gmttime);
-       this.headers.push('Server: ' + SERVER_VERSION);
-       this.headers.push('Connection: close');
-       this.headers.push('Accept-Ranges: bytes');
-}
-/*
- * HTTPReply prototype object
- */
-HTTPReply.prototype = {
-       setType: function(type)
-       {
-
-               this.type = type;
-       },
-
-       addHeader: function(data)
-       {
-
-               this.headers.push(data);
-       },
-
-       addNoCacheHeaders: function()
-       {
-
-               this.headers.push('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
-               this.headers.push('Last-Modified: ' + this.gmttime);
-               this.headers.push('Cache-Control: no-cache, must-revalidate');
-               this.headers.push('Pragma: no-cache');
-       },
-
-       addContent: function(data)
-       {
-
-               this.contents.push(data);
-       },
-
-       flush: function(fd, size)
-       {
-               var headers = '';
-               var contents = '';
-               var i;
-
-               for (i = 0; i < this.contents.length; i++)
-                       contents += this.contents[i];
-
-               this.headers.push('Content-Length: ' +
-                   (size == null ? contents.length : size));
-               headers += 'HTTP/1.1 ' + this.code + ' ' + this.desc + "\r\n";
-               for (i = 0; i < this.headers.length; i++)
-                       headers += this.headers[i] + "\r\n";
-               if (this.type != null)
-                       headers += 'Content-Type: ' + this.type + "\r\n";
-               headers += "\r\n";
-
-               try {
-                       if (!fd.http_old_get)
-                               fd.bwrite(headers + contents);
-                       else
-                               fd.bwrite(contents);
-               } catch (x) {}
-       }
-}
-
-/*
- * Generates an error page and sends it to specified FD object.
- */
-function http_error(fd, code, desc, ldesc)
-{
-       var res = new HTTPReply(code, desc, 'text/html; charset=' +
-           options.default_charset);
-       res.addNoCacheHeaders();
-
-       res.addContent('<html><head><title>' + code + ' ' + desc +
-           '</title></head><body><h1>' + code + ' ' + desc + '</h1>' +
-           '<p>' + ldesc + '</p><br>');
-
-       res.addContent(fd.httpDebug());
-
-       res.addContent('<br><sub>' + SERVER_VERSION + '<br>' + SERVER_CVSID +
-           '</sub></body></html>');
-
-       res.flush(fd, null);
-       delete res;
-}
-
-
-
-/*
- * Add new methods to the FD prototype object (JavaScript is great like that).
- * We need to add these properties one by one to the prototype object of FD,
- * since we wouldn't want to override its default prototype, just expand it.
- */
-
-/*
- * Handles request query processing, to be assigned to FD.process() while in
- * the request query state.  This then invokes parseRequest() which may
- * either send an HTTP response and/or cause a switch to another state.
- */
-function process_query(time)
-{
-       var len;
-       var done = false;
-       var close = false;
-       var idx;
-       var data;
-
-       /*
-        * If we reach a request of 32768 bytes, stop reading.
-        * If there is no request terminating line within
-        * that buffer, close connection.
-        *
-        * On read error, close connection.
-        *
-        * If we do find request terminating line, parse query
-        * to modify state accordingly, and let the parsing
-        * method decide if we'll close the connection.
-        */
-       len = 32768 - this.request_data.length;
-       if (len < 1) {
-               done = true;
-               close = true;
-       } else {
-               try {
-                       data = this.read(len);
-                       if (data.length == 0)
-                               close = true;
-                       this.request_data += data;
-                       this.updateTimeout(time);
-               } catch (x) {
-                       if (this.errno != Errno.EAGAIN)
-                               close = true;
-               }
-       }
-       if ((idx = this.request_data.indexOf("\r\n\r\n")) != -1)
-               done = true;
-       else if (!this.checked_old &&
-           (idx = this.request_data.indexOf("\r\n")) != -1) {
-               var w;
-
-               this.checked_old = true;
-               if ((w = (this.request_data.substr(0, idx)).split(' ')).
-                   length == 2 && w[0] == 'GET') {
-                       /*
-                        * Old-style HTTP request, we need to respond
-                        * immediately in this case without any headers.
-                        */
-                       done = true;
-               }
-       }
-
-       if (done && !close) {
-               /*
-                * Store remaining of buffer after "\r\n" so that we may
-                * be able to process POST for instance, without needing
-                * to read one char at a time here.
-                * Then call our request parsing function.
-                */
-               idx += 4;
-               this.bread_buffer = this.request_data.substr(idx);
-               this.request_data = this.request_data.substr(0, idx);
-               close = this.parseRequest(time);
-       }
-
-       return close;
-}
-
-function process_post(time)
-{
-       var close = false;
-       var len;
-       var data;
-
-       if (this.post_data.length < this.http_content_length) {
-               len = this.http_content_length - this.post_data.length;
-               if (len > options.readbuf_size)
-                       len = options.readbuf_size;
-               try {
-                       data = this.read(len);
-                       if (data.length == 0)
-                               close = true;
-                       this.post_data += data;
-                       this.updateTimeout(time);
-               } catch (x) {
-                       if (this.errno != Errno.EAGAIN)
-                               close = true;
-               }
-       } else
-               close = this.parsePost(time);
-
-       return close;
-}
-
-/*
- * Handles transfer processing, to be assigned to FD.process() while in the
- * transfer state.
- */
-function process_transfer(time)
-{
-       var close = false;
-
-       /*
-        * STATE_TRANSFER_READ specifies that we're reading to the
-        * buffer from transfer_src, or writing from the buffer
-        * to transfer_dst (STATE_TRANSFER_WRITE).  We can do
-        * both steps one after another if possible.
-        * On EAGAIN errors, simply pass our turn to go back to
-        * polling.  On EOF reading from either end, exit transfer
-        * state after writing to the other and syncing/closing,
-        * and order to close client descriptor.
-        * We take care not to transfer more than this.transfer_size bytes
-        * outbound.
-        * XXX We might also want to observe it for inbound, where it could
-        * be set to the user-provided Content-Length...  for PUT ?
-        */
-       if (this.transfer_state == STATE_TRANSFER_READ) {
-               if (this == this.transfer_src) {
-                       /* Reading from client */
-                       try {
-                               this.transfer_data =
-                                   this.read(options.readbuf_size);
-                               if (this.transfer_data.length == 0)
-                                       this.transfer_eof = true;
-                               this.transfer_state = STATE_TRANSFER_WRITE;
-                               this.updateTimeout(time);
-                       } catch (x) {
-                               if (this.errno != Errno.EAGAIN) {
-                                       close = true;
-                                       try {
-                                               this.transfer_dst.fdatasync();
-                                       } catch (x) {}
-                                       try {
-                                               this.transfer_dst.close();
-                                       } catch (x) {}
-                               }
-                       }
-               } else {
-                       /* Reading from file */
-                       var bufsiz = this.transfer_size;
-                       if (bufsiz > options.readbuf_size)
-                               bufsiz = options.readbuf_size;
-                       try {
-                               if (bufsiz > 0)
-                                       this.transfer_data =
-                                           this.transfer_src.read(bufsiz);
-                               else
-                                       this.transfer_data = '';
-                               if (this.transfer_data.length == 0)
-                                       this.transfer_eof = true;
-                               this.transfer_size -=
-                                   this.transfer_data.length;
-                               this.transfer_state = STATE_TRANSFER_WRITE;
-                       } catch (x) {
-                               close = true;
-                               try {
-                                       this.transfer_src.close();
-                               } catch (x) {}
-                       }
-               }
-       }
-       if (this.transfer_state == STATE_TRANSFER_WRITE) {
-               if (this == this.transfer_dst) {
-                       /* Writing to client */
-                       if (this.transfer_eof)
-                               close = true;
-                       else {
-                               try {
-                                       this.bwrite(this.transfer_data);
-                                       this.transfer_state =
-                                           STATE_TRANSFER_READ;
-                                       this.updateTimeout(time);
-                               } catch (x) {
-                                       if (this.errno != Errno.EAGAIN)
-                                               close = true;
-                               }
-                       }
-                       if (close) {
-                               try {
-                                       this.transfer_src.close();
-                               } catch (x) {}
-                       }
-               } else {
-                       /* Writing to file */
-                       if (this.transfer_eof)
-                               close = true;
-                       else {
-                               try {
-                                       this.transfer_dst.write(
-                                           this.transfer_data);
-                                       this.transfer_state =
-                                           STAT_TRANSFER_READ;
-                               } catch (x) {
-                                       close = true;
-                               }
-                       }
-                       if (close) {
-                               try {
-                                       this.transfer_dst.fdatasync();
-                               } catch (x) {}
-                               try {
-                                       this.transfer_dst.close();
-                               } catch (x) {}
-                       }
-               }
-       }
-
-       return close;
-}
-
-/*
- * Updates input timeout expiration time for this FD.
- * To be passed current time in seconds since epoch.
- */
-FD.prototype.updateTimeout = function(time)
-{
-       /* Update input timeout expiration time */
-       this.expires = time + options.io_timeout;
-}
-
-/*
- * Reset FD to a consistent known state, to use after accept(2).
- * To be passed current time in seconds since epoch, and unique id to be used
- * as an index.
- */
-FD.prototype.init = function(time, idx)
-{
-       /* Not a bound socket */
-       this.bound = false;
-       /* Initial state */
-       this.transfer_state = STATE_TRANSFER_READ;
-       this.transfer_src = this.transfer_dst = null;
-       this.transfer_eof = false;
-       this.transfer_data = '';
-       /* Empty request string */
-       this.request_data = '';
-       /* Unique index */
-       this.index = idx;
-       /*
-        * Events interested in.  FD.POLLOUT to be eventually used instead in
-        * transfer state if transfering from server to client.
-        */
-       this.events = FD.POLLIN;
-       /*
-        * Default handler to process this FD, the request state one.
-        * To be changed to the transfer one as needed for transfer state.
-        */
-       this.process = process_query;
-       /* Initial input timeout */
-       this.updateTimeout(time);
-       /* For process_request()/process_post() */
-       this.bread_buffer = this.bwrite_buffer = '';
-       /*
-        * Flag used to speed up request parsing related to old HTTP requests
-        */
-       this.checked_old = false;
-
-       /*
-        * Note that fcntl(2) and setsockopt(2) flags applied to the bound
-        * descriptors are inherited to their children sockets at accept(2).
-        * We therefore can save a few syscalls here.
-        * We are non-blocking already, for instance.
-        */
-}
-
-/*
- * To be called once our client request has been read, to decide what action
- * to perform and modify state accordingly.
- */
-FD.prototype.parseRequest = function(time)
-{
-       var close = valid = false;
-       var evil_browser = evil_os = false;
-       var vhost = '';
-       var lines;
-       var words;
-       var i;
-       var sessid, sess;
-
-       this.http_protocol = '';
-       this.http_method = '';
-       this.http_vhost = undefined;
-       this.http_path = '';
-       this.http_vars_get = {};
-       this.http_vars_post = {};
-       this.http_vars_cookies = {};
-       this.http_agent = '';
-       this.http_content_length = -1;
-       this.http_modified_since = undefined;
-       this.http_sessid = undefined;
-       this.http_vars_session = {};
-       this.http_range = undefined;
-       this.http_old_get = false;
-
-       /* Split request lines */
-       lines = this.request_data.split("\r\n");
-
-       /* Verify if first line has a request which seems valid */
-       if (lines.length > 0) {
-               words = lines[0].split(' ');
-               if (words.length == 2 && words[0] == 'GET') {
-                       this.http_method = words[0];
-                       this.http_path = words[1];
-                       this.http_protocol = 'HTTP/1.1';
-                       this.http_old_get = true;
-                       valid = true;
-               } else if (words.length == 3) {
-                       if ((words[0] == 'GET' || words[0] == 'POST' ||
-                           words[0] == 'PUT') && (words[2] == 'HTTP/1.0' ||
-                           words[2] == 'HTTP/1.1')) {
-                               this.http_method = words[0];
-                               this.http_path = words[1];
-                               this.http_protocol = words[2];
-                               valid = true;
-                       }
-               }
-       }
-
-       /*
-        * Parse header for interesting lines.
-        */
-       if (valid && !this.http_old_get) {
-               for (i in lines) {
-                       words = lines[i].split(' ');
-                       if (words[0] == 'Host:' && words.length == 2) {
-                               var i2;
-
-                               if ((i2 = words[1].indexOf(':')) != -1)
-                                       words[1] = words[1].substr(0, i2);
-                               vhost = words[1];
-                       } else if (words[0] == 'Cookie:') {
-                               words = (lines[i].substr(8)).split('=');
-                               if (words.length == 2)
-                                       property_add(this.http_vars_cookies,
-                                           words[0], words[1]);
-                       } else if (words[0] == 'User-Agent:') {
-                               this.http_agent = lines[i].substr(12);
-                               if (options.ban_msie == true &&
-                                   this.http_agent.indexOf('MSIE') != -1)
-                                       evil_browser = true;
-                               if (options.ban_windows == true &&
-                                   this.http_agent.indexOf('Windows') != -1)
-                                       evil_os = true;
-                       } else if (words[0] == 'Content-Length:' &&
-                                  words.length == 2)
-                               this.http_content_length = words[1].valueOf();
-                       else if (words[0] == 'If-Modified-Since:')
-                               this.http_modified_since = Math.round(
-                                   Date.parse(lines[i].substr(19)) / 1000);
-                       else if (words[0] == 'Range:')
-                               this.http_range = lines[i].substr(7);
-               }
-       }
-
-       /*
-        * If no Host: line set the vhost, set the default one.
-        * If there is a vhost set, but is unknown, also set the default one.
-        * Also set the name of the vhost to the actual vhost name despite
-        * it possibly being resolved through an alias.
-        */
-       if (vhost == '' || vhosts_table[vhost] == undefined)
-               vhost = options.default_vhost;
-       this.http_vhost = vhosts_table[vhost.toLowerCase()];
-
-       if (this.http_old_get && this.http_vhost.scripts) {
-               /*
-                * We only allow old style GET request on static vhosts
-                */
-               this.bwrite('<html><head>' +
-                   '<title>Unsupported Old-Style Request</title></head>' +
-                   '<body><h1>Unsupported Old-Style Request</h1><p>' +
-                   'Your browser sent an old-style HTTP request, which ' +
-                   'this server does not support on dynamic content ' +
-                   'virtual hosts.  Use an HTTP/1.0 or HTTP/1.1 compliant ' +
-                   'client to continue.</p></body></html>' + "\r\n");
-               return true;
-       }
-
-       /*
-        * Filter out definitely invalid requests
-        */
-       if (!valid) {
-               http_error(this, 400, 'Bad Request',
-                   'Your browser sent an invalid HTTP query.');
-               return true;
-       }
-
-       /*
-        * Block out evil Microsoft products.  Start reporting the OS
-        * so that an unwanted windows user doesn't install another
-        * browser to then realize that his OS is banned nevertheless :)
-        */
-       if (evil_os) {
-               http_error(this, 666, 'Evil Operating System Banished!',
-                   'Your Operating System is evil born.<br>At least ' +
-                   '<b>upgrade</b> to a <a href="http://netbsd.org">' +
-                   'decent</a> OS to survive on these grounds.<br>');
-               return true;
-       } else if (evil_browser) {
-               http_error(this, 666, 'Evil Browser Banished!',
-                   'Your browser is evil born.<br>At least ' +
-                   '<b>upgrade</b> to a <a href="http://mozilla.org">' +
-                   'decent</a> browser to survive on these grounds.<br>');
-               return true;
-       }
-
-       /*
-        * Verify if client sent a session cookie, and if it consists of a
-        * valid one, load session data.
-        */
-       if (this.http_vhost.scripts &&
-           (sessid = this.http_vars_cookies['SessionID']) != undefined &&
-           (sess = sessions_table[sessid]) != undefined &&
-           sess.expires > time) {
-               this.http_sessid = sessid;
-               this.http_vars_session = sess.variables;
-       }
-
-       /*
-        * Fill in associative array with any GET-style supplied
-        * variables (as part of the URL).  We want this even for POST method.
-        */
-       if ((i = this.http_path.lastIndexOf('?')) != -1) {
-               var v;
-               var t;
-
-               v = this.http_path.substr(i + 1);
-               /*
-                * Note: substring() and substr() are semantically different
-                */
-               this.http_path = this.http_path.substring(0, i);
-               words = v.split('&');
-               for (i in words) {
-                       t = words[i].split('=');
-                       if (t.length == 2)
-                               property_add(this.http_vars_get, t[0], t[1]);
-               }
-       }
-
-       /*
-        * Switch to POST parsing mode if needed.
-        * This will then call this.parsePost() rather than this function,
-        * which will also invoke this.httpRespond().
-        */
-       if (this.http_method == 'POST' && this.http_content_length != -1) {
-               /*
-                * First obtain buffer stored by process_query() for us,
-                * if any.  If the full post_data was found in it, simply
-                * call the parsing function immediately, which will return
-                * with close status after invking httpRespond().
-                */
-               this.post_data = '';
-               if (this.bread_buffer.length > 0) {
-                       this.post_data += this.bread_buffer;
-                       this.bread_buffer = '';
-               }
-               if (this.post_data.length < this.http_content_length) {
-                       /* Go back to polling, activating process_post */
-                       this.post_data = '';
-                       this.process = process_post;
-                       return false;
-               } else
-                       return this.parsePost(time);
-       }
-
-       if (!close)
-               close = this.httpRespond(time);
-
-       return close;
-}
-
-/*
- * After reading post data, allows to parse it down into variables
- */
-FD.prototype.parsePost = function(time)
-{
-       var words;
-       var i;
-       var t;
-
-       /*
-        * We need to strip "\n", "\r" and "\r\n" which may be sent by broken
-        * clients.
-        */
-       this.post_data = this.post_data.replace(/\n/g, '');
-       this.post_data = this.post_data.replace(/\r/g, '');
-
-       words = this.post_data.split('&');
-       for (i in words) {
-               t = words[i].split('=');
-               if (t.length == 2)
-                       property_add(this.http_vars_post, t[0], t[1]);
-       }
-
-       delete this.post_data;
-
-       return this.httpRespond(time);
-}
-
-/*
- * Finally respond to client request
- */
-FD.prototype.httpRespond = function(time)
-{
-       var path, fd, st, res, ext, mimetype, i, sess, size;
-
-       /*
-        * Verify if requested path is valid
-        */
-       path = this.http_vhost.htdocs_root.valid_virtual(this.http_path);
-       if (!path) {
-               http_error(this, 403, 'Permission Denied',
-                   'You do not have the permission to access this ' +
-                   'resource.');
-               return true;
-       }
-
-       /*
-        * We now want to verify if the client sent a valid session cookie.
-        * If it didn't, we present it with a page with meta-tag reload
-        * instructions to attempt to reload the originally supplied URL,
-        * and with a new session cookie.
-        */
-       if (this.http_vhost.scripts == true && this.http_sessid == undefined) {
-               var doc, sess;
-
-               doc = new HTTPReply(200, 'OK',
-                   'text/html; charset=' + options.default_charset);
-               doc.addNoCacheHeaders();
-
-               sess = new Session(time,
-                   (this.http_vhost.session_exp != undefined ?
-                   this.http_vhost.session_exp :
-                   options.default_session_exp));
-               sess.variables.count = 0;
-               doc.addHeader('Set-Cookie: SessionID=' + sess.sessid +
-                   '; expires=' +
-                   (new Date(sess.expires * 1000)).toGMTString() +
-                   '; path=/');
-               doc.addContent('<html><head><META HTTP-EQUIV="refresh" ' +
-                   'CONTENT="5; URL=' + path.virtual + '"><title>Cookies' +
-                   '</title></head><body><h1>Cookies</h1><p>We are ' +
-                   ' verifying if your browser supports HTTP cookies.  ' +
-                   'These are required to keep persistent session data ' +
-                   'among your connections.  The destination page should ' +
-                   'load automatically in a few seconds.</p>' +
-                   ' <p>If it doesn\'t, please ensure that HTTP cookies ' +
-                   'are enabled on your HTTP client and are accepted ' +
-                   'from this server.</p>' +
-                   '<p>If the page still does not load properly after a ' +
-                   'few seconds, please click on <a href="' + path.virtual +
-                   '">this link</a>.</p><br><sub>' + SERVER_VERSION +
-                   '<br>' + SERVER_CVSID + '</sub>');
-               doc.flush(this, null);
-
-               return true;
-       }
-       if (this.http_sessid != undefined)
-               this.http_vars_session.count++;
-
-
-       /*
-        * Attempt to find requested file.
-        * If it consists of a directory, attempt to first find index.html in
-        * it, then index.jso in it, fail with error 403 if none can be found.
-        * Otherwise, continue forward keeping the descriptor open, and the
-        * stat information already filled in.
-        */
-       fd = new FD();
-
-       try {
-               fd.open(path.real, FD.O_RDONLY);
-               st = fd.fstat();
-       } catch (x) {
-               http_error(this, 404, 'Not Found',
-                   path.virtual + ' could not be found.');
-               return true;
-       }
-
-       if ((st.st_mode & FD.S_IFDIR) != 0) {
-               var error = false;
-
-               fd.close();
-               try {
-                       fd.open(path.real + '/index.html', FD.O_RDONLY);
-                       st = fd.fstat();
-                       path.real += '/index.html';
-                       path.virtual += '/index.html';
-               } catch (x) {
-                       try {
-                               fd.open(path.real + '/index.jso',
-                                   FD.O_RDONLY);
-                               st = fd.fstat();
-                               path.real += '/index.jso';
-                               path.virtual += '/index.jso';
-                       } catch (x) {
-                               error = true;
-                       }
-               }
-               if (error) {
-                       http_error(this, 403, 'Permission Denied',
-                           'You do not have the permission to access the ' +
-                           'resource ' + path.virtual);
-                       return true;
-               }
-       }
-
-       /*
-        * Only continue if file is a regular file
-        */
-       if ((st.st_mode & FD.S_IFREG) == 0) {
-               fd.close();
-               http_error(this, 403, 'Permission Denied',
-                   'You do not have the permission to access the resource ' +
-                   path.virtual);
-               return true;
-       }
-
-       /*
-        * Extract file extension, as well as its mime type.
-        */
-       if ((i = path.virtual.lastIndexOf('.')) != -1) {
-               ext = (path.virtual.substr(i + 1)).toLowerCase();
-               if (ext.lastIndexOf('/') == -1 &&
-                   mimetypes_table[ext] != undefined)
-                       mimetype = mimetypes_table[ext];
-               else
-                       mimetype = options.default_mimetype;
-       }
-       mimetype += '; charset=' + (this.http_vhost.charset == undefined ?
-           options.default_charset : this.http_vhost.charset);
-
-       /*
-        * JavaScript Object (JSO) files are processed especially.
-        * We interpret them, providing them with an environment to
-        * access the needed resources (get/post/cookie/session variables,
-        * as well as the document object they can use).
-        * We flush the document once the script returns, or fire up
-        * an error if something fails.
-        */
-       if (ext == 'jso') {
-
-               /* Create document object */
-               var obj = new HTTPReply(200, 'OK', mimetype);
-               obj.addNoCacheHeaders();
-
-               /* XXX Add other objects to export as necessary */
-               obj.get = this.http_vars_get;
-               obj.post = this.http_vars_post;
-               obj.cookie = this.http_vars_cookies;
-               obj.session = this.http_vars_session;
-               obj.global = this.http_vhost.globals;
-
-               /*
-                * Check if object in our cache already and file not modified
-                * since cached entry.  Reuse function then.  Otherwise,
-                * load in function from file, store a cache entry for it
-                * and launch it.
-                */
-
-               var data, s, o;
-
-               if (((o = jso_cache[path.real]) != undefined) &&
-                   o.time == st.st_mtime) {
-                       obj.script = o.script;
-                       fd.close();
-               } else {
-                       try {
-                               /* file_read() closes fd for us */
-                               data = file_read(fd);
-                               s = 'obj.script = function() {' + data + '}';
-                               eval(s);
-                               o = new JSO(path.real, st.st_mtime,
-                                   obj.script);
-                       } catch (x) {
-                               err.put(x + ' evaluating script ' + path.real
-                                   + "\n");
-                               http_error(this, 500, 'Internal Server Error',
-                                   'Please try again later.');
-                               return true;
-                       }
-               }
-
-               try {
-                       if (obj.script != undefined)
-                               obj.script();
-                       obj.flush(this, null);
-               } catch (x) {
-                       err.put(x + ' executing script ' + path.real + "\n");
-                       http_error(this, 500, 'Internal Server Error',
-                           'Please try again later.');
-               }
-
-               delete obj;
-               return true;
-       }
-
-       /*
-        * If client only wanted the document if it wasn't modified since
-        * a certain time, report that it wasn't if it is the case.
-        */
-       if (this.http_modified_since != undefined &&
-           st.st_mtime <= this.http_modified_since) {
-               fd.close();
-               res = new HTTPReply(304, 'Not Modified', null);
-               res.flush(this, null);
-               return true;
-       }
-
-       /*
-        * If client only requested a range of bytes of the file, verify if
-        * the range is valid, and if so, arrange to only transfer the
-        * requested part of the file.
-        * In any other case, simply transfer the whole file.
-        */
-       if (this.http_range != undefined) {
-               var w;
-
-               if (this.http_range.startsWith('bytes'))
-                       this.http_range = this.http_range.substr(5);
-               if (this.http_range.length > 0 &&
-                   this.http_range.charAt(0) == '=')
-                       this.http_range = this.http_range.substr(1);
-               if ((w = this.http_range.split('-')).length == 2) {
-                       var from, to;
-
-                       if (w[0] == '')
-                               w[0] = 0;
-                       if (w[1] == '')
-                               w[1] = st.st_size - 1;
-                       from = Number(w[0]);
-                       to = Number(w[1]);
-
-                       if (from >= 0 && to < st.st_size && to >= from) {
-                               res = new HTTPReply(206, 'Partial Content',
-                                   mimetype);
-                               res.addHeader('Content-Range: bytes ' +
-                                   from + '-' + to + '/' + st.st_size);
-                               this.transfer_size = Math.abs((to - from) + 1);
-                               if (from > 0) {
-                                       try {
-                                               fd.lseek(from, FD.SEEK_SET);
-                                       } catch(x) {
-                                               err.put(x + " at lseek()\n");
-                                       }
-                               }
-                       }
-               }
-       }
-       if (res == undefined) {
-               res = new HTTPReply(200, 'OK', mimetype);
-               this.transfer_size = Math.abs(st.st_size);
-       }
-
-       /*
-        * Flush HTTP header, sending it
-        */
-       res.flush(this, this.transfer_size);
-
-       /*
-        * Switch to outbound transfer mode.
-        */
-       this.transfer_src = fd;
-       this.transfer_dst = this;
-       this.process = process_transfer;
-       this.events = FD.POLLOUT;
-
-       /*
-        * Return with close=false, to delegate operations to
-        * process_transfer().
-        */
-       return false;
-}
-
-FD.prototype.httpDebug = function()
-{
-       table = new MLTag('table', true);
-       table.addAttr('width', '100%');
-       table.addAttr('border', '1');
-
-       var tr = new MLTag('tr', true);
-       var td = new MLTag('td', true);
-       td.addAttr('width', '10%');
-       td.addAttr('align', 'right');
-       td.addContent('You are:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       td.addAttr('width', '90%');
-       td.addContent(this.client_addr + ':' + this.client_port);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('You sent:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       var font = new MLTag('font', true);
-       font.addAttr('size', '-3');
-       pre = new MLTag('pre', true);
-       pre.addContent(this.request_data);
-       font.addContent(pre);
-       td.addContent(font);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('GET vars:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       var font = new MLTag('font', true);
-       font.addAttr('size', '-3');
-       pre = new MLTag('pre', true);
-       pre.addContent(uneval(this.http_vars_get));
-       font.addContent(pre);
-       td.addContent(font);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('POST vars:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       var font = new MLTag('font', true);
-       font.addAttr('size', '-3');
-       pre = new MLTag('pre', true);
-       pre.addContent(uneval(this.http_vars_post));
-       font.addContent(pre);
-       td.addContent(font);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('Cookies:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       var font = new MLTag('font', true);
-       font.addAttr('size', '-3');
-       pre = new MLTag('pre', true);
-       pre.addContent(uneval(this.http_vars_cookies));
-       font.addContent(pre);
-       td.addContent(font);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('VHost:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       td.addContent(this.http_vhost.name);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('Path:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       td.addContent(this.http_path);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('Mod-Since:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       td.addContent(this.http_modified_since);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('SessID:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       td.addContent(this.http_sessid);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       tr = new MLTag('tr', true);
-       td = new MLTag('td', true);
-       td.addAttr('align', 'right');
-       td.addContent('Sess vars:');
-       tr.addContent(td);
-       td = new MLTag('td', true);
-       var font = new MLTag('font', true);
-       font.addAttr('size', '-3');
-       pre = new MLTag('pre', true);
-       pre.addContent(uneval(this.http_vars_session));
-       font.addContent(pre);
-       td.addContent(font);
-       tr.addContent(td);
-       table.addContent(tr);
-
-       return table.toStr(0);
-}
-
-/*
- * Since we are using nonblocking mode, it is possible for write(2) to return
- * a short count, in which case we must be able to resume writing the
- * remaining buffer after poll(2).  There are currently two write paths,
- * HTTPResponse.flush() and process_transfer().  Both can use this function
- * instead of write(2).  The main poll(2) based loop can then handle buffer
- * flushing.  However, we first attempt to immediately write as much as we can
- * before queuing what needs to be written again.
- * Like write(2), this function can throw an exception on error, including
- * for EAGAIN.
- */
-FD.prototype.bwrite = function(data)
-{
-       var size;
-
-       if ((size = this.write(data)) == data.length)
-               return data.length;
-
-       this.bwrite_buffer += data.substr(size);
-       return size;
-}
-
-/*
- * Called by the main loop to know if there exists queued data, and to write
- * it out if needed.  Returns an object with two properties, done which if
- * true tells the caller that there is no more data to flush, and close
- * which if true means that an error occurred in which case connection should
- * be closed.
- */
-FD.prototype.bwrite_flush = function()
-{
-       var size;
-       var obj = new Object();
-
-       obj.done = obj.close = false;
-
-       if (this.bwrite_buffer.length == 0) {
-               obj.done = true;
-               return obj;
-       }
-
-       b = true;
-       try {
-               size = this.write(this.bwrite_buffer);
-               this.bwrite_buffer = this.bwrite_buffer.substr(size);
-               if (this.bwrite_buffer.length == 0)
-                       obj.done = true;
-       } catch (x) {
-               if (this.errno != Errno.EAGAIN)
-                       obj.close = true;
-       }
-
-       return obj;
-}
-
-/*
- * Verifies if property name ends with [], which considers it as an array of
- * values which are then pushed into that array.
- * Sets the property normally otherwise.
- */
-function property_add(obj, prop, val)
-{
-       prop = unescape(prop.replace(/\+/g, ' '));
-       val = unescape(val.replace(/\+/g, ' '));
-
-       if (prop.endsWith('[]')) {
-               /* Array entry */
-               prop = prop.substring(0, prop.length - 2);
-               if (obj[prop] == undefined)
-                       obj[prop] = [];
-               obj[prop].push(val);
-       } else
-               obj[prop] = val;
-}
-
-
-
-/*
- * To know how many connections we are currently serving and limit them
- */
-var counters_connections = 0;
-var counters_addresses = [];
-
-function counters_inc(fd)
-{
-
-       if (counters_connections >= options.max_connections)
-               return false;
-
-       var addr = fd.client_addr;
-       if ((addrcnt = counters_addresses[addr]) != undefined &&
-           addrcnt >= options.max_connections_addr)
-               return false;
-
-       if (addrcnt == undefined)
-               addrcnt = 1;
-       else
-               addrcnt++;
-       counters_addresses[addr] = addrcnt;
-
-       return true;
-}
-
-function counters_dec(fd)
-{
-       var addr = fd.client_addr;
-       if ((--counters_addresses[addr]) == 0)
-               delete counters_addresses[addr];
-
-       counters_connections--;
-}
-
-
-
-/*
- * Main program
- */
-function main() {
-       var i;
-       var sess_gc_secs = 0;
-
-       /*
-        * Populate vhosts database
-        */
-       for (i in vhosts) {
-               try {
-                       var v = new VHost(vhosts[i]);
-               } catch (x) {
-                       err.put(x + " creating VHost object\n");
-               }
-       }
-       /*
-        * Attempt to link default_vhost to a VHost object
-        */
-       if (options.default_vhost == undefined) {
-               err.put("No default_vhost property in options, exiting\n");
-               exit();
-       }
-       if (vhosts_table[options.default_vhost.toLowerCase()] != undefined)
-               default_vhost =
-                   vhosts_table[options.default_vhost.toLowerCase()];
-       else {
-               err.put('Default vhost ' + options.default_vhost +
-                   " unkonwn, exiting\n");
-               exit();
-       }
-
-       /*
-        * Populate mimetypes database.
-        * XXX If this got very large, because the destination strings
-        * are rather large, it might be good to use indexes or references
-        * to them rather than provide the string for each extension.
-        */
-       for (i in mimetypes) {
-               var i2, ext;
-
-               for (i2 in mimetypes[i]) {
-                       ext = mimetypes[i][i2].toLowerCase();
-                       if (mimetypes_table[ext] != undefined) {
-                               err.put('Conflicting mime type ' +
-                                   ext + ' -> ' + i + "\n");
-                               continue;
-                       }
-                       mimetypes_table[ext] = i;
-               }
-       }
-       if (mimetypes_table['jso'] == undefined)
-               mimetypes_table['jso'] = 'text/html';
-
-       /*
-        * Create polling array set
-        */
-       var set = [];
-
-       /*
-        * Initialize server
-        */
-       for (i in listen) {
-               var fd;
-
-               try {
-                       fd = new FD();
-                       fd.socket(FD.AF_INET, FD.SOCK_STREAM, 0);
-                       fd.bind(listen[i].address, listen[i].port);
-
-                       fd.setsockopt(FD.SO_REUSEADDR, 1);
-                       fd.setsockopt(FD.SO_LINGER, -1);
-                       fd.setsockopt(FD.SO_KEEPALIVE, 1);
-                       fd.setsockopt(FD.TCP_NODELAY, 1);
-
-                       fd.fcntl(FD.F_SETFL, FD.O_NONBLOCK);
-                       fd.listen(options.max_connections);
-                       /*
-                        * Mark socket as bound one and add it to
-                        * polling set
-                        */
-                       fd.events = FD.POLLIN;
-                       fd.bound = true;
-                       set.push(fd);
-               } catch (x) {
-                       err.put(x + " preparing listening socket\n");
-               }
-       }
-       if (set.length == 0)
-               exit();
-
-       /*
-        * Used for unique index associated to each FD for efficient removal
-        * from polling set when closing connection
-        */
-       var count = listen.length + 1;
-
-       /*
-        * Main loop
-        */
-       for (;;) {
-               /*
-                * Determine next to expire FD event, so that we can sleep
-                * as long as possible.  Also get rid of expired requests.
-                */
-               var cur = Date.parse(new Date) / 1000;
-               var exp = cur + 3600;
-               var old;
-               for (i in set) {
-                       var fd;
-
-                       if ((fd = set[i]) == undefined || fd.bound == true)
-                               continue;
-                       if (fd.expires <= cur) {
-                               /*
-                                * Request timeout expired for this
-                                * descriptor, we must close it.
-                                */
-                               fd.close();
-                               counters_dec(fd);
-                               delete set[fd.index];
-                               delete fd;
-                               continue;
-                       }
-                       if (fd.expires < exp)
-                               exp = fd.expires;
-               }
-               exp -= cur;
-
-               /*
-                * Poll our set of descriptors for events
-                */
-               var e;
-               try {
-                       e = FD.poll(set, exp * 1000);
-               } catch (x) {
-                       err.put(x + " for poll(2)\n");
-                       continue;
-               }
-
-               /*
-                * Verify if a timeout occurred.  Because our poll
-                * implementation returns an array, its timeout event can be
-                * checked against by verifying if the set is empty.
-                */
-               if (e.length == 0) {
-                       /* Timeout */
-                       continue;
-               }
-
-               /*
-                * XXX We should perhaps check timeouts after, so that we
-                * only need to query time once per loop?
-                * We could only do this if we knew that all our next
-                * processing is non-blocking, however.  Otherwise we
-                * would loose track of actual time.
-                */
-               old = cur;
-               cur = (Date.parse(new Date) / 1000);
-
-               /*
-                * Verify if we should call the session gc, and if so, do so.
-                */
-               sess_gc_secs += cur - old;
-               if (sess_gc_secs >= options.sess_gc_interval) {
-                       sess_gc_secs = 0;
-                       session_gc(cur);
-               }
-
-               /*
-                * Run through set of descriptors with pending events
-                */
-               for (i in e) {
-                       if (e[i] == undefined)
-                               continue;
-
-                       /*
-                        * If descriptor is a bound one, attempt to accept
-                        * the new client connection
-                        */
-                       if (e[i].bound == true &&
-                           (e[i].revents & FD.POLLIN) != 0) {
-                               var fd;
-
-                               try {
-                                       fd = e[i].accept();
-                                       if (!counters_inc(fd)) {
-                                               http_error(fd, 403.9,
-                                                   'Too Many Connections',
-                                   'Your browser has exceeded its maximum ' +
-                                   'allowed number of concurrent ' +
-                                   'connections.');
-                                               fd.close();
-                                               delete fd;
-                                       } else {
-                                               /*
-                                                * Setup client's initial
-                                                * state and add FD to polling
-                                                * set
-                                                */
-                                               if (++count > 999999)
-                                                       count = listen.length
-                                                          + 1;
-                                               fd.init(cur, count);
-                                               set[count] = fd;
-                                       }
-                               } catch (x) {
-                                       err.put(x + " at accept(2)\n");
-                               }
-                               continue;
-                       }
-
-                       /*
-                        * Not a new connection event
-                        */
-                       var close = false;
-
-                       /*
-                        * Close connection on error conditions,
-                        * Call the FD's process function on interesting
-                        * events, which will tell when we should drop the
-                        * client.
-                        */
-                       if ((e[i].revents & (FD.POLLHUP | FD.POLLERR)) != 0)
-                               close = true;
-                       else if ((e[i].revents & (FD.POLLIN | FD.POLLOUT))
-                           != 0) {
-                               /*
-                                * Flush output queue if any and possible,
-                                * since we're in non-blocking mode writes
-                                * can yield short counts.
-                                */
-                               var o = e[i].bwrite_flush();
-
-                               if (o.close == true)
-                                       close = true;
-                               else if (o.done == true)
-                                       close = e[i].process(cur);
-                       }
-
-                       if (close) {
-                               try {
-                                       e[i].close();
-                               } catch (x) {}
-                               counters_dec(e[i]);
-                               delete set[e[i].index];
-                               delete e[i];
-                       }
-               }
-       }
-
-       /* NOTREACHED */
-       err.close();
-}
-
-main();
-/* NOTREACHED */
-exit(0);
diff --git a/tests/js-test/js/httpd/ml_clean.js b/tests/js-test/js/httpd/ml_clean.js
deleted file mode 100644 (file)
index e0283c6..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* $Id: ml_clean.js,v 1.4 2005/07/12 13:09:07 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Define prototype of the MLTag object.
- */
-MLTag.prototype = {
-       /* A string of spaces to be used for indenting */
-       indent_str: '                                        ' +
-           '                              ',
-
-       /*
-        * Wraps specified string at 70 columns and observing specified
-        * indentation level
-        */
-       wrap: function(str, level)
-       {
-               var len = str.length;
-               var newstr = this.indent_str.substr(0, level);
-               var newlen = level;
-
-               /*
-                * Could find index to space and use substring as necessary
-                * instead of looping through every character.  Of course,
-                * this could also all be implemented using C native code.
-                */
-               for (var i = 0; i < len; i++) {
-                       var c = str.charAt(i);
-
-                       if (c == ' ' && newlen > 70) {
-                               newstr += "\n" + this.indent_str.substr(0,
-                                   level);
-                               newlen = level;
-                               continue;
-                       }
-                       newstr += c;
-                       newlen++;
-               }
-
-               return newstr;
-       },
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       addAttr: function(attr, value)
-       {
-
-               this.attributes[attr] = value;
-       },
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       addContent: function(item)
-       {
-
-               this.contents.push(item);
-       },
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       toStr: function(level)
-       {
-               var str = '';
-
-               /* Null tags may exist as containers */
-               if (this.tag != null) {
-
-                       /* Open opening tag */
-                       str += this.indent_str.substr(0, level) + '<' +
-                           this.tag;
-
-                       /*
-                        * Store these immediately for performance since we
-                        * use those values several times later on, also
-                        * saves typing
-                        */
-                       var taglen = this.tag.length;
-                       var len = level + taglen + 1;
-                       var attributes = this.attributes;
-
-                       /*
-                        * Add each of our attributes with their optional
-                        * values
-                        */
-                       for (var attr in attributes) {
-                               var value;
-
-                               if (len > 70) {
-                                       len = level + taglen + 1;
-                                       str += "\n" +
-                                           this.indent_str.substr(0, len);
-                               }
-                               str += ' ' + attr;
-                               len += taglen + 1;
-                               if ((value = attributes[attr]) != null) {
-                                       str += '="' + value + '"';
-                                       len += value.length + 3;
-                               }
-                       }
-
-                       /* Close opening tag */
-                       str += ">\n";
-
-                       /* Increase our indent level for content */
-                       level++;
-
-               }
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i in this.contents) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += this.wrap(a, level) + "\n";
-               }
-
-               /*
-                * If this tag required closing, do so
-                */
-               if (this.tag != null) {
-                       level--;
-                       if (this.close)
-                               str += this.indent_str.substr(0, level) +
-                                   '</' + this.tag + ">\n";
-               }
-
-               return str;
-       }
-}
-
-
-var entitites_table = {
-       '<': '&lt;',
-       '>': '&gt;',
-       '&': '&amp;',
-       '"': '&quot;',
-       "`": '&lsquo;',
-       "'": '&rsquo;'
-};
-
-/*
- * Function to convert a supplied string to use HTML/SGML special entitites.
- * This also allows HTML escaping from user-supplied strings.
- */
-function toHTMLEntities(str)
-{
-       var s = '';
-       var i, t, c, e;
-
-       for (i = 0, t = str.length; i < t; i++) {
-               c = str.charAt(i);
-               if ((e = entitites_table[c]) != undefined)
-                       s += e;
-               else
-                       s += c;
-       }
-
-       return s;
-}
diff --git a/tests/js-test/js/httpd/ml_machine.js b/tests/js-test/js/httpd/ml_machine.js
deleted file mode 100644 (file)
index d9783e9..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* $Id: ml_machine.js,v 1.4 2005/07/12 13:09:07 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Define prototype of the MLTag object.
- */
-MLTag.prototype = {
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       addAttr: function(attr, value)
-       {
-
-               this.attributes[attr] = value;
-       },
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       addContent: function(item)
-       {
-
-               this.contents.push(item);
-       },
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       toStr: function(level)
-       {
-               var str = '';
-
-               /* Null tags may exist as containers */
-               if (this.tag != null) {
-
-                       /* Open opening tag */
-                       str += '<' + this.tag;
-
-                       /*
-                        * Store these immediately for performance since we
-                        * use those values several times later on, also
-                        * saves typing
-                        */
-                       var taglen = this.tag.length;
-                       var len = taglen + 1;
-                       var attributes = this.attributes;
-
-                       /*
-                        * Add each of our attributes with their optional
-                        * values
-                        */
-                       for (var attr in attributes) {
-                               var value;
-
-                               str += ' ' + attr;
-                               len += taglen + 1;
-                               if ((value = attributes[attr]) != null) {
-                                       str += '="' + value + '"';
-                                       len += value.length + 3;
-                               }
-                       }
-
-                       /* Close opening tag */
-                       str += ">";
-
-               }
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i in this.contents) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(0);
-                       else
-                               str += a;
-               }
-
-               /*
-                * If this tag required closing, do so
-                */
-               if (this.tag != null && this.close)
-                       str += '</' + this.tag + ">";
-
-               return str;
-       }
-
-}
-
-
-var entitites_table = {
-       '<': '&lt;',
-       '>': '&gt;',
-       '&': '&amp;',
-       '"': '&quot;',
-       "`": '&lsquo;',
-       "'": '&rsquo;'
-};
-
-/*
- * Function to convert a supplied string to use HTML/SGML special entitites.
- * This also allows HTML escaping from user-supplied strings.
- */
-function toHTMLEntities(str)
-{
-       var s = '';
-       var i, t, c, e;
-
-       for (i = 0, t = str.length; i < t; i++) {
-               c = str.charAt(i);
-               if ((e = entitites_table[c]) != undefined)
-                       s += e;
-               else
-                       s += c;
-       }
-
-       return s;
-}
diff --git a/tests/js-test/js/httpd/options.js b/tests/js-test/js/httpd/options.js
deleted file mode 100644 (file)
index b0e49c0..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* $Id: options.js,v 1.17 2005/12/12 09:55:45 mmondor Exp $ */
-
-var options = {
-       max_connections:        32,
-       max_connections_addr:   4,
-       io_timeout:             60,
-       readbuf_size:           65536,
-       default_vhost:          "chat.pulsar-zone.net",
-       default_mimetype:       "application/octet-stream",
-       default_charset:        "us-ascii",
-       default_session_exp:    1800,
-       sess_gc_interval:       600,
-       sess_id_size:           64,
-       ban_msie:               false,
-       ban_windows:            false
-};
-
-/* Address:port combinations to listen to */
-var listen = [
-       {
-               address:        "127.0.0.1",
-               port:           8080
-       },
-       {
-               address:        "192.168.1.12",
-               port:           8080
-       }
-];
-
-var vhosts = [
-       /* Default virtual host */
-       {
-               name:           "chat.pulsar-zone.net",
-               root:           "/home/mmondor/jswww/chat",
-               scripts:        true,
-               charset:        'iso-8859-1',
-               session_exp:    14400
-       },
-
-       /* Dynamic application virtual host for ascpi.com */
-       {
-               name:           "ascpi.com",
-               aliases:        [ "www.ascpi.com", "ascpi.hal.xisop",
-                                   "ascpi.hal" ],
-               root:           "/home/mmondor/jswww/ascpi.com"
-       },
-
-       /* Static only test virtual host */
-       {
-               name:           "test.localhost",
-               root:           "/home/mmondor/jswww/welcome"
-       }
-];
-
-var mimetypes  = {
-       'text/html':                            [ "html", "htm", "dhtml",
-                                                   "jso" ],
-       'text/plain':                           [ "txt" ],
-       'text/css':                             [ "css" ],
-       'application/x-xpinstall':              [ "xpi" ],
-       'application/vnd.mozilla.xul+xml':      [ "xul" ],
-       'text/rdf':                             [ "rdf" ],
-       'application/pdf':                      [ "pdf" ],
-       'application/postscript':               [ "ps" ],
-       'application/x-tar':                    [ "tar" ],
-       'application/x-gzip':                   [ "gz" ],
-       'application/x-bzip2':                  [ "bz2" ],
-       'application/zip':                      [ "zip" ],
-       'application/x-javascript':             [ "js" ],
-       'application/x-c':                      [ "c", "h", "cpp", "cc" ],
-       'application/x-sh':                     [ "sh" ],
-       'application/x-shockwave-flash':        [ "swf" ],
-       'application/xml':                      [ "xml" ],
-       'application/xml-dtd':                  [ "dtd" ],
-       'image/jpg':                            [ "jpg", "jpeg" ],
-       'image/png':                            [ "png" ],
-       'image/gif':                            [ "gif" ],
-       'image/x-icon':                         [ "ico" ],
-       'video/mpeg':                           [ "mpeg", "mpg" ],
-       'video/quicktime':                      [ "mov" ],
-       'video/x-msvideo':                      [ "asf", "asx", "wmv", "avi" ]
-};
diff --git a/tests/js-test/js/httpd/root.js b/tests/js-test/js/httpd/root.js
deleted file mode 100644 (file)
index c46fd2b..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* $Id: root.js,v 1.1 2005/07/07 00:11:43 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Implementation of a virtual chroot(2) system.
- */
-
-
-
-const PATH_MAX = 255;
-
-
-
-function Root(root)
-{
-
-       if (!(this.root = this.valid_path(root)))
-               throw('Invalid root path "' + root + '"!');
-       this.cwd = '/';
-}
-
-Root.prototype = {
-
-       /*
-        * Quick lookup table of valid characters within pathnames.
-        * Currently 'a'-'z', 'A'-'Z', '0'-'9', '.', '/', '-', '_'
-        */
-       valid_char_table: [
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
-               1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-               0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-               1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
-               0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-               1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-       ],
-
-       /*
-        * Base function to return formatted valid path, or false.
-        * Returned path will always begin with '/' and not have any
-        * trailing '/'.  Multiple '/' are also collapsed into one.
-        */
-       valid_path: function(path)
-       {
-               var i, t, l, p, c, code;
-
-               p = l = '/';
-               for (i = 0, t = path.length; i < t; i++) {
-                       c = path.charAt(i);
-                       if (l == '/') {
-                               /* Collapse multiple '/' */
-                               if (c == '/')
-                                       continue;
-                               /* Prohibit '.' at start of element */
-                               if (c == '.')
-                                       return false;
-                       }
-                       /* Validate chars */
-                       code = c.charCodeAt(0);
-                       if (code != code & 0xff || 
-                           this.valid_char_table[code] == 0)
-                               return false;
-                       p += c;
-                       l = c;
-               }
-               /* Strip last '/' if any, unless only one */
-               if (c == '/' && p.length > 1)
-                       p = p.substr(0, p.length - 1);
-
-               /* If exceeding PATH_MAX, return false */
-               if (p.length > PATH_MAX)
-                       return false;
-
-               return p;
-       },
-
-       /*
-        * Returns version of provided path which points to the parent
-        * directory if possible.  Returns false otherwise.
-        * Should only be used with paths first copied using valid_path().
-        * Can typically be used with the cwd.
-        */
-       parent: function(path)
-       {
-               var i;
-
-               /* First make sure that path starts with '/' */
-               if (path.length < 2 || path.charAt(0) != '/')
-                       return false;
-
-               /* Strip trailing '/' chars */
-               for (i = path.length - 1; i >= 0 && path.charAt(i) == '/';
-                   i--) ;
-               if (i <= path.length)
-                       path = path.substr(0, i + 1);
-
-               /*
-                * Locate previous '/', strip everything after it, including
-                * it, except in the case where it is the only remaining,
-                * where path must remain '/'.
-                */
-               if ((i = path.lastIndexOf('/')) == 0)
-                       i = 1;
-               return path.substring(0, i);
-       },
-
-       /*
-        * This function should always be called when processing user-supplied
-        * paths.  The application should then only trust the object it
-        * returns.  Returns false if the path is invalid.
-        * Otherwise, returns an object, with the following properties:
-        *
-        * <real>       System-wide absolute real fullpath, to be used by the
-        *              application to access the files/directories in
-        *              question.
-        * <virtual>    Virtual root based absolute fullpath, useful to report
-        *              to the user.  Can also be useful to change a Root
-        *              object's cwd to, after verifying that <real> really
-        *              points to an existing directory.
-        */
-       valid_virtual: function(path)
-       {
-               var cwd, c, l, t, o;
-
-               o = {};
-               cwd = this.cwd;
-
-               /*
-                * Look for '~', or '/' in the beginning of the path,
-                * in which case cwd gets cleared to '/'.  Also look for
-                * './' or '.[EOS]', which we simply skip, meaning the
-                * current directory.
-                */
-               if ((l = path.length) > 0) {
-                       c = path.charAt(0);
-                       if (c == '~' || c == '/') {
-                               cwd = '/';
-                               path = path.substr(1);
-                       } else if (c == '.') {
-                               if (l == 1)
-                                       path = '';
-                               else if (l > 1 && path.charAt(1) == '/')
-                                       path = path.substr(2);
-                       }
-               }
-
-               /*
-                * Now process all starting '..' or '../', modifying cwd if
-                * allowed, and stripping them from path.  In case of '../',
-                * also strip any multiple '/'.
-                */
-               for (;;) {
-                       t = false;
-                       l = path.length;
-                       if ((l == 2 && path == '..') ||
-                           (l > 2 && path.substr(0, 2) == '..' &&
-                           (t = (path.charAt(2) == '/')))) {
-                               if (!(cwd = this.parent(cwd)))
-                                       return false;
-                               if (t) {
-                                       for (i = 2; path.charAt(i) == '/';
-                                           i++) ;
-                                       path = path.substr(i);
-                                       continue;
-                               } else {
-                                       path = path.substr(2);
-                                       continue;
-                               }
-                       }
-                       break;
-               }
-
-               /*
-                * Now attempt to fill in our object properties.
-                * this.valid_path() performs necessary sanity checking.
-                */
-               if (!(o.virtual = this.valid_path('/' + cwd + '/' + path)))
-                       return false;
-               o.real = this.root + o.virtual;
-
-               return o;
-       }
-
-};
diff --git a/tests/js-test/js/httpd/string.js b/tests/js-test/js/httpd/string.js
deleted file mode 100644 (file)
index 5ed8080..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id: string.js,v 1.1 2005/07/11 01:50:56 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Extension to the standard String object to support startsWith() and
- * endsWith() very useful methods.
- */
-
-
-
-String.prototype.startsWith = function(str)
-{
-       var t = str.length;
-
-       if (this.length >= t && this.substr(0, t) == str)
-               return true;
-
-       return false;
-}
-
-String.prototype.endsWith = function(str)
-{
-       var t1 = str.length;
-       var t2 = this.length;
-
-       if (t2 >= t1 && this.substr(t2 - t1, t1) == str)
-               return true;
-
-       return false;
-}
diff --git a/tests/js-test/js/ml.js b/tests/js-test/js/ml.js
deleted file mode 100644 (file)
index dd09de6..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* $Id: ml.js,v 1.4 2005/06/27 18:21:21 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-const ident_str = '                                                  ' +
-    '                    ';
-
-function indent(level)
-{
-       if (level == null)
-               return false;
-
-       return ident_str.substr(0, level);
-}
-
-function wrap(str, level)
-{
-       if (str == null || level == null)
-               return false;
-
-       var len = str.length;
-       var newstr = indent(level);
-       var newlen = level;
-       var i;
-
-       /*
-        * Could find index to space and use substring as necessary instead of
-        * looping through every character.  Of course, this could also all be
-        * implemented using C native code.
-        */
-       for (i = 0; i < len; i++) {
-               if (str.charAt(i) == ' ' && newlen > 70) {
-                       newstr += "\n" + indent(level);
-                       newlen = level;
-                       continue;
-               }
-               newstr += str.charAt(i);
-               newlen++;
-       }
-
-       return newstr;
-}
-
-
-
-function MLAttr(attr, value)
-{
-       /* We allow null value */
-       if (attr == null)
-               return false;
-
-       this.attr = attr;
-       this.value = value;
-}
-
-
-
-/*
- * XXX Using prototypes to inherit functions would be ideal for speed,
- * probably, to avoid having to redeclare the functions in the constructor for
- * every new object instance.  However, I seemed to have problems when using
- * that method, mostly related to the constructor of the object no longer
- * being tracable.
- */
-
-function MLTag(attr, close)
-{
-       if (attr == null || close == null)
-               return false;
-
-       this.attr = attr;
-       this.close = close;
-       this.attributes = new Array();
-       this.attributes_count = 0;
-       this.contents = new Array();
-       this.contents_count = 0;
-
-       this.addAttr = function(attr, value)
-       {
-               if (attr == null)
-                       return false;
-
-               this.attributes[this.attributes_count++] =
-                   new MLAttr(attr, value);
-       }
-
-       this.addContent = function(item)
-       {
-               if (item == null)
-                       return false;
-
-               this.contents[this.contents_count++] = item;
-       }
-
-       this.toStr = function(level)
-       {
-               if (level == null)
-                       return false;
-
-               var str = '';
-               var i, attrlen, len, a;
-
-               str += indent(level) + '<' + this.attr;
-               attrlen = this.attr.length;
-               len = level + attrlen + 1;
-               for (i = 0; i < this.attributes_count; i++) {
-                       a = this.attributes[i];
-
-                       if (len > 70) {
-                               len = level + attrlen + 1;
-                               str += "\n" + indent(len);
-                       }
-                       str += ' ' + a.attr;
-                       len += attrlen + 1;
-                       if (a.value != null) {
-                               var value = a.value;
-                               str += '="' + value + '"';
-                               len += value.length + 3;
-                       }
-               }
-               str += ">\n";
-
-               if (this.close)
-                       level++;
-
-               for (i = 0; i < this.contents_count; i++) {
-                       a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += wrap(a, level) + "\n";
-               }
-
-               if (this.close)
-                       str += indent(--level) + '</' + this.attr + ">\n";
-
-               return str;
-       }
-}
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/ml2.js b/tests/js-test/js/ml2.js
deleted file mode 100644 (file)
index 6a1eab6..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* $Id: ml2.js,v 1.3 2005/06/27 19:45:22 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * XXX Using prototypes to inherit functions would be ideal for speed,
- * probably, to avoid having to redeclare the functions in the constructor for
- * every new object instance.  However, I seemed to have problems when using
- * that method, mostly related to the constructor of the object no longer
- * being tracable.  At worse, we could define our methods as MLTag_foo() and
- * in the constructor function just assign them to the proper properties...
- * The currently used method at least has advantage of being cleaner to read.
- */
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       if (tag == null || close == null)
-               return false;
-
-       /*
-        * A few utility functions used by our methods later on.
-        * Adding these here prevents namespace pollution.
-        */
-
-       /* Returns a string with requested number of spaces */
-       const indent_str = '                                        ' +
-           '                              ';
-       this.indent = function(level)
-       {
-               if (level == null)
-                       return false;
-
-               return indent_str.substr(0, level);
-       }
-
-       /*
-        * Wraps specified string at 70 columns and observing specified
-        * indentation level
-        */
-       this.wrap = function(str, level)
-       {
-               if (str == null || level == null)
-                       return false;
-
-               var len = str.length;
-               var newstr = this.indent(level);
-               var newlen = level;
-
-               /*
-                * Could find index to space and use substring as necessary
-                * instead of looping through every character.  Of course,
-                * this could also all be implemented using C native code.
-                */
-               for (var i = 0; i < len; i++) {
-                       var c = str.charAt(i);
-
-                       if (c == ' ' && newlen > 70) {
-                               newstr += "\n" + this.indent(level);
-                               newlen = level;
-                               continue;
-                       }
-                       newstr += c;
-                       newlen++;
-               }
-
-               return newstr;
-       }
-
-
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = new Object();
-       this.contents = new Array();
-       this.contents_count = 0;
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       this.addAttr = function(attr, value)
-       {
-               if (attr == null)
-                       return false;
-
-               eval('this.attributes.' + attr + ' = \'' + value + '\'');
-       }
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       this.addContent = function(item)
-       {
-               if (item == null)
-                       return false;
-
-               this.contents[this.contents_count++] = item;
-       }
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       this.toStr = function(level)
-       {
-               if (level == null)
-                       return false;
-
-               /* Open opening tag */
-               var str = this.indent(level) + '<' + this.tag;
-
-               /*
-                * Store these immediately for performance since we use those
-                * values several times later on, also saves typing
-                */
-               var taglen = this.tag.length;
-               var len = level + taglen + 1;
-               var attributes = this.attributes;
-
-               /* Add each of our attributes with their optional values */
-               for (var attr in attributes) {
-                       var value;
-
-                       if (len > 70) {
-                               len = level + taglen + 1;
-                               str += "\n" + this.indent(len);
-                       }
-                       str += ' ' + attr;
-                       len += taglen + 1;
-                       if ((value = attributes[attr]) != null) {
-                               str += '="' + value + '"';
-                               len += value.length + 3;
-                       }
-               }
-               /* Close opening tag */
-               str += ">\n";
-
-               /* Increase our indent level for content */
-               level++;
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i = 0; i < this.contents_count; i++) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += this.wrap(a, level) + "\n";
-               }
-
-               /*
-                * This tag required closing, so add corresponding closing tag
-                * and decrease indent level.
-                */
-               level--;
-               if (this.close)
-                       str += this.indent(level) + '</' + this.tag + ">\n";
-
-               return str;
-       }
-}
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/ml3.js b/tests/js-test/js/ml3.js
deleted file mode 100644 (file)
index 3b8cb3b..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* $Id: ml3.js,v 1.3 2005/06/27 19:45:22 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * XXX Using prototypes to inherit functions would be ideal for speed,
- * probably, to avoid having to redeclare the functions in the constructor for
- * every new object instance.  However, I seemed to have problems when using
- * that method, mostly related to the constructor of the object no longer
- * being tracable.  At worse, we could define our methods as MLTag_foo() and
- * in the constructor function just assign them to the proper properties...
- * The currently used method at least has advantage of being cleaner to read.
- */
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       if (tag == null || close == null)
-               return false;
-
-       /*
-        * A few utility functions used by our methods later on.
-        * Adding these here prevents namespace pollution.
-        */
-
-       /* Returns a string with requested number of spaces */
-       const indent_str = '                                        ' +
-           '                              ';
-       this.indent = function(level)
-       {
-               if (level == null)
-                       return false;
-
-               return indent_str.substr(0, level);
-       }
-
-       /*
-        * Wraps specified string at 70 columns and observing specified
-        * indentation level
-        */
-       this.wrap = function(str, level)
-       {
-               if (str == null || level == null)
-                       return false;
-
-               var len = str.length;
-               var newstr = this.indent(level);
-               var newlen = level;
-
-               /*
-                * Could find index to space and use substring as necessary
-                * instead of looping through every character.  Of course,
-                * this could also all be implemented using C native code.
-                */
-               for (var i = 0; i < len; i++) {
-                       var c = str.charAt(i);
-
-                       if (c == ' ' && newlen > 70) {
-                               newstr += "\n" + this.indent(level);
-                               newlen = level;
-                               continue;
-                       }
-                       newstr += c;
-                       newlen++;
-               }
-
-               return newstr;
-       }
-
-
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = new Array();  /* Associative */
-       this.contents = new Array();
-       this.contents_count = 0;
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       this.addAttr = function(attr, value)
-       {
-               if (attr == null)
-                       return false;
-
-               this.attributes[attr] = value;
-       }
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       this.addContent = function(item)
-       {
-               if (item == null)
-                       return false;
-
-               this.contents[this.contents_count++] = item;
-       }
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       this.toStr = function(level)
-       {
-               if (level == null)
-                       return false;
-
-               /* Open opening tag */
-               var str = this.indent(level) + '<' + this.tag;
-
-               /*
-                * Store these immediately for performance since we use those
-                * values several times later on, also saves typing
-                */
-               var taglen = this.tag.length;
-               var len = level + taglen + 1;
-               var attributes = this.attributes;
-
-               /* Add each of our attributes with their optional values */
-               for (var attr in attributes) {
-                       var value;
-
-                       if (len > 70) {
-                               len = level + taglen + 1;
-                               str += "\n" + this.indent(len);
-                       }
-                       str += ' ' + attr;
-                       len += taglen + 1;
-                       if ((value = attributes[attr]) != null) {
-                               str += '="' + value + '"';
-                               len += value.length + 3;
-                       }
-               }
-               /* Close opening tag */
-               str += ">\n";
-
-               /* Increase our indent level for content */
-               level++;
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i = 0; i < this.contents_count; i++) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += this.wrap(a, level) + "\n";
-               }
-
-               /*
-                * This tag required closing, so add corresponding closing tag
-                * and decrease indent level.
-                */
-               level--;
-               if (this.close)
-                       str += this.indent(level) + '</' + this.tag + ">\n";
-
-               return str;
-       }
-}
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/ml4.js b/tests/js-test/js/ml4.js
deleted file mode 100644 (file)
index e2d3383..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/* $Id: ml4.js,v 1.5 2005/06/27 19:45:22 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       if (tag == null || close == null)
-               return false;
-
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Force creation of prototype object
- */
-MLTag('prototype', false);
-
-/*
- * A few utility functions used by our methods later on.
- * Adding these here prevents namespace pollution.
- */
-
-MLTag.prototype.indent_str = '                                        ' +
-    '                              ';
-/* Returns a string with requested number of spaces */
-MLTag.prototype.indent = function(level)
-{
-       if (level == null)
-               return false;
-
-       return this.indent_str.substr(0, level);
-}
-
-/*
- * Wraps specified string at 70 columns and observing specified
- * indentation level
- */
-MLTag.prototype.wrap = function(str, level)
-{
-       if (str == null || level == null)
-               return false;
-
-       var len = str.length;
-       var newstr = this.indent(level);
-       var newlen = level;
-
-       /*
-        * Could find index to space and use substring as necessary
-        * instead of looping through every character.  Of course,
-        * this could also all be implemented using C native code.
-        */
-       for (var i = 0; i < len; i++) {
-               var c = str.charAt(i);
-
-               if (c == ' ' && newlen > 70) {
-                       newstr += "\n" + this.indent(level);
-                       newlen = level;
-                       continue;
-               }
-               newstr += c;
-               newlen++;
-       }
-
-       return newstr;
-}
-
-/*
- * Add specified attribute with optional associated value to this tag
- */
-MLTag.prototype.addAttr = function(attr, value)
-{
-       if (attr == null)
-               return false;
-
-       this.attributes[attr] = value;
-}
-
-/*
- * Add arbitrary content in sequencial order to this tag's body
- */
-MLTag.prototype.addContent = function(item)
-{
-       if (item == null)
-               return false;
-
-       this.contents.push(item);
-}
-
-/*
- * Returns a string consisting of this tag along with its body and
- * optional corresponding closing tag
- */
-MLTag.prototype.toStr = function(level)
-{
-       if (level == null)
-               return false;
-
-       /* Open opening tag */
-       var str = this.indent(level) + '<' + this.tag;
-
-       /*
-        * Store these immediately for performance since we use those
-        * values several times later on, also saves typing
-        */
-       var taglen = this.tag.length;
-       var len = level + taglen + 1;
-       var attributes = this.attributes;
-
-       /* Add each of our attributes with their optional values */
-       for (var attr in attributes) {
-               var value;
-
-               if (len > 70) {
-                       len = level + taglen + 1;
-                       str += "\n" + this.indent(len);
-               }
-               str += ' ' + attr;
-               len += taglen + 1;
-               if ((value = attributes[attr]) != null) {
-                       str += '="' + value + '"';
-                       len += value.length + 3;
-               }
-       }
-       /* Close opening tag */
-       str += ">\n";
-
-       /* Increase our indent level for content */
-       level++;
-
-       /*
-        * Now add all our contents, if any, which may consist of
-        * other MLTag objects or arbitrary String objects.  Use
-        * recursion to process MLTag ones, which may also have their
-        * respective bodies and closing tags.
-        */
-       for (var i = 0; i < this.contents.length; i++) {
-               var a = this.contents[i];
-
-               if (typeof a == 'object')
-                       str += a.toStr(level);
-               else
-                       str += this.wrap(a, level) + "\n";
-       }
-
-       /*
-        * This tag required closing, so add corresponding closing tag
-        * and decrease indent level.
-        */
-       level--;
-       if (this.close)
-               str += this.indent(level) + '</' + this.tag + ">\n";
-
-       return str;
-}
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/ml5.js b/tests/js-test/js/ml5.js
deleted file mode 100644 (file)
index 9c7b772..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* $Id: ml5.js,v 1.3 2005/06/27 19:45:22 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       /*
-       if (tag == null || close == null)
-               return false;
-        */
-
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Define prototype of the MLTag object.
- */
-MLTag.prototype = {
-       /* A string of spaces to be used by indent() */
-       indent_str: '                                        ' +
-           '                              ',
-
-       /* Returns a string with requested number of spaces */
-       indent: function(level)
-       {
-               /*
-               if (level == null)
-                       return false;
-                */
-
-               return this.indent_str.substr(0, level);
-       },
-
-       /*
-        * Wraps specified string at 70 columns and observing specified
-        * indentation level
-        */
-       wrap: function(str, level)
-       {
-               /*
-               if (str == null || level == null)
-                       return false;
-                */
-
-               var len = str.length;
-               var newstr = this.indent(level);
-               var newlen = level;
-
-               /*
-                * Could find index to space and use substring as necessary
-                * instead of looping through every character.  Of course,
-                * this could also all be implemented using C native code.
-                */
-               for (var i = 0; i < len; i++) {
-                       var c = str.charAt(i);
-
-                       if (c == ' ' && newlen > 70) {
-                               newstr += "\n" + this.indent(level);
-                               newlen = level;
-                               continue;
-                       }
-                       newstr += c;
-                       newlen++;
-               }
-
-               return newstr;
-       },
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       addAttr: function(attr, value)
-       {
-               /*
-               if (attr == null)
-                       return false;
-                */
-
-               this.attributes[attr] = value;
-       },
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       addContent: function(item)
-       {
-               /*
-               if (item == null)
-                       return false;
-                */
-
-               this.contents.push(item);
-       },
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       toStr: function(level)
-       {
-               /*
-               if (level == null)
-                       return false;
-                */
-
-               /* Open opening tag */
-               var str = this.indent(level) + '<' + this.tag;
-
-               /*
-                * Store these immediately for performance since we use those
-                * values several times later on, also saves typing
-                */
-               var taglen = this.tag.length;
-               var len = level + taglen + 1;
-               var attributes = this.attributes;
-
-               /* Add each of our attributes with their optional values */
-               for (var attr in attributes) {
-                       var value;
-
-                       if (len > 70) {
-                               len = level + taglen + 1;
-                               str += "\n" + this.indent(len);
-                       }
-                       str += ' ' + attr;
-                       len += taglen + 1;
-                       if ((value = attributes[attr]) != null) {
-                               str += '="' + value + '"';
-                               len += value.length + 3;
-                       }
-               }
-               /* Close opening tag */
-               str += ">\n";
-
-               /* Increase our indent level for content */
-               level++;
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i = 0; i < this.contents.length; i++) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += this.wrap(a, level) + "\n";
-               }
-
-               /*
-                * This tag required closing, so add corresponding closing tag
-                * and decrease indent level.
-                */
-               level--;
-               if (this.close)
-                       str += this.indent(level) + '</' + this.tag + ">\n";
-
-               return str;
-       }
-}
-
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/ml6.js b/tests/js-test/js/ml6.js
deleted file mode 100644 (file)
index 15c3b8c..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* $Id: ml6.js,v 1.1 2005/11/16 00:35:01 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Define prototype of the MLTag object.
- */
-MLTag.prototype = {
-       /* A string of spaces to be used for indenting */
-       indent_str: '                                        ' +
-           '                              ',
-
-       /*
-        * Wraps specified string at 70 columns and observing specified
-        * indentation level
-        */
-       wrap: function(str, level)
-       {
-               var len = str.length;
-               var newstr = this.indent_str.substr(0, level);
-               var newlen = level;
-
-               /*
-                * Could find index to space and use substring as necessary
-                * instead of looping through every character.  Of course,
-                * this could also all be implemented using C native code.
-                */
-               for (var i = 0; i < len; i++) {
-                       var c = str.charAt(i);
-
-                       if (c == ' ' && newlen > 70) {
-                               newstr += "\n" + this.indent_str.substr(0,
-                                   level);
-                               newlen = level;
-                               continue;
-                       }
-                       newstr += c;
-                       newlen++;
-               }
-
-               return newstr;
-       },
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       addAttr: function(attr, value)
-       {
-
-               this.attributes[attr] = value;
-       },
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       addContent: function(item)
-       {
-
-               this.contents.push(item);
-       },
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       toStr: function(level)
-       {
-
-               /* Open opening tag */
-               var str = this.indent_str.substr(0, level) + '<' + this.tag;
-
-               /*
-                * Store these immediately for performance since we use those
-                * values several times later on, also saves typing
-                */
-               var taglen = this.tag.length;
-               var len = level + taglen + 1;
-               var attributes = this.attributes;
-
-               /* Add each of our attributes with their optional values */
-               for (var attr in attributes) {
-                       var value;
-
-                       if (len > 70) {
-                               len = level + taglen + 1;
-                               str += "\n" + this.indent_str.substr(0, len);
-                       }
-                       str += ' ' + attr;
-                       len += taglen + 1;
-                       if ((value = attributes[attr]) != null) {
-                               str += '="' + value + '"';
-                               len += value.length + 3;
-                       }
-               }
-               /* Close opening tag */
-               str += ">\n";
-
-               /* Increase our indent level for content */
-               level++;
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i = 0; i < this.contents.length; i++) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(level);
-                       else
-                               str += this.wrap(a, level) + "\n";
-               }
-
-               /*
-                * This tag required closing, so add corresponding closing tag
-                * and decrease indent level.
-                */
-               level--;
-               if (this.close)
-                       str += this.indent_str.substr(0, level) + '</' +
-                           this.tag + ">\n";
-
-               return str;
-       }
-}
-
-
-
-
-/*
- * Now test our functionality
- */
-
-out = new FD();
-out.set(FD.STDOUT_FILENO);
-
-for (i = 0; i < 1000; i++) {
-
-var table = new MLTag('table', true);
-table.addAttr('border', 0);
-table.addAttr('width', '100%');
-
-var tr = new MLTag('tr', true);
-
-var td = new MLTag('td', true);
-td.addAttr('bgcolor', '#000000');
-
-var p = new MLTag('p', true);
-p.addContent('Hello');
-
-td.addContent(p);
-tr.addContent(td);
-table.addContent(tr);
-
-out.put(table.toStr(8));
-
-//out.put(uneval(table));
-
-}
diff --git a/tests/js-test/js/parse.js b/tests/js-test/js/parse.js
deleted file mode 100644 (file)
index 672b115..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/* $Id: parse.js,v 1.1 2005/11/16 00:36:58 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-/*
- * Useful object to use for HTML tags.  <tab> consists of tag name, and
- * <close> of a boolean specifying of the tag requires a corresponding closing
- * tag (i.e. <p>[body]</p>.  Attributes and body elements may be added after
- * creating such an object, and toStr() used to obtain the actual HTML result.
- */
-function MLTag(tag, close)
-{
-       /*
-        * MLTag object properties
-        */
-       this.tag = tag;
-       this.close = close;
-       this.attributes = {};   /* Object with associative attributes */
-       this.contents = [];     /* Array object */
-}
-
-/*
- * Define prototype of the MLTag object.
- */
-MLTag.prototype = {
-
-       /*
-        * Add specified attribute with optional associated value to this tag
-        */
-       addAttr: function(attr, value)
-       {
-
-               this.attributes[attr] = value;
-       },
-
-       /*
-        * Add arbitrary content in sequencial order to this tag's body
-        */
-       addContent: function(item)
-       {
-
-               this.contents.push(item);
-       },
-
-       /*
-        * Returns a string consisting of this tag along with its body and
-        * optional corresponding closing tag
-        */
-       toStr: function(level)
-       {
-               var str = '';
-
-               /* Null tags may exist as containers */
-               if (this.tag != null) {
-
-                       /* Open opening tag */
-                       str += '<' + this.tag;
-
-                       /*
-                        * Store these immediately for performance since we
-                        * use those values several times later on, also
-                        * saves typing
-                        */
-                       var taglen = this.tag.length;
-                       var len = taglen + 1;
-                       var attributes = this.attributes;
-
-                       /*
-                        * Add each of our attributes with their optional
-                        * values
-                        */
-                       for (var attr in attributes) {
-                               var value;
-
-                               str += ' ' + attr;
-                               len += taglen + 1;
-                               if ((value = attributes[attr]) != null) {
-                                       str += '="' + value + '"';
-                                       len += value.length + 3;
-                               }
-                       }
-
-                       /* Close opening tag */
-                       str += ">";
-
-               }
-
-               /*
-                * Now add all our contents, if any, which may consist of
-                * other MLTag objects or arbitrary String objects.  Use
-                * recursion to process MLTag ones, which may also have their
-                * respective bodies and closing tags.
-                */
-               for (var i = 0; i < this.contents.length; i++) {
-                       var a = this.contents[i];
-
-                       if (typeof a == 'object')
-                               str += a.toStr(0);
-                       else
-                               str += a;
-               }
-
-               /*
-                * If this tag required closing, do so
-                */
-               if (this.tag != null && this.close)
-                       str += '</' + this.tag + ">";
-
-               return str;
-       }
-
-}
-
-
-var entitites_table = {
-       '<': '&lt;',
-       '>': '&gt;',
-       '&': '&amp;',
-       '"': '&quot;',
-       "`": '&lsquo;',
-       "'": '&rsquo;'
-};
-
-/*
- * Function to convert a supplied string to use HTML/SGML special entitites.
- * This also allows HTML escaping from user-supplied strings.
- */
-function toHTMLEntities(str)
-{
-       var s = '';
-       var i, t, c, e;
-
-       for (i = 0, t = str.length; i < t; i++) {
-               c = str.charAt(i);
-               if ((e = entitites_table[c]) != undefined)
-                       s += e;
-               else
-                       s += c;
-       }
-
-       return s;
-}
-
-
-
-/*
- * This is a parsing test.
- *
- * For now, we want to simply accept patterns in the form %x{...}, where
- * there may be arbitrary data within the { }, and function %x must be
- * performed on it.  For instance, %b{some text} would denote this text
- * as bold.  However, we should also allow %b{some text %i{more text}} and
- * such.  Because %, { and } characters are special, we should support
- * escaping with \.  Because \ is special for escaping, we should support
- * \\ meaning a single \.  Unclosed } should either generate an error,
- * or we might want to automatically consider them all closed at the end
- * of the user provided string.
- *
- * XXX One level currently seems to work, but there are recursive problems!
- * Also, we are loosing a space.
- */
-
-function tokenize(str, ctag, i)
-{
-       var t, c;
-       var escaped = false;
-       var tags = new MLTag(null, false);
-       var ss = '';
-
-       if (ctag != undefined) {
-               if (str.length < i || str.charAt(i) != '{')
-                       return tags;
-               i++;
-       } else
-               i = 0;
-
-       for (t = str.length; i < t; i++) {
-               c = str.charAt(i);
-
-               /* Handle '\' escaping, valid for the whole string */
-               if (escaped &&
-                   (c == '\\' || c == '%' || c == '{' || c == '}')) {
-                       ss += c;
-                       escaped = false;
-                       continue;
-               }
-               if (c == '\\') {
-                       escaped = true;
-                       continue;
-               }
-
-               /*
-                * Special character which delimits commands strings. Since
-                * we are recursively called we must detect this condition and
-                * exit just like for the end of string.
-                */
-               if (c == '{' || c == '}' && ctag == undefined) {
-                       ss += c;
-                       continue;
-               }
-               if (c == '}') {
-//                     i++;    /* XXX */
-                       break;
-               }
-
-               /*
-                * Command mode.  Make sure that we do have a command name,
-                * followed with required '{'.  If an invalid command, simply
-                * allow enclosed string to be litteral.  For valid commands,
-                * create the required tag and recurse into ourselves on the
-                * enclosed string in '{' and '}'.
-                */
-               /* Command mode */
-               if (c == '%') {
-                       var ntag, o;
-
-                       if (/*ctag != undefined ||*/ i > t - 1 ||
-                           str.charAt(i + 2) != '{') {
-                               ss += c;
-                               continue;
-                       }
-
-                       /* Flush current string if any */
-                       if (ss.length > 0) {
-                               tags.addContent(ss);
-                               ss = '';
-                       }
-
-                       switch (str.charAt(i + 1)) {
-                       case 'b':
-                               ntag = new MLTag('b', true);
-                               break;
-                       case 'i':
-                               ntag = new MLTag('i', true);
-                               break;
-                       case 'e':
-                               ntag = new MLTag('em', true);
-                               break;
-                       case 'S':
-                               ntag = new MLTag('sup', true);
-                               break;
-                       case 's':
-                               ntag = new MLTag('sub', true);
-                               break;
-                       case 't':
-                               ntag = new MLTag('tt', true);
-                               break;
-                       case 'h':
-                               ntag = new MLTag('h', true);
-                               break;
-                       case 'p':
-                               ntag = new MLTag('p', true);
-                               break;
-                       case 'n':
-                               ntag = new MLTag('br', false);
-                               break;
-                       case 'A':
-                               ntag = new MLTag('a', true);
-                               break;
-                       case 'I':
-                               ntag = new MLTag('img', true);
-                               break;
-                       default:
-                               ntag = new MLTag(null, false);
-                       }
-
-                       o = tokenize(str, ntag, i + 2);
-                       i = o.i;
-                       /* XXX */
-                       ntag.addContent(o.tags.toStr(0));
-                       tags.addContent(ntag);
-                       continue;
-               }
-
-               ss += c;
-       }
-
-       /*
-        * Now that we gathered command-enclosed string, take care of special
-        * cases for <a> and <img>, and add resulting content.
-        */
-       if (ctag != undefined) {
-               switch (ctag.tag) {
-               case 'a':
-                       ctag.addAttr('href', ss);
-                       break;
-               case 'img':
-                       ctag.addAttr('src', ss);
-                       break;
-               }
-               if (ss.length > 0) {
-                       ctag.addContent(ss);
-                       ss = '';
-               }
-               tags.addContent(ctag);
-       }
-       if (ss.length > 0)
-               tags.addContent(ss);
-
-       /*
-        * Return object with current index in string, as well as new tag
-        * container
-        */
-       var obj = {};
-       obj.i = i;
-       obj.tags = tags;
-
-       return obj;
-}
-
-
-//print((tokenize('Some %b{enclosed} string', undefined, 0)).tags.toStr(0));
-print((tokenize('Some %b{enclo%i{s}ed} string', undefined, 0)).tags.toStr(0));
-//print(uneval((tokenize('Some %b{enclo%i{s}ed} string', undefined, 0)).tags));
diff --git a/tests/js-test/js/poll_test.js b/tests/js-test/js/poll_test.js
deleted file mode 100644 (file)
index ba04111..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* $Id: poll_test.js,v 1.3 2005/02/13 09:02:06 mmondor Exp $ */
-
-function events(e)
-{
-       s = new String();
-
-       if (e & FD.POLLIN)
-               s += 'POLLIN ';
-       if (e & FD.POLLOUT)
-               s += 'POLLOUT ';
-       if (e & FD.POLLERR)
-               s += 'POLLERR ';
-       if (e & FD.POLLHUP)
-               s += 'POLLHUP ';
-       if (e & FD.POLLNVAL)
-               s += 'POLLNVAL ';
-
-       return s;
-}
-
-output = new FD();
-output.set(FD.STDOUT_FILENO);
-
-try {
-
-       input = new FD();
-       input.set(FD.STDIN_FILENO);
-
-       set = new Array();
-
-       /*
-        * This is interesting, because we allow normal arrays, either dense
-        * using set.push(), or sparse using set[n] = fd, but we also allow
-        * associative array elements such as set['string'] = fd.  The
-        * returned set only holds FD objects for which events occurred.  One
-        * can run through that resulting set using for (v in a) ... format,
-        * but it is also possible to verify the associative string name to
-        * see if it is in the set.  As usual with poll(2), POLLHUP, POLLERR
-        * and POLLNVAL are always possible even for descriptor objects with
-        * their events property set to 0.  The default events property for
-        * an FD object is also 0.  The user can then verify the revents
-        * property of each FD object in the result set, and take appropriate
-        * I/O action or processing.
-        *
-        * Moreover, JavaScript being a very dynamic language, one can add
-        * properties or methods to individual FD objects as wanted, and of
-        * course can use those to say, process events of the descriptors
-        * returned in the set with pending events.  This means that a common
-        * method name with different functionality added to each FD object
-        * permits a main events loop to transparently execute the wanted code
-        * using, for instance, fd.process().  In a case where two types of
-        * common events, input and output need to be processed differently
-        * with such a method, one can even define new methods as a prototype
-        * for base custom FD objects, which can be automatically inherited
-        * in shared mode by all children objects derived from the prototype
-        * object.
-        */
-
-       /*
-        * Set interesting events mask for our FD objects to monitor
-        */
-       input.events = FD.POLLIN;
-       output.events = 0;
-
-       /*
-        * Add our FD objects to an array
-        */
-       set.push(input);
-       set.push(output);
-
-       /*
-        * Invoke poll(2) on descriptors in our FD objects array, sleep for a
-        * maximum of 5000 milliseconds (5 seconds).  Retreive result set of
-        * FD objects with pending events into rset.
-        */
-       rset = FD.poll(set, 5000);
-
-       /*
-        * Display rset contents
-        */
-       output.put('Set size: ' + rset.length + "\n");
-       for (var i in rset) {
-               output.put(i + ': type=' + rset[i].constructor.name + ' fd=' +
-                   rset[i].fd + ' revents=' + events(rset[i].revents) + "\n");
-       }
-
-       input.close();
-
-} catch (x) {
-       output.put(x + "\n");
-}
-
-output.close();
diff --git a/tests/js-test/js/sock_httpd.js b/tests/js-test/js/sock_httpd.js
deleted file mode 100644 (file)
index d12533b..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/* $Id: sock_httpd.js,v 1.8 2005/06/28 00:19:03 mmondor Exp $ */
-
-/*
- * Little example showing the versatility of ECMAScript, provided with a
- * custom library for BSD socket support, using SpiderMonkey.
- * This tiny HTTPd allows simultaneous concurrent client connections without
- * using multiple threads or processes.  Must be ran through ../src/test,
- * compiled with ../src/classes/js_fd.[ch] support.
- *
- * We support a maximum of 4 concurrent connections per IP address, as well
- * as a total maximum of 32 concurrent connections by default.
- * Change MAX_CONNECTIONS and MAX_CONNECTIONS_ADDR as needed.
- *
- * We also support per-connection request timeouts, defaulting to 60 seconds.
- * Change REQUEST_TIMEOUT as wanted.
- * Note that this timeout consists of a total timeout for the connection,
- * rather than an actual input timeout (which would require to reset the
- * expiration time everytime user input occurs).  Using the current timeout
- * method suits most embedded applications, but would not be adequate to
- * support large file transfers or the like (connection would timeout
- * during a long transfer).  However, if we supported this kind of long
- * file transfers, because we are single-threaded, we would need two states
- * in our machine, one where small requests take place, and another
- * specialized for ongoing file transfers.  Although this could be
- * implemented, it was not a required functionality for this demonstration.
- */
-
-
-
-/*
- * Configuration
- */
-const MAX_CONNECTIONS          = 32;
-const MAX_CONNECTIONS_ADDR     = 4;
-const REQUEST_TIMEOUT          = 60;
-
-
-
-/*
- * Open standard error FD for diagnostics output
- */
-err = new FD();
-err.set(FD.STDERR_FILENO);
-
-
-/*
- * Initialize server
- */
-try {
-       sock = new FD();
-       sock.socket(FD.AF_INET, FD.SOCK_STREAM, 0);
-       sock.bind('127.0.0.1', 1337);
-       sock.listen(MAX_CONNECTIONS);
-} catch (x) {
-       err.put(x + "\n");
-       exit();
-}
-
-
-/*
- * Create polling array set and insert bound socket in it
- */
-var set = [];
-sock.events = FD.POLLIN;
-set['bind'] = sock;
-
-
-
-/*
- * Used for unique index associated to each FD for efficient removal from
- * polling set when closing connection
- */
-var count = 0;
-
-
-/*
- * To know how many connections we are currently serving and limit them
- */
-var connections = 0;
-var addresses = [];
-
-function counters_inc(fd)
-{
-       if (connections >= MAX_CONNECTIONS)
-               return false;
-
-       var addr = fd.client_addr;
-       if ((addrcnt = addresses[addr]) != undefined &&
-           addrcnt >= MAX_CONNECTIONS_ADDR)
-               return false;
-
-       if (addrcnt == undefined)
-               addrcnt = 1;
-       else
-               addrcnt++;
-       addresses[addr] = addrcnt;
-
-       return true;
-}
-
-function counters_dec(fd)
-{
-       var addr = fd.client_addr;
-       if ((--addresses[addr]) == 0)
-               delete addresses[addr];
-
-       connections--;
-}
-
-
-/*
- * Handles client request and replies back
- */
-function handle_request(fd)
-{
-       try {
-               fd.put(
-                   "HTTP/1.1 200\r\n" +
-                   "Content-type: text/html\r\n" +
-                   "Server: js/1\r\n" +
-                   "Connection: close\r\n" +
-                   "\r\n" +
-                   "<HTML><HEAD><TITLE>Detected!</TITLE></HEAD>\n" +
-                   "<BODY><PRE>\n" +
-                   "You are: " + fd.client_addr + ":" + fd.client_port +
-                   "\n" + "ID: " + fd.index + "\n\n" +
-                   "You sent:\n" + fd.request + "\n" +
-                   "</PRE>\n" + "<P>Tracing in progress...</P>\n" +
-                   "</BODY></HTML>\r\n");
-       } catch (x) {}
-}
-
-
-/*
- * Main server loop
- */
-for (;;) {
-       try {
-
-               /*
-                * Determine next to expire FD event, so that we can sleep
-                * as long as possible.  Also get rid of expired requests.
-                */
-               var cur = Date.parse(new Date) / 1000;
-               var exp = cur + 3600;
-               for (i in set) {
-                       var fd;
-
-                       if ((fd = set[i]) == undefined || i == 'bind')
-                               continue;
-                       if (fd.expires <= cur) {
-                               /*
-                                * Request timeout expired for this
-                                * descriptor, we must close it.
-                                */
-                               fd.close();
-                               counters_dec(fd);
-                               delete set[fd.index];
-                               delete fd;
-                               continue;
-                       }
-                       if (fd.expires < exp)
-                               exp = fd.expires;
-               }
-               exp -= cur;
-
-               /*
-                * Poll our set of descriptors for events
-                */
-               var e = FD.poll(set, exp * 1000);
-               /*
-                * Verify if a timeout occurred.  Because our poll
-                * implementation returns an array, its timeout event can be
-                * checked against by verifying if the set is empty.  However,
-                * associative-array/object-attributes are not accounted
-                * properly with 'length' in JS, so also test fo the case of
-                * the 'bind' entry.
-                */
-               if (e.length == 0 && e['bind'] == undefined) {
-                       /* Timeout */
-                       continue;
-               }
-
-               /*
-                * Process occurred events.  First handle new connections,
-                * if any.
-                */
-               if (e['bind'] != undefined) {
-                       /*
-                        * New connection, accept it
-                        */
-                       var fd = sock.accept();
-
-                       if (!counters_inc(fd)) {
-                               fd.put("HTTP/1.1 403.9\r\n" + 
-                                   "Connection: close\r\n\r\n");
-                               fd.close();
-                               delete fd;
-                       } else {
-                               /*
-                                * Associate a new string with FD object
-                                * which will serve to hold the client request
-                                */
-                               fd.request = '';
-                               /*
-                                * We add this custom property to efficiently
-                                * be able to remove FD from polling set later
-                                * on
-                                */
-                               count++;
-                               fd.index = count;
-                               /*
-                                * Set its interesting polling event to
-                                * POLLIN
-                                */
-                               fd.events = FD.POLLIN;
-                               /*
-                                * Also set request expiration time
-                                */
-                               fd.expires = (Date.parse(new Date) / 1000) +
-                                   REQUEST_TIMEOUT;
-                               /*
-                                * Add descriptor to polling set
-                                */
-                               set[count] = fd;
-                       }
-               }
-
-               /*
-                * Run through set of descriptors with pending events
-                */
-               for (i in e) {
-                       if (e[i] == undefined || i == 'bind')
-                               continue;
-                       if ((e[i].revents & (FD.POLLHUP | FD.POLLERR)) != 0) {
-                               /*
-                                * Unexpected connection loss, close and
-                                * remove from polling set.
-                                */
-                               e[i].close();
-                               counters_dec(e[i]);
-                               delete set[e[i].index];
-                               delete e[i];
-                       } else if ((e[i].revents & FD.POLLIN) != 0) {
-                               var l, close = false;
-
-                               /*
-                                * New data to read from this FD, add to
-                                * request string, verify if we should answer
-                                * and close connection.
-                                * We also limit the maximum request length.
-                                */
-                               if ((l = e[i].get()) != null) {
-                                       if (e[i].length > 32768)
-                                               close = true;
-                                       else
-                                               e[i].request += l;
-                                       if (e[i].request.search("\r\n\r\n")
-                                           != -1)
-                                               close = true;
-                               } else
-                                       close = true;
-
-                               if (close) {
-                                       /*
-                                        * Answer and close connection
-                                        */
-                                       handle_request(e[i]);
-                                       e[i].close();
-                                       counters_dec(e[i]);
-                                       /*
-                                        * Nice feature, we can hint the
-                                        * GC about the fact that we no
-                                        * longer refer to, or want these,
-                                        * which saves RAM since it avoids
-                                        * caching many old useless objects.
-                                        */
-                                       delete set[e[i].index];
-                                       delete e[i];
-                               }
-                       }
-               }
-       } catch (x) {
-               err.put(x + "\n");
-       }
-}
-
-
-/* NOTREACHED */
-
-sock.close();
-err.close();
diff --git a/tests/js-test/js/sock_listen.js b/tests/js-test/js/sock_listen.js
deleted file mode 100644 (file)
index 55f19e1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* $Id: sock_listen.js,v 1.4 2005/04/20 08:50:06 mmondor Exp $ */
-
-err = new FD();
-err.set(FD.STDERR_FILENO);
-
-try {
-       sock = new FD();
-       sock.socket(FD.AF_INET, FD.SOCK_STREAM, 0);
-       sock.bind('127.0.0.1', 1337);
-       sock.listen(10);
-} catch (x) {
-       err.put(x + "\n");
-}
-
-var req = '';
-for (;;) {
-       try {
-               fd = sock.accept();
-               try {
-                       req = '';
-                       while (req.length < 32768) {
-                               if ((l = fd.get()) == null)
-                                       break;
-                               req += l;
-                               if (l.search("\r\n\r\n"))
-                                       break;
-                       }
-                       /*
-                        * Note: because I was asked a few times about this,
-                        * the following is a joke :) we actually don't care
-                        * about the client and won't traceroute, we only
-                        * want client connections to test the program.
-                        */
-                       fd.put("HTTP/1.1 200\r\nServer: js/1\r\n" +
-                           "Connection: close\r\n" + "\r\n");
-                       fd.put("<HTML><HEAD><TITLE>Detected!</TITLE></HEAD>" +
-                           "<BODY><PRE>\n");
-                       fd.put("You are: " + fd.client_addr + ":" +
-                           fd.client_port + "\n\nYou sent:\n" + req + "\n");
-                       fd.put("</PRE>\n" + "<P>Tracing in progress...</P>\n" +
-                           "</BODY></HTML>\r\n");
-               } catch (y) {
-                       err.put(y + "\n");
-               }
-               fd.close();
-       } catch (x) {
-               err.put(x + "\n");
-       }
-}
-
-sock.close();
-err.close();
diff --git a/tests/js-test/js/test.js b/tests/js-test/js/test.js
deleted file mode 100644 (file)
index b27fc71..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $Id: test.js,v 1.1 2004/12/27 11:16:15 mmondor Exp $ */
-
-
-/*
- * The following test should not succeed on API class
- */
-
-/* {{ */
-
-/*
-function test(s)
-{
-       API.print(s);
-}
-
-API.test = test;
-API.test("Successfully added method to API class!\n");
-API.test2 = "Successfully added property to API class!\n";
-API.test(API.test2 + "\n");
-*/
-
-/* }} */
-
-
-
-/*
- * These tests should succeed, however.
- */
-
-API.print("API.property1 = " + API.property1 + "\n");
-API.print("API.property2 = " + API.property2 + "\n");
-API.print("API.property3 = " + API.property3 + "\n\n");
-
-/*
- * XXX
- * These fail, even though these are permanent and read/write properties.
- * JS_SealObject() seems to be converting all read/write properties to
- * report an error if setProperty() method is called. However, interestingly
- * enough, read/only properties report no error. However, they obviously
- * are not modified despite attempts to assign them new values.
- */
-API.property1 = 'Hello';
-API.property2 = 911;
-
-/*
- * Following statement should fail, but is simply internally ignored at least
- * (the setProperty() method is not called).
- */
-API.property3 = 'READONLY!';
-
-API.print("API.property1 = " + API.property1 + "\n");
-API.print("API.property2 = " + API.property2 + "\n");
-API.print("API.property3 = " + API.property3 + "\n\n");
-
-
-
-/*
- * Perform a test loop, during which callMe() should be called by the
- * application code, via the break callback handler function.
- */
-for (i = 0; i < 3; i++) {
-       API.print("We are the: " + Date() + "\n");
-       API.print("NetBSD Kernel size is " +
-           (API.fileSize("/netbsd") / 1024 / 1024) + "MB\n");
-       API.print("END\n");
-}
-API.print("\n");
-
-
-
-/*
- * Will be called by our application if we create it
- */
-function callMe(n)
-{
-       API.print("CallMe(" + n + ")!\n");
-}
-
-
-
-/*
- * Interesting feature where we can return a value explicitely, optionally
- */
-10
diff --git a/tests/js-test/js/test2.js b/tests/js-test/js/test2.js
deleted file mode 100644 (file)
index 5cb105e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: test2.js,v 1.4 2005/02/05 08:07:35 mmondor Exp $ */
-
-var file;
-
-try {
-       file = new API.File("/etc/hosts");
-       API.print("File '" + file.path + "' is loaded (" + file.size +
-           ") bytes.\n");
-       file.release();
-} catch (x) {
-       API.print("Exception: " + x + "\n");
-       exit();
-}
-
-API.print("Finishing...\n");
diff --git a/tests/js-test/js/test3.js b/tests/js-test/js/test3.js
deleted file mode 100644 (file)
index c683324..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-function Employee() {
-       this.name = "";
-       this.dept = "general";
-}
-
-function Manager() {
-       this.reports = [];
-}
-Manager.prototype = new Employee;
-
-function WorkerBee() {
-       this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
-function SalesPerson() {
-       this.dept = "sales";
-       this.quota = 100;
-}
-SalesPerson.prototype = new WorkerBee;
-
-function Engineer() {
-       this.dept = "engineering";
-       this.machine = "";
-}
-Engineer.prototype = new WorkerBee;
-
-t = Engineer;
-var eng
-eng = new t();
-API.print(typeof eng + ', ' + eng.constructor.name);
-API.print("\n");
-
-/* Interesting test. Dynamically create properties i0 - i9 */
-list = new Object;
-for (i = 0; i < 10; i++) {
-       c = 'list.i' + i + ' = ' + i * i;
-       eval(c);
-}
-/* And print the values of our i0 - i9 previously created properties. */
-for (i = 0; i < 10; i++) {
-       c = 'API.print(\'' + 'list.i' + i + ' = \' + list.i' + i + ' + "\\n")';
-       eval(c);  
-}
-
-API.print("\nEND\n");
diff --git a/tests/js-test/src/GNUmakefile b/tests/js-test/src/GNUmakefile
deleted file mode 100644 (file)
index 828cfae..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# $Id: GNUmakefile,v 1.9 2006/07/17 08:55:18 mmondor Exp $
-
-#CFLAGS += -g
-CFLAGS += -Wall
-
-JS_CFLAGS := $(shell spidermonkey-config -dc)
-JS_LDFLAGS := $(shell spidermonkey-config -dl)
-
-PG_CFLAGS := $(shell pg_config --cppflags)
-PG_LDFLAGS := $(shell pg_config --ldflags)
-PG_LDFLAGS += -lpq
-
-OBJS := $(addprefix classes/,js_fd.o js_errno.o js_signal.o js_pgsql.o)
-OBJS += js-server.o
-
-CFLAGS += $(JS_CFLAGS) $(PG_CFLAGS) -Iclasses -Wall
-LDFLAGS += $(JS_LDFLAGS) $(PG_LDFLAGS)
-
-
-all: js-server
-
-%.o: %.c
-       cc -c ${CFLAGS} -o $@ $<
-
-js-server: $(OBJS)
-       cc -o $@ -lc ${LDFLAGS} $(OBJS)
-
-clean:
-       rm -f js-server $(OBJS)
diff --git a/tests/js-test/src/classes/js_errno.c b/tests/js-test/src/classes/js_errno.c
deleted file mode 100644 (file)
index af58462..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $Id: js_errno.c,v 1.3 2005/12/12 09:55:15 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Basic UNIX errno services for ECMAScript
- */
-
-
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsapi.h>
-
-
-
-/* Utility macros */
-#define QUEUE_EXCEPTION(s)     do {                                    \
-       JS_SetPendingException(cx,                                      \
-           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
-} while (/* CONSTCOND */0)
-
-
-
-/* Prototypes */
-static JSBool  errno_sm_strerror(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-
-
-/* Actual class parameters */
-static JSClass errno_class = {
-       "Errno", 0, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
-};
-
-/* Provided static methods */
-static JSFunctionSpec errno_smethods[] = {
-       { "strerror", errno_sm_strerror, 1, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-/*
- * Provided static properties.
- * We use these to provide ECMAScript with the ability to use system-specific
- * standard C constant macros without us having to tidiously map them
- * individually, or to require other scripts to be used as headers to define
- * them.  Another possibility would have been to supply these parameters as
- * string, but this would have required even slower remapping because of the
- * parsing and string comparisions.
- * We only include those which we consider necessary for now, others may be
- * added easily as needed, provided that they are added in all three maps.
- * I might perhaps develop macros and/or functions to map all these easily
- * from a single map.
- */
-
-struct property_spec {
-       const char      *name;
-       int             value;
-};
-
-#define SP(n) \
-    { #n, n }
-
-static struct property_spec    errno_sprops[] = {
-       SP(EPERM),
-       SP(ENOENT),
-       SP(EINTR),
-       SP(EIO),
-       SP(ENXIO),
-       SP(EBADF),
-       SP(EACCES),
-       SP(ENOTBLK),
-       SP(EBUSY),
-       SP(EEXIST),
-       SP(EXDEV),
-       SP(ENODEV),
-       SP(ENOTDIR),
-       SP(EISDIR),
-       SP(EINVAL),
-       SP(ENFILE),
-       SP(EMFILE),
-       SP(ENOTTY),
-       SP(ETXTBSY),
-       SP(EFBIG),
-       SP(ENOSPC),
-       SP(ESPIPE),
-       SP(EROFS),
-       SP(EMLINK),
-       SP(EPIPE),
-       SP(EAGAIN),
-       SP(EINPROGRESS),
-       SP(EALREADY),
-       SP(ENOTSOCK),
-       SP(EDESTADDRREQ),
-       SP(EMSGSIZE),
-       SP(EPROTOTYPE),
-       SP(EPROTONOSUPPORT),
-       SP(EOPNOTSUPP),
-       SP(EPFNOSUPPORT),
-       SP(EAFNOSUPPORT),
-       SP(EADDRINUSE),
-       SP(EADDRNOTAVAIL),
-       SP(ENETDOWN),
-       SP(ENETUNREACH),
-       SP(ENETRESET),
-       SP(ECONNABORTED),
-       SP(ECONNRESET),
-       SP(ENOBUFS),
-       SP(EISCONN),
-       SP(ENOTCONN),
-       SP(ESHUTDOWN),
-       SP(ETIMEDOUT),
-       SP(ECONNREFUSED),
-       SP(ELOOP),
-       SP(ENAMETOOLONG),
-       SP(EHOSTDOWN),
-       SP(EHOSTUNREACH),
-       SP(ENOTEMPTY),
-       SP(EDQUOT),
-       SP(ESTALE),
-       SP(ENOLCK),
-       SP(ENOSYS),
-       SP(EFTYPE),
-       SP(ENOMSG),
-       SP(ENOTSUP),
-       SP(ECANCELED),
-       SP(EBADMSG),
-       SP(ENODATA),
-       SP(ETIME),
-
-       { NULL, 0 }
-};
-
-#undef SP
-
-
-
-/*
- * Class control functions
- */
-
-JSObject *
-js_InitErrnoClass(JSContext *cx, JSObject *obj)
-{
-       JSObject                *proto, *ctor;
-       struct property_spec    *sp;
-
-       if ((proto = JS_InitClass(cx, obj, NULL, &errno_class, NULL,
-           0, NULL, NULL, NULL, errno_smethods)) == NULL) {
-               (void) fprintf(stderr, "Error initializing Errno class\n");
-               return NULL;
-       }
-
-       /* Create static properties */
-       if ((ctor = JS_GetConstructor(cx, proto)) == NULL) {
-               (void) fprintf(stderr, "Errno: JS_GetConstructor == NULL\n");
-               return NULL;
-       }
-       for (sp = errno_sprops; sp->name != NULL; sp++) {
-               if (JS_DefineProperty(cx, ctor, sp->name,
-                   INT_TO_JSVAL(sp->value), NULL, NULL,
-                   JSPROP_READONLY | JSPROP_PERMANENT) == JS_FALSE) {
-                       (void) fprintf(stderr,
-                           "Errno: Error defining property %s\n", sp->name);
-                       return NULL;
-               }
-       }
-
-       return proto;
-}
-
-
-
-/*
- * Static properties functions
- */
-
-
-
-/*
- * Static methods
- */
-
-static JSBool
-errno_sm_strerror(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       int             error;
-       JSString        *string;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-       if (!JSVAL_IS_INT(*argv)) {
-               QUEUE_EXCEPTION("Argument not an integer");
-               return JS_FALSE;
-       }
-       error = (int)JSVAL_TO_INT(*argv);
-
-       if ((string = JS_NewStringCopyZ(cx, strerror(error))) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               return JS_FALSE;
-       }
-
-       *rval = STRING_TO_JSVAL(string);
-
-       return JS_TRUE;
-}
diff --git a/tests/js-test/src/classes/js_errno.h b/tests/js-test/src/classes/js_errno.h
deleted file mode 100644 (file)
index 22b69bb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id: js_errno.h,v 1.2 2005/07/19 19:25:44 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSERRNO_H
-#define JSERRNO_H
-
-extern JSObject        *js_InitErrnoClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/classes/js_fd.c b/tests/js-test/src/classes/js_fd.c
deleted file mode 100644 (file)
index e0f8a1a..0000000
+++ /dev/null
@@ -1,1971 +0,0 @@
-/* $Id: js_fd.c,v 1.42 2006/07/11 10:25:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Basic UNIX filedescriptor and BSD sockets services for ECMAScript
- */
-
-/*
- * XXX TODO XXX
- * - Possibly create a byte buffer type
- * - Add path based restrictions to open()
- * - (maybe) add restrictions to bind()
- * - Either add stat() or provide equivalent properties
- * - Enhance exception reports.  Function name should be provided, and
- *   errno should be displayed when wanted. Perhaps that jsfd->error could
- *   also be set automatically when an exception is generated which involves
- *   errno.
- *   - Check JS_ReportError().
- * - Moving finalizer freeing and close() freeing code to a common function
- *   might be a good idea.
- * - Add getnameinfo()/getaddrinfo() ? Or should we transparently allow this
- *   through properties?
- * - Add send()/sendto()/sendmsg(), recv()/recvfrom()/recvmsg() ...
- * - It is possible that we need to verify that obj is instance of FD in all
- *   methods, perhaps.  I.E. consider an FD method assigned on another object.
- * - Add hostname to address and address to hostname resolution facilities
- * - Maybe also add properties for local end address/port of socket
- * - Would be nice to experiment with a fork(2) heh.  If so, if we allow
- *   fcntl(2) close-on-exec flag, we should make sure to mark FD objects as
- *   closed too for an execve(2) wrapper.
- * - popen(2), would probably need to use custom execve(2) wrapper above...
- * - Add support to easily restrict an application's right to functions.
- *   Path and mode sanity checking functions should also be written and their
- *   parameters set on a per-application basis.
- * - Maybe virtual chdir(2)
- * - A stdio FILE extension object might be nice, with stuff like fdopen() to
- *   create one...  This would be most useful for buffered lined based input
- *   and output.  Exporting mmfd library to js might also be nice perhaps,
- *   either as alternative or addition.
- * - mmap(2) - how could I do this without some byte class and associated
- *   methods?  Seems way tricky.
- * - lstat(2), fstat(2)
- * - dup2()
- * - rename(2), unlink(2) etc would be useful, but we need another class
- *   for this (maybe a VFS static class?)  Maybe even something calling
- *   execve(2) and fork(2), those primitives... popen(3) also.
- * - Also opendir(3) and friends wrapper...
- */
-
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <poll.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsapi.h>
-
-#include <js_fd.h>
-
-
-
-/* Utility macros */
-#define QUEUE_EXCEPTION(s)     do {                                    \
-       JS_SetPendingException(cx,                                      \
-           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
-} while (/* CONSTCOND */0)
-
-
-/* Internal representation of FD object */
-typedef struct jsfd {
-       int     fd;
-       int     type;
-       union   {
-               struct {
-                       char                    *path;
-                       int                     flags;
-                       mode_t                  mode;
-               } file;
-               struct {
-                       int                     domain, type, protocol;
-                       struct sockaddr_in      caddr;
-               } socket;
-       } u;
-       /* For polling; Interesting events, and occurred events */
-       short   events, revents;
-       /* Last error for this descriptor */
-       int     error;
-} jsfd_t;
-
-enum jsfd_types {
-       /* Type */
-       JSFD_NONE =     0,              /* Initial */
-       JSFD_STD =      (1 << 1),
-       JSFD_FILE =     (1 << 2),
-       JSFD_SOCKET =   (1 << 3)
-};
-
-/* Used our fd_sm_poll() function */
-struct poll_fdsi {
-       char    *name;  /* Property name or NULL */
-       jsval   fdobj;  /* Pointer to FD object */
-       jsfd_t  *jsfd;  /* Pointer to FD object data */
-};
-
-struct poll_fds {
-       struct pollfd           *entries;       /* Passed to poll(2) */
-       struct poll_fdsi        *info;
-       int                     count, size;
-};
-
-/* Functions arguments types */
-enum jsarg_types {
-       JSAT_INTEGER = 1,
-       JSAT_DOUBLE,
-       JSAT_STRING,
-       JSAT_OBJECT
-};
-
-
-/* Prototypes */
-static JSBool  fd_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static void    fd_finalize(JSContext *, JSObject *);
-
-static JSBool  fd_getProperty(JSContext *, JSObject *, jsval, jsval *);
-static JSBool  fd_setProperty(JSContext *, JSObject *, jsval, jsval *);
-
-static JSBool  fd_m_open(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_set(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_close(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_truncate(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  fd_m_put(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_get(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_socket(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_connect(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_bind(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_listen(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_accept(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_shutdown(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  fd_m_setsockopt(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  fd_m_getsockopt(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  fd_m_fcntl(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_write(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_read(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_fdatasync(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  fd_m_lseek(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_fchmod(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_flock(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_m_fstat(JSContext *, JSObject *, uintN, jsval *, jsval *);
-
-static JSBool  fd_sm_poll(JSContext *, JSObject *, uintN, jsval *, jsval *);
-static JSBool  fd_sm_poll_mkset(JSContext *, jsval *, jsval *, void *);
-
-static JSBool  object_iterate(JSContext *, JSObject *, void *,
-                   JSBool (*)(JSContext *, jsval *, jsval *, void *));
-static int     fd_path_allow(const char *);
-static mode_t  fd_mode_allow(mode_t);
-static int     fd_flags_allow(int);
-static jsfd_t * fd_methods_args_check(JSContext *, JSObject *, const char *,
-                   int, int, jsval *, int);
-
-
-
-/* Actual class parameters */
-static JSClass fd_class = {
-       "FD", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,
-       fd_getProperty, fd_setProperty, JS_EnumerateStub, JS_ResolveStub,
-       JS_ConvertStub, fd_finalize
-};
-
-enum fd_methods_args_enum {
-       FDMA_SET,
-       FDMA_CLOSE,
-       FDMA_TRUNCATE,
-       FDMA_GET,
-       FDMA_SOCKET,
-       FDMA_CONNECT,
-       FDMA_BIND,
-       FDMA_LISTEN,
-       FDMA_ACCEPT,
-       FDMA_SHUTDOWN,
-       FDMA_SETSOCKOPT,
-       FDMA_GETSOCKOPT,
-       FDMA_FCNTL,
-       FDMA_READ,
-       FDMA_WRITE,
-       FDMA_FDATASYNC,
-       FDMA_LSEEK,
-       FDMA_FCHMOD,
-       FDMA_FLOCK,
-       FDMA_FSTAT,
-       FDMA_MAX
-};
-
-static int fd_methods_args_array[FDMA_MAX][6] = {
-       { 1, JSAT_INTEGER },                            /* SET */
-       { 0 },                                          /* CLOSE */
-       { 1, JSAT_DOUBLE },                             /* TRUNCATE */
-       { 0 },                                          /* GET */
-       { 3, JSAT_INTEGER, JSAT_INTEGER, JSAT_INTEGER },/* SOCKET */
-       { 2, JSAT_STRING, JSAT_INTEGER },               /* CONNECT */
-       { 2, JSAT_STRING, JSAT_INTEGER },               /* BIND */
-       { 1, JSAT_INTEGER },                            /* LISTEN */
-       { 0 },                                          /* ACCEPT */
-       { 1, JSAT_INTEGER },                            /* SHUTDOWN */
-       { 2, JSAT_INTEGER, JSAT_INTEGER },              /* SETSOCKOPT */
-       { 1, JSAT_INTEGER },                            /* GETSOCKOPT */
-       { 2, JSAT_INTEGER, JSAT_INTEGER },              /* FCNTL */
-       { 1, JSAT_INTEGER },                            /* READ */
-       { 1, JSAT_STRING },                             /* WRITE */
-       { 0 },                                          /* FDATASYNC */
-       { 2, JSAT_DOUBLE, JSAT_INTEGER },               /* LSEEK */
-       { 1, JSAT_INTEGER },                            /* FCHMOD */
-       { 1, JSAT_INTEGER },                            /* FLOCK */
-       { 0 }                                           /* FSTAT */
-};
-
-/* Provided methods/functions */
-static JSFunctionSpec fd_methods[] = {
-       { "open", fd_m_open, 0, 0, 0 }, /* Variable 2-3 parameters */
-       { "set", fd_m_set, 1, 0, 0 },
-       { "close", fd_m_close, 0, 0, 0 },
-       { "truncate", fd_m_truncate, 1, 0, 0 },
-       { "put", fd_m_put, 1, 0, 0 },
-       { "get", fd_m_get, 0, 0, 0 },
-       { "socket", fd_m_socket, 3, 0, 0 },
-       { "connect", fd_m_connect, 2, 0, 0 },
-       { "bind", fd_m_bind, 2, 0, 0 },
-       { "listen", fd_m_listen, 1, 0, 0 },
-       { "accept", fd_m_accept, 0, 0, 0 },
-       { "shutdown", fd_m_shutdown, 1, 0, 0 },
-       { "setsockopt", fd_m_setsockopt, 2, 0, 0 },
-       { "getsockopt", fd_m_getsockopt, 1, 0, 0 },
-       { "fcntl", fd_m_fcntl, 2, 0, 0 },
-       { "read", fd_m_read, 1, 0, 0 },
-       { "write", fd_m_write, 1, 0, 0 },
-       { "fdatasync", fd_m_fdatasync, 0, 0, 0 },
-       { "lseek", fd_m_lseek, 2, 0, 0 },
-       { "fchmod", fd_m_fchmod, 1, 0, 0 },
-       { "flock", fd_m_flock, 1, 0, 0 },
-       { "fstat", fd_m_fstat, 0, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-/* Provided static methods */
-static JSFunctionSpec fd_smethods[] = {
-       { "poll", fd_sm_poll, 2, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-/* Provided properties */
-enum fd_props {
-       FD_P_PATH = 0,
-       FD_P_FD,
-       FD_P_MODE,
-       FD_P_EVENTS,
-       FD_P_REVENTS,
-       FD_P_ERRNO,
-       FD_P_CLIENT_ADDR,
-       FD_P_CLIENT_PORT,
-       FD_P_MAX
-};
-
-static JSPropertySpec fd_properties[FD_P_MAX + 1] = {
-       { "path", FD_P_PATH, JSPROP_ENUMERATE | JSPROP_READONLY, NULL, NULL },
-       { "fd", FD_P_FD, JSPROP_ENUMERATE | JSPROP_READONLY, NULL, NULL },
-       { "mode", FD_P_MODE, JSPROP_ENUMERATE | JSPROP_READONLY, NULL, NULL },
-       { "events", FD_P_EVENTS, JSPROP_ENUMERATE, NULL, NULL },
-       { "revents", FD_P_REVENTS, JSPROP_ENUMERATE | JSPROP_READONLY, NULL,
-           NULL },
-       { "errno", FD_P_ERRNO, JSPROP_ENUMERATE | JSPROP_READONLY, NULL,
-           NULL },
-       { "client_addr", FD_P_CLIENT_ADDR, JSPROP_ENUMERATE | JSPROP_READONLY,
-           NULL, NULL },
-       { "client_port", FD_P_CLIENT_PORT, JSPROP_ENUMERATE | JSPROP_READONLY,
-           NULL, NULL },
-       { NULL, 0, 0, NULL, NULL }
-};
-
-/*
- * Provided static properties.
- * We use these to provide ECMAScript with the ability to use system-specific
- * standard C constant macros without us having to tidiously map them
- * individually, or to require other scripts to be used as headers to define
- * them.  Another possibility would have been to supply these parameters as
- * string, but this would have required even slower remapping because of the
- * parsing and string comparisions.
- * We only include those which we consider necessary for now, others may be
- * added easily as needed, provided that they are added in all three maps.
- * I might perhaps develop macros and/or functions to map all these easily
- * from a single map.
- */
-
-struct property_spec {
-       const char      *name;
-       int             value;
-};
-
-#define SP(n) \
-    { #n, n }
-
-static struct property_spec    fd_sprops[] = {
-       SP(STDIN_FILENO),
-       SP(STDOUT_FILENO),
-       SP(STDERR_FILENO),
-
-       SP(O_RDONLY),
-       SP(O_WRONLY),
-       SP(O_RDWR),
-       SP(O_APPEND),
-       SP(O_CREAT),
-       SP(O_TRUNC),
-       SP(O_NONBLOCK),
-
-       SP(POLLIN),
-       SP(POLLRDNORM),
-       SP(POLLRDBAND),
-       SP(POLLPRI),
-       SP(POLLOUT),
-       SP(POLLWRNORM),
-       SP(POLLWRBAND),
-       SP(POLLERR),
-       SP(POLLHUP),
-       SP(POLLNVAL),
-
-       SP(SHUT_RD),
-       SP(SHUT_WR),
-       SP(SHUT_RDWR),
-
-       SP(AF_INET),
-       SP(SOCK_STREAM),
-       SP(SOCK_DGRAM),
-
-       SP(SO_REUSEADDR),
-       SP(SO_REUSEPORT),
-       SP(SO_KEEPALIVE),
-       SP(SO_DONTROUTE),
-       SP(SO_LINGER),
-       SP(SO_BROADCAST),
-       SP(SO_OOBINLINE),
-       SP(SO_SNDBUF),
-       SP(SO_RCVBUF),
-       SP(SO_SNDLOWAT),
-       SP(SO_RCVLOWAT),
-       SP(SO_SNDTIMEO),
-       SP(SO_RCVTIMEO),
-       SP(SO_TIMESTAMP),
-       SP(SO_TYPE),
-       SP(SO_ERROR),
-       SP(TCP_NODELAY),
-
-       SP(F_SETFL),
-       SP(F_GETFL),
-
-       SP(SEEK_SET),
-       SP(SEEK_CUR),
-       SP(SEEK_END),
-
-       SP(S_IRWXU),
-       SP(S_IRUSR),
-       SP(S_IWUSR),
-       SP(S_IXUSR),
-       SP(S_IRWXG),
-       SP(S_IRGRP),
-       SP(S_IXGRP),
-       SP(S_IRWXO),
-       SP(S_IROTH),
-       SP(S_IWOTH),
-       SP(S_IXOTH),
-       SP(S_ISUID),
-       SP(S_ISGID),
-       SP(S_ISVTX),
-       SP(S_IFMT),
-       SP(S_IFIFO),
-       SP(S_IFCHR),
-       SP(S_IFDIR),
-       SP(S_IFBLK),
-       SP(S_IFREG),
-       SP(S_IFLNK),
-       SP(S_IFSOCK),
-       SP(S_IFWHT),
-       SP(UF_NODUMP),
-       SP(UF_IMMUTABLE),
-       SP(UF_APPEND),
-       SP(UF_OPAQUE),
-       SP(SF_ARCHIVED),
-       SP(SF_IMMUTABLE),
-       SP(SF_APPEND),
-
-       SP(LOCK_SH),
-       SP(LOCK_EX),
-       SP(LOCK_NB),
-       SP(LOCK_UN),
-
-       { NULL, 0 }
-};
-
-#undef SP
-
-
-
-/*
- * Miscelaneous static globals
- */
-
-/* XXX Should be initialized at main process startup ideally */
-static int     tcp_proto = -1;
-static char    *read_charbuf = NULL;
-static size_t  read_charbuf_size = 0;
-
-
-
-/*
- * Class control functions
- */
-
-JSObject *
-js_InitFDClass(JSContext *cx, JSObject *obj)
-{
-       JSObject                *proto, *ctor;
-       struct property_spec    *sp;
-
-       if ((proto = JS_InitClass(cx, obj, NULL, &fd_class, fd_constructor,
-           0, fd_properties, fd_methods, NULL, fd_smethods))
-           == NULL) {
-               (void) fprintf(stderr, "Error initializing FD class\n");
-               return NULL;
-       }
-
-       /* Create static properties.  Should probably be a function. */
-
-       if ((ctor = JS_GetConstructor(cx, proto)) == NULL) {
-               (void) fprintf(stderr, "FD: JS_GetConstructor == NULL\n");
-               return NULL;
-       }
-       for (sp = fd_sprops; sp->name != NULL; sp++) {
-               if (JS_DefineProperty(cx, ctor, sp->name,
-                   INT_TO_JSVAL(sp->value), NULL, NULL,
-                   JSPROP_READONLY | JSPROP_PERMANENT) == JS_FALSE) {
-                       (void) fprintf(stderr,
-                           "FD: Error defining property %s\n", sp->name);
-                       return NULL;
-               }
-       }
-
-       return proto;
-}
-
-static JSBool
-fd_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t  *jsfd = NULL;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-
-       /*
-        * IMPORTANT: We must verify if the caller attempts to execute us as a
-        * normal function rather than as a constructor.  Otherwise, the
-        * caller can cause the interpreter to abort(3) in an assertion in
-        * JS_SetPrivate()!
-        */
-       if (!JS_IsConstructing(cx)) {
-               QUEUE_EXCEPTION("Constructor called as a function");
-               goto err;
-       }
-
-       if ((jsfd = JS_malloc(cx, sizeof(jsfd_t))) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-
-       jsfd->fd = -1;
-       jsfd->type = JSFD_NONE;
-       jsfd->events = jsfd->revents = 0;
-       jsfd->error = 0;
-
-       if (!JS_SetPrivate(cx, obj, jsfd)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (jsfd != NULL)
-               JS_free(cx, jsfd);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-       return JS_FALSE;
-}
-
-static void
-fd_finalize(JSContext *cx, JSObject *obj)
-{
-       jsfd_t  *jsfd;
-
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) != NULL) {
-               /* Only close if not one of std descriptors */
-               if (jsfd->fd != -1 && jsfd->type != JSFD_STD) {
-                       (void) close(jsfd->fd);
-                       jsfd->fd = -1;
-                       jsfd->type = JSFD_NONE;
-               }
-               if (jsfd->type == JSFD_FILE && jsfd->u.file.path != NULL) {
-                       JS_free(cx, jsfd->u.file.path);
-                       jsfd->u.file.path = NULL;
-               }
-               JS_free(cx, jsfd);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-}
-
-
-/*
- * Property functions
- */
-
-static JSBool
-fd_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
-       jsfd_t  *jsfd;
-       jsint   p;
-
-       if (!JSVAL_IS_INT(id))
-               return JS_TRUE;
-       p = (int)JSVAL_TO_INT(id);
-
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) == NULL)
-               return JS_TRUE;
-       if (jsfd->fd == -1)
-               return JS_TRUE;
-
-       switch (p) {
-       case FD_P_PATH:
-               if (jsfd->type == JSFD_FILE) {
-                       JSString        *string;
-
-                       if ((string = JS_NewStringCopyZ(cx,
-                           jsfd->u.file.path)) == NULL) {
-                               QUEUE_EXCEPTION("Out of memory");
-                               return JS_FALSE;
-                       }
-                       *vp = STRING_TO_JSVAL(string);
-               }
-               break;
-       case FD_P_FD:
-               *vp = INT_TO_JSVAL(jsfd->fd);
-               break;
-       case FD_P_MODE:
-               if (jsfd->type == JSFD_FILE)
-                       *vp = INT_TO_JSVAL((int)jsfd->u.file.mode);
-               break;
-       case FD_P_EVENTS:
-               *vp = INT_TO_JSVAL((int)jsfd->events);
-               break;
-       case FD_P_REVENTS:
-               *vp = INT_TO_JSVAL((int)jsfd->revents);
-               break;
-       case FD_P_ERRNO:
-               *vp = INT_TO_JSVAL(jsfd->error);
-               break;
-       case FD_P_CLIENT_ADDR:
-               if (jsfd->type == JSFD_SOCKET) {
-                       char            addr[16];
-                       JSString        *string;
-
-                       if (inet_ntop(AF_INET, &jsfd->u.socket.caddr.sin_addr,
-                           addr, 15) == NULL) {
-                               QUEUE_EXCEPTION(strerror(errno));
-                               return JS_FALSE;
-                       }
-                       if ((string = JS_NewStringCopyZ(cx, addr)) == NULL) {
-                               QUEUE_EXCEPTION("Out of memory");
-                               return JS_FALSE;
-                       }
-                       *vp = STRING_TO_JSVAL(string);
-               }
-               break;
-       case FD_P_CLIENT_PORT:
-               if (jsfd->type == JSFD_SOCKET) {
-                       *vp = INT_TO_JSVAL((int)ntohs(jsfd->
-                           u.socket.caddr.sin_port));
-               }
-               break;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
-       jsfd_t  *jsfd;
-       jsint   p;
-
-       if (!JSVAL_IS_INT(id))
-               return JS_TRUE;
-       p = (int)JSVAL_TO_INT(id);
-
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) == NULL)
-               return JS_TRUE;
-       if (jsfd->fd == -1)
-               return JS_TRUE;
-
-       switch (p) {
-       case FD_P_EVENTS:
-               if (!JSVAL_IS_INT(*vp)) {
-                       QUEUE_EXCEPTION(
-                           "FD_P_EVENTS property requires an int");
-                       return JS_FALSE;
-               }
-               jsfd->events = (short)JSVAL_TO_INT(*vp);
-               break;
-       }
-
-       return JS_TRUE;
-}
-
-
-/*
- * Static properties functions
- */
-
-
-/*
- * Method functions
- */
-
-static JSBool
-fd_m_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       int             fd, flags;
-       mode_t          mode = 0644;
-       char            *bytes;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       /*
-        * We use custom arguments checking here since we can accept both
-        * 2 or 3.
-        */
-       if (argc < 2 || argc > 3) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("First argument must be a string");
-               return JS_FALSE;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Second argument must be an integer");
-               return JS_FALSE;
-       }
-       if (argc == 3 && !JSVAL_IS_INT(argv[2])) {
-               QUEUE_EXCEPTION("Third argument must be an integer");
-               return JS_FALSE;
-       }
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Null private data!");
-               return JS_FALSE;
-       }
-       if (jsfd->type != JSFD_NONE) {
-               QUEUE_EXCEPTION("Descriptor already open");
-               return JS_FALSE;
-       }
-
-       if (argc == 3) {
-               /*
-                * Mode, supplied as an int.
-                */
-               mode = (mode_t)JSVAL_TO_INT(argv[2]);
-               if ((mode = fd_mode_allow(mode)) == (mode_t)-1) {
-                       QUEUE_EXCEPTION("Mode not permitted");
-                       return JS_FALSE;
-               }
-       }
-
-       /*
-        * Flags, provided as an int.
-        */
-       flags = JSVAL_TO_INT(argv[1]);
-       if ((flags = fd_flags_allow(flags)) == -1) {
-               QUEUE_EXCEPTION("Flag not permitted");
-               return JS_FALSE;
-       }
-
-       /* Path, provided as a string */
-       if ((bytes = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]))) == NULL) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-       /* Perform path sanity checking */
-       if (fd_path_allow(bytes) == -1) {
-               QUEUE_EXCEPTION("Invalid path");
-               return JS_FALSE;
-       }
-       if ((jsfd->u.file.path = JS_strdup(cx, bytes)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               return JS_FALSE;
-       }
-
-       /* We can finally attempt to open(2) */
-       if ((fd = open(bytes, flags, mode)) == -1) {
-               jsfd->error = errno;
-               /*
-                * XXX strerror() seems to always need to load up the
-                * nls table file, which is way silly for performance.
-                * This is related to locale stuff, and should be able
-                * to simply be disabled, even.
-                * Since this event occurs often in httpd.js, let's just
-                * output a fixed string for now.
-                * I should actually fix NetBSD libc on this matter.
-                */
-/*             QUEUE_EXCEPTION(strerror(errno));       */
-               QUEUE_EXCEPTION("open() error");
-               JS_free(cx, jsfd->u.file.path);
-               return JS_FALSE;
-       }
-
-       /* Success! */
-       jsfd->fd = fd;
-       jsfd->type = JSFD_FILE;
-       jsfd->u.file.flags = flags;
-       jsfd->u.file.mode = mode;
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_set(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       int32_t         fd;
-       jsfd_t          *jsfd;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "set", FDMA_SET, argc,
-           argv, JSFD_NONE)) == NULL)
-               return JS_FALSE;
-
-       fd = JSVAL_TO_INT(*argv);
-       if (fd < STDIN_FILENO || fd > STDERR_FILENO) {
-               QUEUE_EXCEPTION("Unknown standard descriptor");
-               return JS_FALSE;
-       }
-       jsfd->fd = fd;
-       jsfd->type = JSFD_STD;
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t  *jsfd;
-       int     error;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "close", FDMA_CLOSE, argc,
-           argv, JSFD_STD | JSFD_FILE | JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       if (jsfd->type == JSFD_STD) {
-               jsfd->fd = -1;
-               jsfd->type = JSFD_NONE;
-               return JS_TRUE;
-       }
-
-       if (jsfd->type == JSFD_FILE) {
-               if (jsfd->u.file.path != NULL) {
-                       JS_free(cx, jsfd->u.file.path);
-                       jsfd->u.file.path = NULL;
-               }
-       }
-
-       error = close(jsfd->fd);
-       jsfd->fd = -1;
-       jsfd->type = JSFD_NONE;
-
-       if (error == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_truncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t          *jsfd;
-       off_t           size;
-       jsdouble        dsize;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "truncate", FDMA_TRUNCATE,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       if (!JS_ValueToNumber(cx, *argv, &dsize)) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-       size = (off_t)dsize;
-
-       if (ftruncate(jsfd->fd, size) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_put(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       JSString        *str;
-       char            *bytes;
-       ssize_t         size;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Null private data!");
-               return JS_FALSE;
-       }
-
-       if (jsfd->fd == -1) {
-               QUEUE_EXCEPTION("Descriptor closed");
-               return JS_FALSE;
-       }
-
-       /*
-        * Instead of verifying if supplied value really is a JSString, and
-        * using JSVAL_TO_STRING(), we convert the value to a string in this
-        * case.
-        */
-       if ((str = JS_ValueToString(cx, *argv)) == NULL ||
-           (bytes = JS_GetStringBytes(str)) == NULL) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-
-       size = strlen(bytes);
-       if ((size = write(jsfd->fd, bytes, size)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       *rval = INT_TO_JSVAL((int)size);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_get(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       char            bytes[4096];
-       ssize_t         size;
-       JSString        *string;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "get", FDMA_GET, argc,
-           argv, JSFD_STD | JSFD_FILE | JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       if ((size = read(jsfd->fd, bytes, 4096)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-       if (size == 0)
-               return JS_TRUE;
-
-       if ((string = JS_NewStringCopyN(cx, bytes, size)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               return JS_FALSE;
-       }
-       *rval = STRING_TO_JSVAL(string);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_socket(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       int     domain, type, protocol, error;
-       jsfd_t  *jsfd;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "socket", FDMA_SOCKET,
-           argc, argv, JSFD_NONE)) == NULL)
-               return JS_FALSE;
-
-       domain = (int)JSVAL_TO_INT(argv[0]);
-       type = (int)JSVAL_TO_INT(argv[1]);
-       protocol = (int)JSVAL_TO_INT(argv[2]);
-
-       /* Sanity checking on currently supported protocols */
-       if (domain != AF_INET || (type != SOCK_DGRAM && type != SOCK_STREAM)
-           || protocol != 0) {
-               QUEUE_EXCEPTION("Unsupported protocol");
-               return JS_FALSE;
-       }
-
-       if ((error = socket(domain, type, protocol)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       jsfd->fd = error;
-       jsfd->type = JSFD_SOCKET;
-       jsfd->u.socket.domain = domain;
-       jsfd->u.socket.type = type;
-       jsfd->u.socket.protocol = protocol;
-
-       return JS_TRUE;
-}
-
-/*
- * We currently make this rather simple; If the supplied string doesn't
- * consist of a valid IPv4 address, we simply attempt to resolve it, and on
- * success then attempt connection.
- */
-static JSBool
-fd_m_connect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t                  *jsfd;
-       char                    *address;
-       struct sockaddr_in      sinaddr;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "connect", FDMA_CONNECT,
-           argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       address = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-       if (inet_pton(AF_INET, address, &sinaddr.sin_addr) != 1) {
-               struct hostent  *h;
-
-               /*
-                * Not a valid IPv4 address, consider it as a hostname and
-                * attempt to resolve it.
-                * XXX Note: Not thread safe unless a global mutex/rwlock is
-                * used.  Should use getaddrinfo(3) instead.  Especially if we
-                * someday want to support other address families than
-                * AF_INET.
-                */
-               if ((h = gethostbyname(address)) == NULL) {
-                       jsfd->error = errno;
-                       QUEUE_EXCEPTION("Invalid address or hostname");
-                       return JS_FALSE;
-               }
-               sinaddr.sin_addr.s_addr =
-                   ((struct in_addr *)h->h_addr_list[0])->s_addr;
-       }
-       sinaddr.sin_port = htons((in_port_t)JSVAL_TO_INT(argv[1]));
-
-       if (connect(jsfd->fd, (struct sockaddr *)&sinaddr,
-           sizeof(struct sockaddr_in)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_bind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t                  *jsfd;
-       struct sockaddr_in      sinaddr;
-       char                    *address;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "bind", FDMA_BIND, argc,
-           argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       address = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-       if (inet_pton(AF_INET, address, &sinaddr.sin_addr) != 1) {
-               QUEUE_EXCEPTION("Invalid IP address");
-               return JS_FALSE;
-       }
-       sinaddr.sin_port = htons((in_port_t)JSVAL_TO_INT(argv[1]));
-
-       if (bind(jsfd->fd, (struct sockaddr *)&sinaddr,
-           sizeof(struct sockaddr_in)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_listen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t  *jsfd;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "listen", FDMA_LISTEN,
-           argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       if (listen(jsfd->fd, (int)JSVAL_TO_INT(*argv)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_accept(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t                  *jsfd, *njsfd;
-       int                     sock;
-       struct sockaddr_in      sinaddr;
-       socklen_t               socklen;
-       JSObject                *nobj;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "accept", FDMA_ACCEPT,
-           argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       socklen = sizeof(struct sockaddr_in);
-       if ((sock = accept(jsfd->fd, (struct sockaddr *)&sinaddr, &socklen))
-           == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       /*
-        * Success, create new FD object, fill it and return it.
-        */
-       if ((nobj = JS_ConstructObject(cx, &fd_class, obj, obj)) == NULL) {
-               (void) close(sock);
-               QUEUE_EXCEPTION("Out of resources");
-               return JS_FALSE;
-       }
-       njsfd = JS_GetInstancePrivate(cx, nobj, &fd_class, NULL);
-       njsfd->fd = sock;
-       njsfd->type = JSFD_SOCKET;
-       njsfd->u.socket.domain = jsfd->u.socket.domain;
-       njsfd->u.socket.type = jsfd->u.socket.type;
-       njsfd->u.socket.protocol = jsfd->u.socket.protocol;
-       (void) memcpy(&njsfd->u.socket.caddr, &sinaddr,
-           sizeof(struct sockaddr_in));
-
-       *rval = OBJECT_TO_JSVAL(nobj);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_shutdown(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t  *jsfd;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "shutdown", FDMA_SHUTDOWN,
-           argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       if (shutdown(jsfd->fd, (int)JSVAL_TO_INT(*argv)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-/*
- * XXX Not thread safe ATM as it uses a static int with test-and-set operation
- * to only query the protocol database once.  This could be done at early
- * process initialization alternatively.
- * Unlike BSD/POSIX setsockopt(2), always requires a single integer value (-1
- * in the case of SO_LINGER to disable it, or the number of seconds to
- * linger to enable it).
- */
-static JSBool
-fd_m_setsockopt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t          *jsfd;
-       void            *opt;
-       struct linger   l;
-       int             optname, level, optval;
-       socklen_t       optlen;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "setsockopt",
-           FDMA_SETSOCKOPT, argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       optname = JSVAL_TO_INT(argv[0]);
-       optval = JSVAL_TO_INT(argv[1]);
-
-       /*
-        * Work out special case for SO_LINGER
-        */
-       if (optname == SO_LINGER) {
-               if (optval == -1) {
-                       l.l_onoff = 0;
-                       l.l_linger = 0;
-               } else {
-                       l.l_onoff = 1;
-                       l.l_linger = optval;
-               }
-               opt = &l;
-               optlen = sizeof(struct linger);
-       } else {
-               opt = &optval;
-               optlen = sizeof(int);
-               optval = (optval != 0 ? 1 : 0);
-       }
-
-       /*
-        * And for TCP_NODELAY which must use tcp_proto as level
-        */
-       if (optname == TCP_NODELAY) {
-               if (tcp_proto == -1) {
-                       struct protoent *pent;
-
-                       if ((pent = getprotobyname("TCP")) != NULL)
-                               tcp_proto = pent->p_proto;
-                       else
-                               tcp_proto = 4;  /* Generally allright */
-               }
-               level = tcp_proto;
-       } else
-               level = SOL_SOCKET;
-
-       if (setsockopt(jsfd->fd, level, optname, opt, optlen) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-/*
- * XXX Not thread safe ATM as it uses a static int with test-and-set operation
- * to only query the protocol database once.  This could be done at early
- * process initialization alternatively.
- * Unlike BSD/POSIX getsockopt(2), always returns a single integer value (-1
- * in the case of SO_LINGER disabled, or the number of seconds assigned to
- * wait if enabled).
- */
-static JSBool
-fd_m_getsockopt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t          *jsfd;
-       void            *opt;
-       struct linger   l;
-       int             i, optname, level, result;
-       socklen_t       optlen;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "getsockopt",
-           FDMA_GETSOCKOPT, argc, argv, JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       optname = JSVAL_TO_INT(*argv);
-
-       /*
-        * Special case for SO_LINGER which expects a structure rather than an
-        * integer
-        */
-       if (optname == SO_LINGER) {
-               opt = &l;
-               optlen = sizeof(struct linger);
-       } else {
-               opt = &i;
-               optlen = sizeof(int);
-       }
-
-       /*
-        * And for TCP_NODELAY which must use TCP protocol number rather than
-        * SOL_SOCKET level
-        */
-       if (optname == TCP_NODELAY) {
-               if (tcp_proto == -1) {
-                       struct protoent *pent;
-
-                       if ((pent = getprotobyname("TCP")) != NULL)
-                               tcp_proto = pent->p_proto;
-                       else
-                               tcp_proto = 4;  /* Generally allright */
-               }
-               level = tcp_proto;
-       } else
-               level = SOL_SOCKET;
-
-       if (getsockopt(jsfd->fd, level, optname, opt, &optlen) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       /*
-        * To simplify the implementation, special case of SO_LINGER result;
-        * We return -1 if lingering is disabled, or otherwise return the
-        * number of seconds it should linger for maximum.
-        */
-       if (optname == SO_LINGER) {
-               if (l.l_onoff != 0)
-                       result = l.l_linger;
-               else
-                       result = -1;
-       } else
-               /*
-                * These are booleans, so ensure proper return value despite
-                * several implementations which return a mask rather than 0/1
-                */
-               result = (i != 0 ? 1 : 0);
-
-       *rval = INT_TO_JSVAL(result);
-
-       return JS_TRUE;
-}
-
-/*
- * Unlike POSIX fcntl(2), only currently supports F_GETFL and F_SETFL along
- * with O_NONBLOCK and O_APPEND.  The flags argument is also mandatory, which
- * will serve as a result mask for F_GETFL or to set wanted flags using
- * F_SETFL.  The previous flags are returned as usual (but will only ever
- * include 0, O_NONBLOCK and/or O_APPEND).
- */
-static JSBool
-fd_m_fcntl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t  *jsfd;
-       int     cmd, flags, error;
-
-       *rval = INT_TO_JSVAL(0);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "fcntl", FDMA_FCNTL,
-           argc, argv, JSFD_FILE | JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       cmd = JSVAL_TO_INT(argv[0]);
-       flags = JSVAL_TO_INT(argv[1]);
-
-       if (cmd != F_GETFL && cmd != F_SETFL) {
-               QUEUE_EXCEPTION("Unimplemented fcntl() command");
-               return JS_FALSE;
-       }
-       flags &= (O_NONBLOCK | O_APPEND);
-       if ((flags & O_NONBLOCK) == 0 && (flags & O_APPEND) == 0) {
-               QUEUE_EXCEPTION("Unimplemented fcntl() flag");
-               return JS_FALSE;
-       }
-
-       if (cmd == F_GETFL) {
-               if ((error = fcntl(jsfd->fd, cmd, NULL)) == -1) {
-                       jsfd->error = errno;
-                       QUEUE_EXCEPTION(strerror(errno));
-                       return JS_FALSE;
-               }
-               error &= flags;
-       } else {
-               if ((error = fcntl(jsfd->fd, cmd, flags)) == -1) {
-                       jsfd->error = errno;
-                       QUEUE_EXCEPTION(strerror(errno));
-                       return JS_FALSE;
-               }
-               error &= (O_NONBLOCK | O_APPEND);
-       }
-
-       *rval = INT_TO_JSVAL(error);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       size_t          size;
-       ssize_t         rsize;
-       JSString        *string;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "read", FDMA_READ,
-           argc, argv, JSFD_FILE | JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       size = (size_t)JSVAL_TO_INT(*argv);
-       if (size < 1) {
-               QUEUE_EXCEPTION("read() requested size smaller than 1");
-               return JS_FALSE;
-       }
-
-       /*
-        * Ensure that our read buffer is ready, and of a large enough size
-        * to accomodate read.
-        */
-       if (read_charbuf_size < size) {
-               if (read_charbuf == NULL) {
-                       /* Never allocated yet, simply allocate */
-                       if ((read_charbuf = malloc(size)) == NULL) {
-                               QUEUE_EXCEPTION("Cannot allocate read buffer");
-                               return JS_FALSE;
-                       }
-               } else {
-                       char    *ptr;
-
-                       /* Buffer too small, attempt to increase it */
-                       if ((ptr = realloc(read_charbuf, size)) == NULL) {
-                               QUEUE_EXCEPTION(
-                                   "Cannot reallocate read buffer");
-                               return JS_FALSE;
-                       }
-                       read_charbuf = ptr;
-               }
-               read_charbuf_size = size;
-       }
-
-       if ((rsize = read(jsfd->fd, read_charbuf, size)) == -1) {
-               /*
-                * XXX Should we really throw an exception, or simply return
-                * an error?  For instance, if using nonblocking mode and
-                * expecting EAGAIN, would using an exception clubber
-                * unnecessarily the code?
-                */
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-       if (size == 0)
-               return JS_TRUE;
-
-       if ((string = JS_NewStringCopyN(cx, read_charbuf, rsize)) == NULL) {
-               QUEUE_EXCEPTION("Couldn't allocate read result string");
-               return JS_FALSE;
-       }
-       *rval = STRING_TO_JSVAL(string);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       ssize_t         rsize;
-       JSString        *str;
-       char            *bytes;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "write", FDMA_WRITE,
-           argc, argv, JSFD_FILE | JSFD_SOCKET)) == NULL)
-               return JS_FALSE;
-
-       str = JSVAL_TO_STRING(*argv);
-       if ((bytes = JS_GetStringBytes(str)) == NULL) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-
-       if ((rsize = write(jsfd->fd, bytes, JS_GetStringLength(str))) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-       *rval = INT_TO_JSVAL((int)rsize);
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_fdatasync(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       jsfd_t          *jsfd;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "fdatasync",
-           FDMA_FDATASYNC, argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       if (fdatasync(jsfd->fd) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_lseek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       off_t           off, newoff;
-       int             whence;
-       jsdouble        doff;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "lseek", FDMA_LSEEK,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       if (!JS_ValueToNumber(cx, argv[0], &doff)) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-       off = (off_t)doff;
-       whence = JSVAL_TO_INT(argv[1]);
-
-       if ((newoff = lseek(jsfd->fd, off, whence)) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       if (!JS_NewDoubleValue(cx, (jsdouble)newoff, rval)) {
-               QUEUE_EXCEPTION("Internal error");
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_fchmod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       mode_t          mode;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "fchmod", FDMA_FCHMOD,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       mode = (mode_t)JSVAL_TO_INT(*argv);
-       if ((mode = fd_mode_allow(mode)) == (mode_t)-1) {
-               QUEUE_EXCEPTION("Mode not permitted");
-               return JS_FALSE;
-       }
-
-       if (fchmod(jsfd->fd, mode) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_flock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       int             op;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "flock", FDMA_FLOCK,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       op = JSVAL_TO_INT(*argv);
-       if (flock(jsfd->fd, op) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       return JS_TRUE;
-}
-
-static JSBool
-fd_m_fstat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       jsfd_t          *jsfd;
-       struct stat     st;
-       JSObject        *array = NULL;
-       jsval           val;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if ((jsfd = fd_methods_args_check(cx, obj, "fstat", FDMA_FSTAT,
-           argc, argv, JSFD_FILE)) == NULL)
-               return JS_FALSE;
-
-       if (fstat(jsfd->fd, &st) == -1) {
-               jsfd->error = errno;
-               QUEUE_EXCEPTION(strerror(errno));
-               return JS_FALSE;
-       }
-
-       /*
-        * Note: We immediately link newly created objects to avoid GC
-        * problems.  For the simplicity of this task we don't need an
-        * additional root to be created using JS_AddRoot(), since *rval
-        * is already rooted.  Moreover, the double objects we create are
-        * immediately added as propery as well.
-        */
-
-       if ((array = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       *rval = OBJECT_TO_JSVAL(array);
-
-#define DEFINE_INT_PROP(n, i)  do {                                    \
-       val = INT_TO_JSVAL((int)(i));                                   \
-       if (!JS_DefineProperty(cx, array, (n), val, NULL, NULL,         \
-           JSPROP_ENUMERATE)) {                                        \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-#define DEFINE_DOUBLE_PROP(n, d) do {                                  \
-       if (!JS_NewDoubleValue(cx, (jsdouble)(d), &val))                \
-               goto err;                                               \
-       if (!JS_DefineProperty(cx, array, (n), val, NULL, NULL,         \
-           JSPROP_ENUMERATE)) {                                        \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-       DEFINE_INT_PROP("st_dev", st.st_dev);
-       DEFINE_INT_PROP("st_ino", st.st_ino);
-       DEFINE_INT_PROP("st_mode", st.st_mode);
-       DEFINE_INT_PROP("st_nlink", st.st_nlink);
-       DEFINE_INT_PROP("st_uid", st.st_uid);
-       DEFINE_INT_PROP("st_gid", st.st_gid);
-       DEFINE_INT_PROP("st_rdev", st.st_rdev);
-       DEFINE_DOUBLE_PROP("st_atime", st.st_atime);
-       DEFINE_DOUBLE_PROP("st_mtime", st.st_mtime);
-       DEFINE_DOUBLE_PROP("st_ctime", st.st_ctime);
-       DEFINE_DOUBLE_PROP("st_size", st.st_size);
-       DEFINE_DOUBLE_PROP("st_blocks", st.st_blocks);
-       DEFINE_INT_PROP("st_blksize", st.st_blksize);
-       DEFINE_INT_PROP("st_flags", st.st_flags);
-       DEFINE_INT_PROP("st_gen", st.st_gen);
-
-#undef DEFINE_INT_PROP
-#undef DEFINE_DOUBLE_PROP
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-
-
-/*
- * Static methods
- */
-
-static JSBool
-fd_sm_poll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
-{
-       struct poll_fds fds;
-       int             nfds, timeout, i;
-       JSObject        *array = NULL;
-       jsint           index;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if (argc != 2) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-
-       /*
-        * First make sure that user supplied object really consists of an
-        * array.
-        */
-       if (!JSVAL_IS_OBJECT(argv[0]) ||
-           !JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) {
-               QUEUE_EXCEPTION("First argument must be Array object");
-               return JS_FALSE;
-       }
-
-       /*
-        * Obtain timeout from argv[1]
-        */
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Second argument must be timeout integer");
-               return JS_FALSE;
-       }
-       timeout = (int)JSVAL_TO_INT(argv[1]);
-
-       /*
-        * Create our pollfd array, iterating through all FD objects of the
-        * user-provided array object.
-        */
-       if ((fds.entries = malloc(sizeof(struct pollfd) * 16)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       if ((fds.info = malloc(sizeof(struct poll_fdsi) * 16)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       fds.count = 0;
-       fds.size = 16;
-       if (!object_iterate(cx, JSVAL_TO_OBJECT(argv[0]), &fds,
-           fd_sm_poll_mkset))
-               goto err;
-
-       /*
-        * Finally perform actual polling
-        */
-       if ((nfds = poll(fds.entries, fds.count, timeout)) == -1) {
-               QUEUE_EXCEPTION(strerror(errno));
-               goto err;
-       }
-
-       /*
-        * Now set FD objects event field and create custom array object to
-        * return to the caller, only holding entries for which events
-        * occurred.
-        * Link object immediately to avoid GC problems or needing
-        * JS_AddRoot().
-        */
-       if ((array = JS_NewArrayObject(cx, 0, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       *rval = OBJECT_TO_JSVAL(array);
-
-       for (i = 0, index = 0; i < fds.count && nfds != 0; i++) {
-               if (fds.entries[i].revents != 0) {
-                       nfds--;
-                       fds.info[i].jsfd->revents = fds.entries[i].revents;
-                       /*
-                        * Add an element if numeric index entry, or a
-                        * property if name based/associative entry.
-                        */
-                       if (fds.info[i].name == NULL) {
-                               if (!JS_DefineElement(cx, array, index++,
-                                   fds.info[i].fdobj, NULL, NULL,
-                                   JSPROP_ENUMERATE)) {
-                                       QUEUE_EXCEPTION("Internal error!");
-                                       goto err;
-                               }
-                       } else {
-                               if (!JS_DefineProperty(cx, array,
-                                   fds.info[i].name, fds.info[i].fdobj, NULL,
-                                   NULL, JSPROP_ENUMERATE)) {
-                                       QUEUE_EXCEPTION("Internal error!");
-                                       goto err;
-                               }
-                       }
-               }
-       }
-
-       free(fds.entries);
-       free(fds.info);
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-       if (fds.entries != NULL)
-               free(fds.entries);
-       if (fds.info != NULL)
-               free(fds.info);
-
-       return JS_FALSE;
-}
-
-static JSBool
-fd_sm_poll_mkset(JSContext *cx, jsval *id, jsval *val, void *udata)
-{
-       struct poll_fds *fds = (struct poll_fds *)udata;
-       JSObject        *o;
-       jsfd_t          *jsfd;
-
-       if (!JSVAL_IS_OBJECT(*val) ||
-           !JS_InstanceOf(cx, (o = JSVAL_TO_OBJECT(*val)), &fd_class, NULL)) {
-               QUEUE_EXCEPTION("Not FD object");
-               return JS_FALSE;
-       }
-       if ((jsfd = JS_GetInstancePrivate(cx, o, &fd_class, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Null private data!");
-               return JS_FALSE;
-       }
-
-       if (fds->count == fds->size) {
-               void    *ptr;
-
-               /* Need to grow entries and names */
-               if ((ptr = realloc(fds->entries,
-                   sizeof(struct pollfd) * fds->size * 2)) == NULL) {
-                       QUEUE_EXCEPTION("Out of memory");
-                       return JS_FALSE;
-               }
-               fds->entries = ptr;
-               if ((ptr = realloc(fds->info,
-                   sizeof(struct poll_fdsi) * fds->size * 2)) == NULL) {
-                       QUEUE_EXCEPTION("Out of memory");
-                       return JS_FALSE;
-               }
-               fds->info = ptr;
-               fds->size *= 2;
-       }
-
-       /*
-        * Add new entry.  If it's a property (associative array entry), also
-        * fill in the name pointer which will be used to recreate the result
-        * array with those names as well.  We set the name to NULL for index
-        * based array entries.
-        */
-       fds->entries[fds->count].fd = jsfd->fd;
-       fds->entries[fds->count].events = jsfd->events;
-       fds->entries[fds->count].revents = 0;
-       if (JSVAL_IS_STRING(*id))
-               fds->info[fds->count].name =
-                  JS_GetStringBytes(JSVAL_TO_STRING(*id));
-       else
-               fds->info[fds->count].name = NULL;
-       fds->info[fds->count].fdobj = *val;
-       fds->info[fds->count++].jsfd = jsfd;
-
-       return JS_TRUE;
-}
-
-
-/*
- * Utility functions
- */
-
-/*
- * Was written to be able to iterate over all elements of an array object,
- * despite being an associated array or not, or a mix of both.  Unfortunately
- * uses marked as private JSIdArray structure.
- * This was needed because arrays are using indexes, while associative arrays
- * are nothing more than an object with its properties.  This function can
- * deal with both.
- */
-static JSBool
-object_iterate(JSContext *cx, JSObject *obj, void *udata,
-    JSBool (*func)(JSContext *, jsval *, jsval *, void *))
-{
-       JSIdArray       *a;
-       jsval           id, val;
-       char            *name;
-       jsint           i;
-       JSBool          ret = JS_FALSE;
-
-       if ((a = JS_Enumerate(cx, obj)) != NULL) {
-               for (i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JSVAL_IS_STRING(id)) {
-                               /*
-                                * Property id is a string, attempt to
-                                * lookup its value by name.
-                                */
-                               name = JS_GetStringBytes(JSVAL_TO_STRING(id));
-                               if (!JS_LookupProperty(cx, obj, name, &val))
-                                       continue;
-                       } else {
-                               /*
-                                * Property id is a number, attempt to
-                                * lookup its array element by index.
-                                */
-                               if (!JS_LookupElement(cx, obj,
-                                   JSVAL_TO_INT(id), &val))
-                                               continue;
-                       }
-                       if (!JSVAL_IS_VOID(val)) {
-                               if (!(ret = func(cx, &id, &val, udata)))
-                                       break;
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-       }
-
-       return ret;
-}
-
-/*
- * Utility function return 0 if user supplied path should be allowed, or -1 if
- * it should be rejected (invalid, or permission denied).  This can for
- * instance be used to restrict the program in a virtual chroot(2)-like jail.
- */
-/* ARGSUSED */
-static int
-fd_path_allow(const char *path)
-{
-       /* XXX */
-
-       return 0;
-}
-
-/* ARGSUSED */
-static mode_t
-fd_mode_allow(mode_t mode)
-{
-       /* XXX */
-
-       return mode;
-}
-
-/* ARGSUSED */
-static int
-fd_flags_allow(int flags)
-{
-       /* XXX */
-
-       return flags;
-}
-
-/*
- * Useful to ensure that a function's arguments are as expected, and to
- * retrieve the private data associated with the FD object.  Implemented to
- * minimize code duplication among common functions.
- */
-static jsfd_t *
-fd_methods_args_check(JSContext *cx, JSObject *obj, const char *fun, int id,
-    int argc, jsval *argv, int type)
-{
-       int     *p = fd_methods_args_array[id], i;
-       char    line[1024];
-       jsfd_t  *jsfd;
-
-       if (*p != argc) {
-               (void) snprintf(line, 1023,
-                   "%s() - Wrong number of arguments (%d), expected %d",
-                   fun, argc, *p);
-               QUEUE_EXCEPTION(line);
-               return NULL;
-       }
-
-       for (p++, i = 0; i < argc; i++) {
-               switch (p[i]) {
-               case JSAT_INTEGER:
-                       if (!JSVAL_IS_INT(argv[i])) {
-                               (void) snprintf(line, 1023,
-                                   "%s() - argument #%d not an integer",
-                                   fun, i + 1);
-                               QUEUE_EXCEPTION(line);
-                               return NULL;
-                       }
-                       break;
-               case JSAT_DOUBLE:
-                       if (!JSVAL_IS_DOUBLE(argv[i]) &&
-                           !JSVAL_IS_INT(argv[i])) {
-                               (void) snprintf(line, 1023,
-                                   "%s() - argument #%d not a double",
-                                   fun, i + 1);
-                               QUEUE_EXCEPTION(line);
-                               return NULL;
-                       }
-                       break;
-               case JSAT_STRING:
-                       if (!JSVAL_IS_STRING(argv[i])) {
-                               (void) snprintf(line, 1023,
-                                   "%s() - argument #%d not a string",
-                                   fun, i + 1);
-                               QUEUE_EXCEPTION(line);
-                               return NULL;
-                       }
-                       break;
-               default:
-                       (void) snprintf(line, 1023,
-                           "%s() - Unexpected argument type #%d",
-                           fun, i + 1);
-                       QUEUE_EXCEPTION(line);
-                       return NULL;
-               }
-       }
-
-       if ((jsfd = JS_GetInstancePrivate(cx, obj, &fd_class, NULL))
-           == NULL) {
-               (void) snprintf(line, 1023, "%s() - NULL private data!", fun);
-               QUEUE_EXCEPTION(line);
-               return NULL;
-       }
-
-       if (type == JSFD_NONE && jsfd->type != JSFD_NONE) {
-               (void) snprintf(line, 1023,
-                   "%s() - Descriptor is already open",
-                   fun);
-               QUEUE_EXCEPTION(line);
-               return NULL;
-       } else 
-               return jsfd;
-
-       if ((jsfd->type & type) == 0) {
-               (void) snprintf(line, 1023,
-                   "%s() - Descriptor is closed or of wrong type",
-                   fun);
-               QUEUE_EXCEPTION(line);
-               return NULL;
-       }
-
-       return jsfd;
-}
diff --git a/tests/js-test/src/classes/js_fd.h b/tests/js-test/src/classes/js_fd.h
deleted file mode 100644 (file)
index 9ef410e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: js_fd.h,v 1.4 2006/07/11 06:45:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSFD_H
-#define JSFD_H
-
-#include <jsapi.h>
-
-extern JSObject        *js_InitFDClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/classes/js_global.c b/tests/js-test/src/classes/js_global.c
deleted file mode 100644 (file)
index c386b11..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $Id: js_global.c,v 1.1 2006/07/22 03:43:09 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Provide a means to set and access global objects and global properties.
- * Basically we can store hashtable objects, which each can store arbitrary
- * String/String tuples, but using shared memory instead of a database.
- * Internally a hash table would also be used to index hash tables by String.
- * There would be a single synchronization lock around the system.
- * We would need to initially work with an allocated buffer of shared memory,
- * which only needed pages are used.  For this, mmpool(3) could be used.
- * A pool of hash tables would be necessary, as well as one for the data
- * pair items.  To be linked among those.
- *
- * I yet have to find a proper interface.  We optionally could have stuff
- * like:
- *
- * Global.getProperty(table, property);
- * Global.setProperty(table, property, string);
- *
- * But would it also be possible to use lazy allocation such that this would
- * be possible, although of course enforcing the same internal behavior:
- *
- * Global.table.property  would be read or set as necessary.
- *
- * Or:
- * table = new Global(tablename);
- * table.prop = 'string';
- * out.put(table.prop + "\n");
- */
-
-
-
-#include <stdint.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsapi.h>
-
-#include <js_global.h>
-
-
-
-#define QUEUE_EXCEPTION(s)     do {                                    \
-       JS_SetPendingException(cx,                                      \
-           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
-} while (/* CONSTCOND */0)
-
-
-
-/*
- * Static prototypes
- */
-static JSBool  global_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static void    global_finalize(JSContext *, JSObject *);
-
-static JSBool  global_getProperty(JSContext *, JSObject *, jsval, jsval *);
-static JSBool  global_setProperty(JSContext *, JSObject *, jsval, jsval *);
-
-
-
-/*
- * Static globals
- */
-
-/* Global class */
-static JSClass pg_class = {
-       "Global", JCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,
-       global_getProperty, global_setProperty, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, global_finalize
-};
-
-
-
-/*
- * Global object control
- */
-
-JSObject *
-js_InitGlobalClass(JSContext *cx, JSObject *obj)
-{
-       JSObject                *proto, *ctor;
-       struct property_spec    *sp;
-
-       if ((proto = JS_InitClass(cx, obj, NULL, &global_class,
-           global_constructor, 0, NULL, NULL, NULL, NULL)) == NULL) {
-               (void) fprintf(stderr, "Error initializing Global class\n");
-               goto err;
-       }
-
-       /* XXX Initialize shared memory and lock */
-
-       return proto;
-
-err:
-
-       return NULL;
-}
-
-static JSBool
-global_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-
-       if (!JS_IsConstructing(cx)) {
-               QUEUE_EXCEPTION("Constructor called as a function");
-               goto err;
-       }
-
-       /* XXX */
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-global_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
-
-       /* XXX */
-
-       return JS_TRUE;
-}
-
-static JSBool
-global_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
-{
-
-       /* XXX */
-
-       return JS_TRUE;
-}
diff --git a/tests/js-test/src/classes/js_global.h b/tests/js-test/src/classes/js_global.h
deleted file mode 100644 (file)
index 725ffea..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: js_global.h,v 1.1 2006/07/22 03:43:09 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSGLOBAL_H
-#define JSGLOBAL_H
-
-#include <jsapi.h>
-
-extern JSObject        *js_InitGlobalClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/classes/js_mysql.c b/tests/js-test/src/classes/js_mysql.c
deleted file mode 100644 (file)
index 8126f72..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/* $Id: js_mysql.c,v 1.1 2006/07/09 00:30:30 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
diff --git a/tests/js-test/src/classes/js_mysql.h b/tests/js-test/src/classes/js_mysql.h
deleted file mode 100644 (file)
index c04eee4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id: js_mysql.h,v 1.1 2006/07/09 00:30:30 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSMYSQL_H
-#define JSMYSQL_H
-
-extern JSObject        *js_InitMySQLClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/classes/js_pgsql.c b/tests/js-test/src/classes/js_pgsql.c
deleted file mode 100644 (file)
index e697b99..0000000
+++ /dev/null
@@ -1,3493 +0,0 @@
-/* $Id: js_pgsql.c,v 1.17 2006/07/22 03:22:05 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * XXX TODO XXX
- * - Verify if JS_GetStringLength() really safe to continue using
- * - Perhaps provide simpler replacement functions for query functions
- *   allowing separate parameters to be set (perhaps not necessary considering
- *   that we can provide null to an array).
- * - All functions creating doubles or strings should check if NULL is
- *   returned.  Verify this.
- * - (maybe) make reentrant by causing optimization buffers to be part of
- *   generated objects instances's private data (using structures as necessary
- *   instead of simply wrapping around the native object's pointer
- *   (actually PGconn object).
- * - 28.10. Notice Processing
- *   Either place one(s) that use syslog(3) transparently, or somehow allow
- *   the user to set a custom handler
- * - Large objects API
- * - Compare to PHP library to verify if missing any nice functions ideas
- * - See what to do about the following functions:
- *   - PQgetssl() (returns an SSL object!)
- *   - PQprint() (writes to a supplied FILE *)
- */
-
-
-
-#include <stdint.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsapi.h>
-
-#include <libpq-fe.h>
-
-#include <js_pgsql.h>
-
-
-
-/*
- * PostgreSQL services for ECMAScript
- *
- * NOTES:
- * We create a parent PG object which allows us to store static first-level
- * methods as well as numeric properties required to work with the libpq
- * library.  Almost all other functionality is available through PGconn and
- * PGresult objects afterwards.
- *
- * If supporting the asynchroneous part of the API, it should also be possible
- * for us to return an FD object for a PGconn * so that polling could be used,
- * etc.  Or at least just return the fd int which can be used easily to create
- * an FD object with afterwards by the caller.
- */
-
-
-
-#define QUEUE_EXCEPTION(s)     do {                                    \
-       JS_SetPendingException(cx,                                      \
-           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
-} while (/* CONSTCOND */0)
-
-
-struct property_spec {
-       const char      *name;
-       int             value;
-};
-
-
-
-/*
- * Static prototypes
- */
-static int     buffer_grow(size_t);
-static int     param_grow(int);
-
-static JSBool  pg_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-static JSBool  pg_sm_PQconndefaults(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pg_sm_PQconnectdb(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pg_sm_PQconnectStart(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pg_sm_PQresStatus(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pg_sm_PQunescapeBytea(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-static JSObject        *js_InitPGconnClass(JSContext *, JSObject *);
-static JSBool  pgconn_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static void    pgconn_finalize(JSContext *, JSObject *);
-
-static JSBool  pgconn_m_PQfinish(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQconnectPoll(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQreset(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQresetStart(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQresetPoll(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQdb(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQuser(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQpass(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQhost(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQport(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQtty(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQoptions(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQstatus(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQtransactionStatus(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQparameterStatus(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQprotocolVersion(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQserverVersion(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQerrorMessage(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQsocket(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQbackendPID(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQexec(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQsendQuery(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQexecParams2(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *, int);
-static JSBool  pgconn_m_PQexecParams(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQsendQueryParams(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQprepare2(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *, int);
-static JSBool  pgconn_m_PQprepare(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQsendPrepare(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQexecPrepared2(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *, int);
-static JSBool  pgconn_m_PQexecPrepared(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQsendQueryPrepared(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQmakeEmptyPGresult(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQescapeStringConn(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQescapeByteaConn(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQgetCancel(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQnotifies(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQgetResult(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQconsumeInput(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQisBusy(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQsetnonblocking(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQisnonblocking(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQflush(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQsetErrorVerbosity(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgconn_m_PQtrace(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQuntrace(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQputCopyData(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQputCopyEnd(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgconn_m_PQgetCopyData(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-static JSObject        *js_InitPGresultClass(JSContext *, JSObject *);
-static JSBool  pgresult_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static void    pgresult_finalize(JSContext *, JSObject *);
-
-static JSBool  pgresult_m_PQclear(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQresultStatus(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgresult_m_PQresultErrorMessage(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgresult_m_PQresultErrorField(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgresult_m_PQntuples(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQnfields(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQfname(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQfnumber(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQftable(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQftablecol(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQfformat(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQftype(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQfmod(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQfsize(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQbinaryTuples(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgresult_m_PQgetvalue(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQgetisnull(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQgetlength(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQcmdStatus(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQcmdTuples(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static JSBool  pgresult_m_PQoidValue(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-static JSObject        *js_InitPGcancelClass(JSContext *, JSObject *);
-static JSBool  pgcancel_constructor(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-static void    pgcancel_finalize(JSContext *, JSObject *);
-
-static JSBool  pgcancel_m_PQfreeCancel(JSContext *, JSObject *, uintN,
-                   jsval *, jsval *);
-static JSBool  pgcancel_m_PQcancel(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-
-
-/*
- * Static globals
- */
-
-/*
- * General purpose string buffer (note that this is not thread-safe).
- * Allows to optimize functions such as PQescapeStringConn().
- */
-static char    *buffer = NULL;
-static size_t  buffer_size = 0;
-static Oid     *param_types = NULL;
-static char    **param_values = NULL;
-static int     *param_lengths = NULL;
-static int     *param_formats = NULL;
-static int     param_entries = 0;
-
-/* PG class */
-static JSClass pg_class = {
-       "PG", 0, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub,
-       JS_ConvertStub, JS_FinalizeStub
-};
-
-/* Provided static methods */
-static JSFunctionSpec pg_smethods[] = {
-       { "connDefaults", pg_sm_PQconndefaults, 0, 0, 0 },
-       { "connectDb", pg_sm_PQconnectdb, 1, 0, 0 },
-       { "connectStart", pg_sm_PQconnectStart, 1, 0, 0 },
-       { "resStatus", pg_sm_PQresStatus, 1, 0, 0 },
-       { "unescapeBytea", pg_sm_PQunescapeBytea, 2, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-/* Provided static properties */
-
-#define SP(n) \
-    { #n, n }
-
-static struct property_spec    pg_sprops[] = {
-       SP(PGRES_POLLING_OK),
-       SP(PGRES_POLLING_READING),
-       SP(PGRES_POLLING_WRITING),
-       SP(PGRES_POLLING_FAILED),
-       SP(PGRES_EMPTY_QUERY),
-       SP(PGRES_COMMAND_OK),
-       SP(PGRES_TUPLES_OK),
-       SP(PGRES_COPY_OUT),
-       SP(PGRES_COPY_IN),
-       SP(PGRES_BAD_RESPONSE),
-       SP(PGRES_NONFATAL_ERROR),
-       SP(PGRES_FATAL_ERROR),
-       SP(PG_DIAG_SEVERITY),
-       SP(PG_DIAG_SQLSTATE),
-       SP(PG_DIAG_MESSAGE_PRIMARY),
-       SP(PG_DIAG_MESSAGE_DETAIL),
-       SP(PG_DIAG_MESSAGE_HINT),
-       SP(PG_DIAG_STATEMENT_POSITION),
-       SP(PG_DIAG_INTERNAL_POSITION),
-       SP(PG_DIAG_INTERNAL_QUERY),
-       SP(PG_DIAG_CONTEXT),
-       SP(PG_DIAG_SOURCE_FILE),
-       SP(PG_DIAG_SOURCE_LINE),
-       SP(PG_DIAG_SOURCE_FUNCTION),
-       SP(CONNECTION_OK),
-       SP(CONNECTION_BAD),
-       SP(CONNECTION_STARTED),
-       SP(CONNECTION_MADE),
-       SP(CONNECTION_AWAITING_RESPONSE),
-       SP(CONNECTION_AUTH_OK),
-       SP(CONNECTION_SSL_STARTUP),
-       SP(CONNECTION_SETENV),
-       SP(PQTRANS_IDLE),
-       SP(PQTRANS_ACTIVE),
-       SP(PQTRANS_INTRANS),
-       SP(PQTRANS_INERROR),
-       SP(PQTRANS_UNKNOWN),
-       SP(InvalidOid),
-       SP(PQERRORS_TERSE),
-       SP(PQERRORS_DEFAULT),
-       SP(PQERRORS_VERBOSE),
-       { NULL, 0 }
-};
-
-#undef SP
-
-
-/* PGconn class */
-static JSClass pgconn_class = {
-       "PGConn", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, pgconn_finalize
-};
-
-/* Provided methods/functions */
-static JSFunctionSpec pgconn_methods[] = {
-       { "finish", pgconn_m_PQfinish, 0, 0, 0 },
-       { "connectPoll", pgconn_m_PQconnectPoll, 0, 0, 0 },
-       { "reset", pgconn_m_PQreset, 0, 0, 0 },
-       { "resetStart", pgconn_m_PQresetStart, 0, 0, 0 },
-       { "resetPoll", pgconn_m_PQresetPoll, 0, 0, 0 },
-       { "db", pgconn_m_PQdb, 0, 0, 0 },
-       { "user", pgconn_m_PQuser, 0, 0, 0 },
-       { "pass", pgconn_m_PQpass, 0, 0, 0 },
-       { "host", pgconn_m_PQhost, 0, 0, 0 },
-       { "port", pgconn_m_PQport, 0, 0, 0 },
-       { "tty", pgconn_m_PQtty, 0, 0, 0 },
-       { "options", pgconn_m_PQoptions, 0, 0, 0 },
-       { "status", pgconn_m_PQstatus, 0, 0, 0 },
-       { "transactionStatus", pgconn_m_PQtransactionStatus, 0, 0, 0 },
-       { "parameterStatus", pgconn_m_PQparameterStatus, 1, 0, 0 },
-       { "protocolVersion", pgconn_m_PQprotocolVersion, 0, 0, 0 },
-       { "serverVersion", pgconn_m_PQserverVersion, 0, 0, 0 },
-       { "errorMessage", pgconn_m_PQerrorMessage, 0, 0, 0 },
-       { "socket", pgconn_m_PQsocket, 0, 0, 0 },
-       { "backendPid", pgconn_m_PQbackendPID, 0, 0, 0 },
-       { "exec", pgconn_m_PQexec, 1, 0, 0 },
-       { "sendQuery", pgconn_m_PQsendQuery, 1, 0, 0 },
-       { "execParams", pgconn_m_PQexecParams, 7, 0, 0 },
-       { "sendQueryParams", pgconn_m_PQsendQueryParams, 7, 0, 0 },
-       { "prepare", pgconn_m_PQprepare, 4, 0, 0 },
-       { "sendPrepare", pgconn_m_PQsendPrepare, 4, 0, 0 },
-       { "execPrepared", pgconn_m_PQexecPrepared, 6, 0, 0 },
-       { "sendQueryPrepared", pgconn_m_PQsendQueryPrepared, 6, 0, 0 },
-       { "makeEmptyPGResult", pgconn_m_PQmakeEmptyPGresult, 1, 0, 0 },
-       { "escapeStringConn", pgconn_m_PQescapeStringConn, 1, 0, 0 },
-       { "escapeByteaConn", pgconn_m_PQescapeByteaConn, 1, 0, 0 },
-       { "getCancel", pgconn_m_PQgetCancel, 0, 0, 0 },
-       { "notifies", pgconn_m_PQnotifies, 0, 0, 0 },
-       { "getResult", pgconn_m_PQgetResult, 0, 0, 0 },
-       { "consumeInput", pgconn_m_PQconsumeInput, 0, 0, 0 },
-       { "isBusy", pgconn_m_PQisBusy, 0, 0, 0 },
-       { "setNonBlocking", pgconn_m_PQsetnonblocking, 1, 0, 0 },
-       { "isNonBlocking", pgconn_m_PQisnonblocking, 0, 0, 0 },
-       { "flush", pgconn_m_PQflush, 0, 0, 0 },
-       { "setErrorVerbosity", pgconn_m_PQsetErrorVerbosity, 1, 0, 0 },
-       { "trace", pgconn_m_PQtrace, 0, 0, 0 },
-       { "untrace", pgconn_m_PQuntrace, 0, 0, 0 },
-       { "putCopyData", pgconn_m_PQputCopyData, 1, 0, 0 },
-       { "putCopyEnd", pgconn_m_PQputCopyEnd, 1, 0, 0 },
-       { "getCopyData", pgconn_m_PQgetCopyData, 1, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-
-/* PGresult class */
-static JSClass pgresult_class = {
-       "PGResult", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, pgresult_finalize
-};
-
-/* Provided methods/functions */
-static JSFunctionSpec pgresult_methods[] = {
-       { "clear", pgresult_m_PQclear, 0, 0, 0 },
-       { "resultStatus", pgresult_m_PQresultStatus, 0, 0, 0 },
-       { "resultErrorMessage", pgresult_m_PQresultErrorMessage, 0, 0, 0 },
-       { "resultErrorField", pgresult_m_PQresultErrorField, 1, 0, 0 },
-       { "nTuples", pgresult_m_PQntuples, 0, 0, 0 },
-       { "nFields", pgresult_m_PQnfields, 0, 0, 0 },
-       { "fName", pgresult_m_PQfname, 1, 0, 0 },
-       { "fNumber", pgresult_m_PQfnumber, 1, 0, 0 },
-       { "fTable", pgresult_m_PQftable, 1, 0, 0 },
-       { "fTableCol", pgresult_m_PQftablecol, 1, 0, 0 },
-       { "fFormat", pgresult_m_PQfformat, 1, 0, 0 },
-       { "fType", pgresult_m_PQftype, 1, 0, 0 },
-       { "fMod", pgresult_m_PQfmod, 1, 0, 0 },
-       { "fSize", pgresult_m_PQfsize, 1, 0, 0 },
-       { "binaryTuples", pgresult_m_PQbinaryTuples, 1, 0, 0 },
-       { "getValue", pgresult_m_PQgetvalue, 2, 0, 0 },
-       { "getIsNull", pgresult_m_PQgetisnull, 2, 0, 0 },
-       { "getLength", pgresult_m_PQgetlength, 2, 0, 0 },
-       { "cmdStatus", pgresult_m_PQcmdStatus, 0, 0, 0 },
-       { "cmdTuples", pgresult_m_PQcmdTuples, 0, 0, 0 },
-       { "oidValue", pgresult_m_PQoidValue, 0, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-
-/* PGcancel class */
-static JSClass pgcancel_class = {
-       "PGCancel", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, pgcancel_finalize
-};
-
-/* Provided methods/functions */
-static JSFunctionSpec pgcancel_methods[] = {
-       { "freeCancel", pgcancel_m_PQfreeCancel, 0, 0, 0 },
-       { "cancel", pgcancel_m_PQcancel, 1, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-
-
-static int
-buffer_grow(size_t required)
-{
-       size_t  new;
-       void    *ptr;
-
-       if (required <= buffer_size)
-               return 0;
-
-       for (new = buffer_size; new < required; new *= 2) ;
-
-       if ((ptr = realloc(buffer, new)) == NULL)
-               return -1;
-
-       buffer = ptr;
-       buffer_size = new;
-
-       return 0;
-}
-
-static int
-param_grow(int required)
-{
-       int     new;
-       void    *types, *values, *lengths, *formats;
-
-       if (required <= param_entries)
-               return 0;
-
-       for (new = param_entries; new < required; new *= 2) ;
-
-       if ((types = realloc(param_types, sizeof(Oid) * new)) == NULL ||
-           (values = realloc(param_values, sizeof(char *) * new)) == NULL ||
-           (lengths = realloc(param_lengths, sizeof(int) * new)) == NULL ||
-           (formats = realloc(param_formats, sizeof(int) * new)) == NULL)
-               return -1;
-
-       param_types = types;
-       param_values = values;
-       param_lengths = lengths;
-       param_formats = formats;
-       param_entries = new;
-
-       return 0;
-}
-
-
-/*
- * PG object control
- */
-
-JSObject *
-js_InitPGClass(JSContext *cx, JSObject *obj)
-{
-       JSObject                *proto, *ctor;
-       struct property_spec    *sp;
-
-       if ((proto = JS_InitClass(cx, obj, NULL, &pg_class, pg_constructor, 0,
-           NULL, NULL, NULL, pg_smethods)) == NULL) {
-               (void) fprintf(stderr, "Error initializing PG class\n");
-               goto err;
-       }
-
-       /* Create static properties */
-       if ((ctor = JS_GetConstructor(cx, proto)) == NULL) {
-               (void) fprintf(stderr, "PG: JS_GetConstructor == NULL\n");
-               goto err;
-       }
-       for (sp = pg_sprops; sp->name != NULL; sp++) {
-               if (!JS_DefineProperty(cx, ctor, sp->name,
-                   INT_TO_JSVAL(sp->value), NULL, NULL,
-                   JSPROP_READONLY | JSPROP_PERMANENT)) {
-                       (void) fprintf(stderr,
-                           "PG: Error defining property %s\n", sp->name);
-                       goto err;
-               }
-       }
-
-       /* Initialize PGconn class since we'll need to instanciate it from C */
-       if (js_InitPGconnClass(cx, obj) == NULL) {
-               (void) fprintf(stderr, "PG: InitPGconnClass()\n");
-               goto err;
-       }
-       /* Same for PGresult class */
-       if (js_InitPGresultClass(cx, obj) == NULL) {
-               (void) fprintf(stderr, "PG: InitPGresultClass()\n");
-               goto err;
-       }
-       /* And PGcancel class */
-       if (js_InitPGcancelClass(cx, obj) == NULL) {
-               (void) fprintf(stderr, "PG: InitPGcancelClass()\n");
-               goto err;
-       }
-
-       /*
-        * Note that the following buffers, although allowing optimizations,
-        * cause the functions using them to not be reentrant.  For reentrancy
-        * similar buffers could be attached to the object instances instead.
-        * This would of course however mean a larger memory footprint.
-        * If doing this, we would also need a custom structure for the
-        * private data instead of simply wrapping around the native pointers.
-        */
-
-       /* Allocate an initial general purpose buffer */
-       if ((buffer = malloc(16384)) == NULL) {
-               (void) fprintf(stderr, "PG: malloc()\n");
-               goto err;
-       }
-       buffer_size = 16384;
-
-       /* As well as buffers for the *Params() parameter arrays */
-       if ((param_types = malloc(sizeof(Oid) * 16)) == NULL ||
-           (param_values = malloc(sizeof(char *) * 16)) == NULL ||
-           (param_lengths = malloc(sizeof(int) * 16)) == NULL ||
-           (param_formats = malloc(sizeof(int) * 16)) == NULL) {
-               (void) fprintf(stderr, "PG: malloc()\n");
-               goto err;
-       }
-       param_entries = 16;
-
-       return proto;
-
-err:
-       if (buffer != NULL)
-               free(buffer);
-       if (param_types != NULL)
-               free(param_types);
-       if (param_values != NULL)
-               free(param_values);
-       if (param_lengths != NULL)
-               free(param_lengths);
-       if (param_formats != NULL)
-               free(param_formats);
-
-       return NULL;
-}
-
-/* Non instanciable */
-static JSBool
-pg_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       QUEUE_EXCEPTION("PG class uninstanciable");
-
-       return JS_FALSE;
-}
-
-
-/*
- * PG object static methods
- */
-
-/*
- * Returns an array of objects which each contain the various parameters
- * returned by PQconndefaults().
- * XXX Could be more useful if it returned an object of objects using the
- * keyword as property in the first object level, perhaps.
- */
-static JSBool
-pg_sm_PQconndefaults(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PQconninfoOption        *in = NULL, *p;
-       JSObject                *array = NULL;
-       JSString                *str;
-       int                     i;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-
-       if ((in = PQconndefaults()) == NULL) {
-               QUEUE_EXCEPTION("PQconndefaults() == NULL");
-               goto err;
-       }
-       if ((array = JS_NewArrayObject(cx, 0, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(array);
-
-#define DEFINE_STRING_PROP(n, s)       do {                            \
-       if ((str = JS_NewStringCopyZ(cx, (char *)(s))) == NULL) {       \
-               QUEUE_EXCEPTION("Out of memory!");                      \
-               goto err;                                               \
-       }                                                               \
-       if (!JS_DefineProperty(cx, o, (n), STRING_TO_JSVAL(str), NULL,  \
-           NULL, JSPROP_ENUMERATE)) {                                  \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-#define DEFINE_STRING_PROP2(n, s, l)   do {                            \
-       if ((str = JS_NewStringCopyN(cx, (char *)(s), (l))) == NULL) {  \
-               QUEUE_EXCEPTION("Out of memory!");                      \
-               goto err;                                               \
-       }                                                               \
-       if (!JS_DefineProperty(cx, o, (n), STRING_TO_JSVAL(str), NULL,  \
-           NULL, JSPROP_ENUMERATE)) {                                  \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-#define DEFINE_INT_PROP(n, i)  do {                                    \
-       if (!JS_DefineProperty(cx, array, (n), INT_TO_JSVAL((int)(i)),  \
-           NULL, NULL, JSPROP_ENUMERATE)) {                            \
-               QUEUE_EXCEPTION("Internal error!");                     \
-               goto err;                                               \
-       }                                                               \
-} while (/* CONSTCOND */0)
-
-
-       /* Polulate array with objects */
-       for (i = 0, p = in; p->keyword != NULL; p++, i++) {
-               JSObject        *o;
-
-               if ((o = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
-                       QUEUE_EXCEPTION("Out of memory");
-                       goto err;
-               }
-               /* Root immediately by inserting object into array */
-               if (!JS_DefineElement(cx, array, i, OBJECT_TO_JSVAL(o),
-                   NULL, NULL, JSPROP_ENUMERATE)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-
-               /* Populate object with properties */
-               DEFINE_STRING_PROP("keyword", p->keyword);
-               DEFINE_STRING_PROP("envvar", p->envvar);
-               DEFINE_STRING_PROP("compiled", p->compiled);
-               DEFINE_STRING_PROP("val", p->val);
-               DEFINE_STRING_PROP("label", p->label);
-               DEFINE_STRING_PROP2("dispchar", p->dispchar, 1);
-               DEFINE_INT_PROP("dispsize", p->dispsize);
-       }
-
-#undef DEFINE_STRING_PROP
-#undef DEFINE_STRING_PROP2
-#undef DEFINE_INT_PROP
-
-       PQconninfoFree(in);
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-       if (in != NULL)
-               PQconninfoFree(in);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pg_sm_PQconnectdb(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc = NULL;
-       char            *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-       str = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       if ((o = JS_NewObject(cx, &pgconn_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if ((pgc = PQconnectdb(str)) == NULL) {
-               QUEUE_EXCEPTION("PQconnectdb");
-               goto err;
-       }
-       if (!JS_SetPrivate(cx, o, pgc)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgc != NULL)
-               PQfinish(pgc);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pg_sm_PQconnectStart(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc = NULL;
-       char            *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-       str = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       if ((o = JS_NewObject(cx, &pgconn_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if ((pgc = PQconnectStart(str)) == NULL) {
-               QUEUE_EXCEPTION("PQconnectStart");
-               goto err;
-       }
-       if (!JS_SetPrivate(cx, o, pgc)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgc != NULL)
-               PQfinish(pgc);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pg_sm_PQresStatus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       char    *res;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       res = PQresStatus(JSVAL_TO_INT(argv[0]));
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, res));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: Semantics are different from C PQunescapeBytea() in that it is
- * supplied a single String and that it returns a resulting String, or null on
- * error.  Much easier to work with within ECMAScript this way.
- */
-static JSBool
-pg_sm_PQunescapeBytea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-       JSString        *str;
-       char            *from;
-       size_t          reslen;
-       unsigned char   *res = NULL;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       from = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       if ((res = PQunescapeBytea(from, &reslen)) == NULL) {
-               QUEUE_EXCEPTION("PQescapeByteaConn()");
-               goto err;
-       }
-
-       if ((str = JS_NewStringCopyN(cx, res, reslen)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       PQfreemem(res);
-       *rval = STRING_TO_JSVAL(str);
-
-       return JS_TRUE;
-
-err:
-       if (res != NULL)
-               PQfreemem(res);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-
-/*
- * PGconn object control
- */
-
-static JSObject *
-js_InitPGconnClass(JSContext *cx, JSObject *obj)
-{
-
-       return (JS_InitClass(cx, obj, NULL, &pgconn_class, pgconn_constructor,
-           0, NULL, pgconn_methods, NULL, NULL));
-}
-
-/* Non instanciable */
-static JSBool
-pgconn_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       QUEUE_EXCEPTION("PGconn class not user-instanciable");
-
-       return JS_FALSE;
-}
-
-static void
-pgconn_finalize(JSContext *cx, JSObject *obj)
-{
-       PGconn  *pgc;
-
-       if ((pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL))
-           != NULL) {
-               PQfinish(pgc);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-}
-
-
-/*
- * PGconn object methods
- */
-
-static JSBool
-pgconn_m_PQfinish(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       if ((pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL))
-           != NULL) {
-               PQfinish(pgc);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQconnectPoll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn                          *pgc;
-       PostgresPollingStatusType       s;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       s = PQconnectPoll(pgc);
-       *rval = INT_TO_JSVAL((int)s);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQreset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn                          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       PQreset(pgc);
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQresetStart(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQconnectPoll(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQresetPoll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn                          *pgc;
-       PostgresPollingStatusType       s;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       s = PQresetPoll(pgc);
-       *rval = INT_TO_JSVAL((int)s);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQdb(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQdb(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQuser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQuser(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQpass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQpass(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQhost(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQhost(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQport(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQtty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQtty(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQoptions(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQoptions(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQstatus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-       ConnStatusType  s = CONNECTION_BAD;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       s = PQstatus(pgc);
-       *rval = INT_TO_JSVAL((int)s);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQtransactionStatus(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn                  *pgc;
-       PGTransactionStatusType s;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       s = PQtransactionStatus(pgc);
-       *rval = INT_TO_JSVAL((int)s);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQparameterStatus(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn          *pgc;
-       char            *param;
-       const char      *str;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               return JS_FALSE;
-       }
-       param = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((str = PQparameterStatus(pgc, param)) != NULL)
-               *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQprotocolVersion(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQprotocolVersion(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQserverVersion(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQserverVersion(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQerrorMessage(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-       char    *str;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = PQerrorMessage(pgc);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQsocket(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQsocket(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQbackendPID(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQbackendPID(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQexec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-       char            *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-       str = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if ((pgr = PQexec(pgc, str)) == NULL) {
-               QUEUE_EXCEPTION("PQexec()");
-               goto err;
-       }
-       if (!JS_SetPrivate(cx, o, pgr)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQsendQuery(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-       char            *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-       str = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQsendQuery(pgc, str));
-
-       return JS_TRUE;
-
-err:
-       *rval = INT_TO_JSVAL(0);
-
-       return JS_FALSE;
-}
-
-/*
- * A fairly hairy function.
- */
-static JSBool
-pgconn_m_PQexecParams2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval, int async)
-{
-       int             nargs, i;
-       JSObject        *arrays[4], *o;
-       JSIdArray       *a = NULL;
-       Oid             *types = NULL;
-       char            **values = NULL;
-       int             *lengths = NULL;
-       int             *formats = NULL;
-       char            str[256];
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-
-       if (argc != 7) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not a String");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not an int");
-               goto err;
-       }
-       for (i = 2; i < 6; i++) {
-               if (JSVAL_IS_NULL(argv[i])) {
-                       arrays[i - 2] = NULL;
-                       continue;
-               }
-               if (!JSVAL_IS_OBJECT(argv[i]) ||
-                   !JS_IsArrayObject(cx,
-                   (arrays[i - 2] = JSVAL_TO_OBJECT(argv[i])))) {
-                       (void) snprintf(str, 255, "Argument %d not an Array",
-                           i + 1);
-                       QUEUE_EXCEPTION(str);
-                       goto err;
-               }
-       }
-       if (!JSVAL_IS_INT(argv[6])) {
-               QUEUE_EXCEPTION("Argument 7 not an int");
-               goto err;
-       }
-
-       /* Array arguments processing */
-       nargs = JSVAL_TO_INT(argv[1]);
-       if (nargs < 0) {
-               QUEUE_EXCEPTION("Argument 2 negative");
-               goto err;
-       }
-
-       if (arrays[0] != NULL)
-               types = param_types;
-       if (arrays[1] != NULL)
-               values = param_values;
-       if (arrays[2] != NULL)
-               lengths = param_lengths;
-       if (arrays[3] != NULL)
-               formats = param_formats;
-
-       for (i = 0; i < 4; i++) {
-               jsint   len;
-
-               if (arrays[i] == NULL)
-                       continue;
-
-               if (!JS_GetArrayLength(cx, arrays[i], &len) || len != nargs) {
-                       (void) snprintf(str, 255,
-                           "Argument %d Array not holding %d elements",
-                           i + 2, nargs);
-                       QUEUE_EXCEPTION(str);
-                       goto err;
-               }
-       }
-
-       if (param_grow(nargs) == -1) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       /* param_types */
-       if (types != NULL) {
-               jsval           id, val;
-               int             i2;
-               jsdouble        v;
-
-               o = arrays[0];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_NUMBER(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 3 Array's element %d "
-                                           "not a number", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               if (!JS_ValueToNumber(cx, val, &v)) {
-                                       QUEUE_EXCEPTION("Internal error!");
-                                       goto err;
-                               }
-                               types[i2++] = (Oid)v;
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       /* param_values */
-       if (values != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[1];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (JSVAL_IS_NULL(val)) {
-                                       values[i2++] = NULL;
-                                       continue;
-                               }
-                               if (!JSVAL_IS_STRING(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 4 Array's element %d "
-                                           "not a String", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               values[i2++] = JS_GetStringBytes(
-                                   JSVAL_TO_STRING(val));
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       /* param_lengths */
-       if (lengths != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[2];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_INT(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 5 Array's element %d "
-                                           "not an int", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               lengths[i2++] = JSVAL_TO_INT(val);
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       /* param_formats */
-       if (formats != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[3];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_INT(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 6 Array's element %d "
-                                           "not an int", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               formats[i2++] = JSVAL_TO_INT(val);
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if (!async) {
-
-               if ((pgr = PQexecParams(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   nargs, types, (const char * const *)values, lengths,
-                   formats, JSVAL_TO_INT(argv[6]))) == NULL) {
-                       QUEUE_EXCEPTION("PQexecParams()");
-                       goto err;
-               }
-
-               if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL))
-                   == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               /* Root immediately */
-               *rval = OBJECT_TO_JSVAL(o);
-
-               if (!JS_SetPrivate(cx, o, pgr)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-
-       } else {
-
-               *rval = INT_TO_JSVAL(PQsendQueryParams(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   nargs, types, (const char * const *)values, lengths,
-                   formats, JSVAL_TO_INT(argv[6])));
-
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-       if (a != NULL)
-               JS_DestroyIdArray(cx, a);
-
-       if (!async)
-               *rval = OBJECT_TO_JSVAL(NULL);
-       else
-               *rval = INT_TO_JSVAL(0);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQexecParams(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       return pgconn_m_PQexecParams2(cx, obj, argc, argv, rval, 0);
-}
-
-static JSBool
-pgconn_m_PQsendQueryParams(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-
-       return pgconn_m_PQexecParams2(cx, obj, argc, argv, rval, 1);
-}
-
-static JSBool
-pgconn_m_PQprepare2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval, int async)
-{
-       int             nargs, i;
-       JSObject        *array, *o;
-       JSIdArray       *a = NULL;
-       Oid             *types = NULL;
-       char            str[256];
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-
-       if (argc != 4) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not a String");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not a String");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[2])) {
-               QUEUE_EXCEPTION("Argument 3 not an int");
-               goto err;
-       }
-       if (JSVAL_IS_NULL(argv[3]))
-               array = NULL;
-       else {
-               if (!JSVAL_IS_OBJECT(argv[3]) ||
-                   !JS_IsArrayObject(cx,
-                   (array = JSVAL_TO_OBJECT(argv[3])))) {
-                       QUEUE_EXCEPTION("Argument 4 not an Array");
-                       goto err;
-               }
-       }
-
-       /* Array arguments processing */
-       nargs = JSVAL_TO_INT(argv[2]);
-       if (nargs < 0) {
-               QUEUE_EXCEPTION("Argument 3 negative");
-               goto err;
-       }
-
-       if (array != NULL) {
-               jsint   len;
-
-               types = param_types;
-
-               if (!JS_GetArrayLength(cx, array, &len) || len != nargs) {
-                       (void) snprintf(str, 255,
-                           "Argument 4 Array not holding %d elements",
-                           nargs);
-                       QUEUE_EXCEPTION(str);
-                       goto err;
-               }
-       }
-
-       if (param_grow(nargs) == -1) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       /* param_types */
-       if (types != NULL) {
-               jsval           id, val;
-               int             i2;
-               jsdouble        v;
-
-               o = array;
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_NUMBER(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 4 Array's element %d "
-                                           "not a number", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               if (!JS_ValueToNumber(cx, val, &v)) {
-                                       QUEUE_EXCEPTION("Internal error!");
-                                       goto err;
-                               }
-                               types[i2++] = (Oid)v;
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if (!async) {
-
-               if ((pgr = PQprepare(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[1])),
-                   nargs, types)) == NULL) {
-                       QUEUE_EXCEPTION("PQprepare()");
-                       goto err;
-               }
-
-               if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL))
-                   == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               /* Root immediately */
-               *rval = OBJECT_TO_JSVAL(o);
-
-               if (!JS_SetPrivate(cx, o, pgr)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-
-       } else {
-
-               *rval = INT_TO_JSVAL(PQsendPrepare(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[1])),
-                   nargs, types));
-
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-
-       if (!async)
-               *rval = OBJECT_TO_JSVAL(NULL);
-       else
-               *rval = INT_TO_JSVAL(0);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQprepare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       return pgconn_m_PQprepare2(cx, obj, argc, argv, rval, 0);
-}
-
-static JSBool
-pgconn_m_PQsendPrepare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       return pgconn_m_PQprepare2(cx, obj, argc, argv, rval, 1);
-}
-
-/*
- * Also rather hairy
- */
-static JSBool
-pgconn_m_PQexecPrepared2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval, int async)
-{
-       int             nargs, i;
-       JSObject        *arrays[3], *o;
-       JSIdArray       *a = NULL;
-       char            **values = NULL;
-       int             *lengths = NULL;
-       int             *formats = NULL;
-       char            str[256];
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-
-       if (argc != 6) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not a String");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not an int");
-               goto err;
-       }
-       for (i = 2; i < 5; i++) {
-               if (JSVAL_IS_NULL(argv[i])) {
-                       arrays[i - 2] = NULL;
-                       continue;
-               }
-               if (!JSVAL_IS_OBJECT(argv[i]) ||
-                   !JS_IsArrayObject(cx,
-                   (arrays[i - 2] = JSVAL_TO_OBJECT(argv[i])))) {
-                       (void) snprintf(str, 255, "Argument %d not an Array",
-                           i + 1);
-                       QUEUE_EXCEPTION(str);
-                       goto err;
-               }
-       }
-       if (!JSVAL_IS_INT(argv[5])) {
-               QUEUE_EXCEPTION("Argument 7 not an int");
-               goto err;
-       }
-
-       /* Array arguments processing */
-       nargs = JSVAL_TO_INT(argv[1]);
-       if (nargs < 0) {
-               QUEUE_EXCEPTION("Argument 2 negative");
-               goto err;
-       }
-
-       if (arrays[0] != NULL)
-               values = param_values;
-       if (arrays[1] != NULL)
-               lengths = param_lengths;
-       if (arrays[2] != NULL)
-               formats = param_formats;
-
-       for (i = 0; i < 3; i++) {
-               jsint   len;
-
-               if (arrays[i] == NULL)
-                       continue;
-
-               if (!JS_GetArrayLength(cx, arrays[i], &len) || len != nargs) {
-                       (void) snprintf(str, 255,
-                           "Argument %d Array not holding %d elements",
-                           i + 2, nargs);
-                       QUEUE_EXCEPTION(str);
-                       goto err;
-               }
-       }
-
-       if (param_grow(nargs) == -1) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       /* param_values */
-       if (values != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[0];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (JSVAL_IS_NULL(val)) {
-                                       values[i2++] = NULL;
-                                       continue;
-                               }
-                               if (!JSVAL_IS_STRING(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 3 Array's element %d "
-                                           "not a String", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               values[i2++] = JS_GetStringBytes(
-                                   JSVAL_TO_STRING(val));
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       /* param_lengths */
-       if (lengths != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[1];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_INT(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 4 Array's element %d "
-                                           "not an int", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               lengths[i2++] = JSVAL_TO_INT(val);
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       /* param_formats */
-       if (formats != NULL) {
-               jsval           id, val;
-               int             i2;
-
-               o = arrays[2];
-               if ((a = JS_Enumerate(cx, o)) == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               for (i2 = i = 0; i < a->length; i++) {
-                       JS_IdToValue(cx, a->vector[i], &id);
-                       if (JS_LookupElement(cx, o, JSVAL_TO_INT(id), &val) &&
-                           !JSVAL_IS_VOID(val)) {
-                               if (!JSVAL_IS_INT(val)) {
-                                       (void) snprintf(str, 255,
-                                           "Argument 5 Array's element %d "
-                                           "not an int", i2);
-                                       QUEUE_EXCEPTION(str);
-                                       goto err;
-                               }
-                               formats[i2++] = JSVAL_TO_INT(val);
-                       }
-               }
-               JS_DestroyIdArray(cx, a);
-               a = NULL;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if (!async) {
-
-               if ((pgr = PQexecPrepared(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   nargs, (const char * const *)values, lengths, formats,
-                   JSVAL_TO_INT(argv[5]))) == NULL) {
-                       QUEUE_EXCEPTION("PQexecPrepared()");
-                       goto err;
-               }
-
-               if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL))
-                   == NULL) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               /* Root immediately */
-               *rval = OBJECT_TO_JSVAL(o);
-
-               if (!JS_SetPrivate(cx, o, pgr)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-
-       } else {
-
-               *rval = INT_TO_JSVAL(PQsendQueryPrepared(pgc,
-                   JS_GetStringBytes(JSVAL_TO_STRING(argv[0])),
-                   nargs, (const char * const *)values, lengths, formats,
-                   JSVAL_TO_INT(argv[5])));
-
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-       if (a != NULL)
-               JS_DestroyIdArray(cx, a);
-
-       if (!async)
-               *rval = OBJECT_TO_JSVAL(NULL);
-       else
-               *rval = INT_TO_JSVAL(0);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQexecPrepared(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       return pgconn_m_PQexecPrepared2(cx, obj, argc, argv, rval, 0);
-}
-
-static JSBool
-pgconn_m_PQsendQueryPrepared(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-
-       return pgconn_m_PQexecPrepared2(cx, obj, argc, argv, rval, 1);
-}
-
-static JSBool
-pgconn_m_PQmakeEmptyPGresult(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if ((pgr = PQmakeEmptyPGresult(pgc, JSVAL_TO_INT(argv[0]))) == NULL) {
-               QUEUE_EXCEPTION("PQmakeEmptyPGresult()");
-               goto err;
-       }
-
-       if (!JS_SetPrivate(cx, o, pgr)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: Semantics are different from C PQescapeStringConn() in that it is
- * supplied a single String and that it returns a resulting String, or null on
- * error.  Much easier to work with within ECMAScript this way.
- */
-static JSBool
-pgconn_m_PQescapeStringConn(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn          *pgc;
-       JSString        *str;
-       char            *from;
-       size_t          len;
-       int             ret;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = JSVAL_TO_STRING(argv[0]);
-       from = JS_GetStringBytes(str);
-       len = JS_GetStringLength(str);
-
-       if (buffer_grow((len * 2) + 2) == -1) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       len = PQescapeStringConn(pgc, buffer, from, len, &ret);
-       if (ret != 0) {
-               QUEUE_EXCEPTION("PQescapeStringConn()");
-               goto err;
-       }
-
-       if ((str = JS_NewStringCopyN(cx, buffer, len)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-       *rval = STRING_TO_JSVAL(str);
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/* PQescapeString() deprecated in favor of PQescapeStringConn() */
-
-/*
- * Note: Semantics are different from C PQescapeByteaConn() in that it is
- * supplied a single String and that it returns a resulting String, or null on
- * error.  Much easier to work with within ECMAScript this way.
- */
-static JSBool
-pgconn_m_PQescapeByteaConn(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn          *pgc;
-       JSString        *str;
-       char            *from;
-       size_t          fromlen, reslen;
-       unsigned char   *res = NULL;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = JSVAL_TO_STRING(argv[0]);
-       from = JS_GetStringBytes(str);
-       fromlen = JS_GetStringLength(str);
-
-       if ((res = PQescapeByteaConn(pgc, from, fromlen, &reslen)) == NULL) {
-               QUEUE_EXCEPTION("PQescapeByteaConn()");
-               goto err;
-       }
-
-       if ((str = JS_NewStringCopyN(cx, res, reslen)) == NULL) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-
-       PQfreemem(res);
-       *rval = STRING_TO_JSVAL(str);
-
-       return JS_TRUE;
-
-err:
-       if (res != NULL)
-               PQfreemem(res);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQgetCancel(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       PGcancel        *pgcn = NULL;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((o = JS_NewObject(cx, &pgcancel_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if ((pgcn = PQgetCancel(pgc)) == NULL) {
-               QUEUE_EXCEPTION("PQgetCancel()");
-               goto err;
-       }
-       if (!JS_SetPrivate(cx, o, pgcn)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgcn != NULL)
-               PQfreeCancel(pgcn);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: Unlike C native PQnotifies(), returns null or a normal object with
- * the three properties set, rather than specifically a PQnotify object.
- */
-static JSBool
-pgconn_m_PQnotifies(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       PGnotify        *pgn = NULL;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((pgn = PQnotifies(pgc)) == NULL) {
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_TRUE;
-       }
-
-       if ((o = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if (!JS_DefineProperty(cx, o, "relname", STRING_TO_JSVAL(
-           JS_NewStringCopyZ(cx, pgn->relname)), NULL, NULL,
-           JSPROP_ENUMERATE)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       if (!JS_DefineProperty(cx, o, "be_pid", INT_TO_JSVAL(pgn->be_pid),
-           NULL, NULL, JSPROP_ENUMERATE)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       if (!JS_DefineProperty(cx, o, "extra", STRING_TO_JSVAL(
-           JS_NewStringCopyZ(cx, pgn->extra)), NULL, NULL,
-           JSPROP_ENUMERATE)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       PQfreemem(pgn);
-
-       return JS_TRUE;
-
-err:
-       if (pgn != NULL)
-               PQfreemem(pgn);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQgetResult(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       PGresult        *pgr = NULL;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       if ((pgr = PQgetResult(pgc)) == NULL) {
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_TRUE;
-       }
-
-       if ((o = JS_NewObject(cx, &pgresult_class, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if (!JS_SetPrivate(cx, o, pgr)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       if (pgr != NULL)
-               PQclear(pgr);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQconsumeInput(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQconsumeInput(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQisBusy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQisBusy(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQsetnonblocking(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQsetnonblocking(pgc, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQisnonblocking(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQisnonblocking(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQflush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQflush(pgc));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQsetErrorVerbosity(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGconn  *pgc;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQsetErrorVerbosity(pgc, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQtrace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-       PQtrace(pgc, stderr);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQuntrace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-       PQuntrace(pgc);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgconn_m_PQputCopyData(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-       JSString        *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       str = JSVAL_TO_STRING(argv[0]);
-       *rval = INT_TO_JSVAL(PQputCopyData(pgc, JS_GetStringBytes(str),
-           JS_GetStringLength(str)));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgconn_m_PQputCopyEnd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGconn          *pgc;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0]) && !JSVAL_IS_NULL(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String or null");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       *rval = INT_TO_JSVAL(PQputCopyEnd(pgc, (JSVAL_IS_NULL(argv[0]) ? NULL :
-           JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: unlike native PQgetCopyData(), which returns an int but is supplied a
- * pointer to a pointer to be set, this implementation returns an object which
- * holds two elements: result (the integer) and data (null or String), to make
- * it easier to use with ECMAScript.
- */
-static JSBool
-pgconn_m_PQgetCopyData(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       JSObject        *o;
-       PGconn          *pgc;
-       char            *data = NULL;
-       int             res;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgconn_class, NULL);
-       assert(pgc != NULL);
-
-       res = PQgetCopyData(pgc, &data, JSVAL_TO_INT(argv[0]));
-
-       if ((o = JS_NewObject(cx, NULL, NULL, NULL)) == NULL) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       /* Root immediately */
-       *rval = OBJECT_TO_JSVAL(o);
-
-       if (!JS_DefineProperty(cx, o, "result", INT_TO_JSVAL(res),
-           NULL, NULL, JSPROP_ENUMERATE)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-       if (data != NULL && res > 0) {
-               if (!JS_DefineProperty(cx, o, "data", STRING_TO_JSVAL(
-                   JS_NewStringCopyN(cx, data, res)), NULL, NULL,
-                   JSPROP_ENUMERATE)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-               PQfreemem(data);
-       } else {
-               if (!JS_DefineProperty(cx, o, "data", OBJECT_TO_JSVAL(NULL),
-                   NULL, NULL, JSPROP_ENUMERATE)) {
-                       QUEUE_EXCEPTION("Internal error!");
-                       goto err;
-               }
-       }
-
-       return JS_TRUE;
-
-err:
-       if (data != NULL)
-               PQfreemem(data);
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-
-/*
- * PGresult object control
- */
-
-static JSObject *
-js_InitPGresultClass(JSContext *cx, JSObject *obj)
-{
-
-       return (JS_InitClass(cx, obj, NULL, &pgresult_class,
-           pgresult_constructor, 0, NULL, pgresult_methods, NULL, NULL));
-}
-
-/* Non instanciable */
-static JSBool
-pgresult_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       QUEUE_EXCEPTION("PGresult class not user-instanciable");
-
-       return JS_FALSE;
-}
-
-static void
-pgresult_finalize(JSContext *cx, JSObject *obj)
-{
-       PGresult        *pgr;
-
-       if ((pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL))
-           != NULL) {
-               PQclear(pgr);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-}
-
-
-/*
- * PGresult object methods
- */
-
-static JSBool
-pgresult_m_PQclear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       if ((pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL))
-           != NULL) {
-               PQclear(pgr);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgresult_m_PQresultStatus(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGresult        *pgr;
-       ExecStatusType  s;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       s = PQresultStatus(pgr);
-       *rval = INT_TO_JSVAL((int)s);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgresult_m_PQresultErrorMessage(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGresult        *pgr;
-       char            *res;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       res = PQresultErrorMessage(pgr);
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, res));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgresult_m_PQresultErrorField(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGresult        *pgr;
-       char            *res;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       res = PQresultErrorField(pgr, JSVAL_TO_INT(argv[0]));
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, res));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQntuples(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQntuples(pgr));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgresult_m_PQnfields(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQnfields(pgr));
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgresult_m_PQfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       char            *res;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       res = PQfname(pgr, JSVAL_TO_INT(argv[0]));
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, res));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQfnumber(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       char            *str;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument not a String");
-               goto err;
-       }
-       str = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQfnumber(pgr, str));
-
-       return JS_TRUE;
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: Oid is a typedef to unsigned int.  Thus, we use a double object to
- * make sure that we do not loose any precision.
- */
-static JSBool
-pgresult_m_PQftable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       Oid             oid;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       oid = PQftable(pgr, JSVAL_TO_INT(argv[0]));
-
-       if (!JS_NewDoubleValue(cx, (jsdouble)oid, rval)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQftablecol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQftablecol(pgr, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: we possibly could return a boolean value instead of an integer
- * but the documentation says that other values are reserved for possible
- * future use.  I am surprised that they do not return enumerated values.
- */
-static JSBool
-pgresult_m_PQfformat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQfformat(pgr, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: Oid is a typedef to unsigned int.  Thus, we use a double object to
- * make sure that we do not loose any precision.
- */
-static JSBool
-pgresult_m_PQftype(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       Oid             oid;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       oid = PQftype(pgr, JSVAL_TO_INT(argv[0]));
-
-       if (!JS_NewDoubleValue(cx, (jsdouble)oid, rval)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQfmod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQfmod(pgr, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQfsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQfsize(pgr, JSVAL_TO_INT(argv[0])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQbinaryTuples(JSContext *cx, JSObject *obj, uintN argc,
-    jsval *argv, jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQbinaryTuples(pgr));
-
-       return JS_TRUE;
-}
-
-/*
- * Note: The semantics of PGresult.PQgetvalue() is different from the actual
- * libpq C function PQgetvalue() in that we return null on NULL fields, and
- * that we always return either the binary or text data into the field as a
- * String (since ECMAScript Strings objects allow NUL characters).
- */
-static JSBool
-pgresult_m_PQgetvalue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       JSString        *str;
-       char            *res;
-       int             row, col;
-
-       if (argc != 2) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       row = JSVAL_TO_INT(argv[0]);
-       col = JSVAL_TO_INT(argv[1]);
-
-       if (PQgetisnull(pgr, row, col)) {
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_TRUE;
-       }
-
-       if ((res = PQgetvalue(pgr, row, col)) == NULL) {
-               QUEUE_EXCEPTION("PQgetvalue() == NULL");
-               goto err;
-       }
-
-       if ((str = JS_NewStringCopyN(cx, res, PQgetlength(pgr, row, col)))
-           == NULL) {
-               QUEUE_EXCEPTION("Out of memory!");
-               goto err;
-       }
-       *rval = STRING_TO_JSVAL(str);
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-/*
- * Note: unlike the C PQgetisnull() function, which returns 0 or 1, we return
- * true or false, since ECMAScript supports booleans.
- * Moreover, one no longer needs to call this function in JS if it is to
- * subsequently use PQgetvalue(), since ours can return null.
- * May still be useful in some situations.
- */
-static JSBool
-pgresult_m_PQgetisnull(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 2) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = BOOLEAN_TO_JSVAL(PQgetisnull(pgr, JSVAL_TO_INT(argv[0]),
-           JSVAL_TO_INT(argv[1])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQgetlength(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 2) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not an int");
-               goto err;
-       }
-       if (!JSVAL_IS_INT(argv[1])) {
-               QUEUE_EXCEPTION("Argument 2 not an int");
-               goto err;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = INT_TO_JSVAL(PQgetlength(pgr, JSVAL_TO_INT(argv[0]),
-           JSVAL_TO_INT(argv[1])));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-static JSBool
-pgresult_m_PQcmdStatus(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, PQcmdStatus(pgr)));
-
-       return JS_TRUE;
-}
-
-/*
- * We could return a double easily, but like the C API are returning a string
- */
-static JSBool
-pgresult_m_PQcmdTuples(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, PQcmdTuples(pgr)));
-
-       return JS_TRUE;
-}
-
-/*
- * Note: Oid is a typedef to unsigned int.  Thus, we use a double object to
- * make sure that we do not loose any precision.
- */
-static JSBool
-pgresult_m_PQoidValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGresult        *pgr;
-       Oid             oid;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       pgr = JS_GetInstancePrivate(cx, obj, &pgresult_class, NULL);
-       assert(pgr != NULL);
-
-       oid = PQoidValue(pgr);
-
-       if (!JS_NewDoubleValue(cx, (jsdouble)oid, rval)) {
-               QUEUE_EXCEPTION("Internal error!");
-               goto err;
-       }
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
-
-
-
-/*
- * PGcancel object control
- */
-
-static JSObject *
-js_InitPGcancelClass(JSContext *cx, JSObject *obj)
-{
-
-       return (JS_InitClass(cx, obj, NULL, &pgcancel_class,
-           pgcancel_constructor, 0, NULL, pgcancel_methods, NULL, NULL));
-}
-
-/* Non instanciable */
-static JSBool
-pgcancel_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-
-       QUEUE_EXCEPTION("PGcancel class not user-instanciable");
-
-       return JS_FALSE;
-}
-
-static void
-pgcancel_finalize(JSContext *cx, JSObject *obj)
-{
-       PGcancel        *pgc;
-
-       if ((pgc = JS_GetInstancePrivate(cx, obj, &pgcancel_class, NULL))
-           != NULL) {
-               PQfreeCancel(pgc);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-}
-
-
-/*
- * PGcancel object methods
- */
-
-static JSBool
-pgcancel_m_PQfreeCancel(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGcancel        *pgc;
-
-       if (argc != 0) {
-               QUEUE_EXCEPTION("Function allows no arguments");
-               *rval = OBJECT_TO_JSVAL(NULL);
-               return JS_FALSE;
-       }
-
-       if ((pgc = JS_GetInstancePrivate(cx, obj, &pgcancel_class, NULL))
-           != NULL) {
-               PQfreeCancel(pgc);
-               (void) JS_SetPrivate(cx, obj, NULL);
-       }
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_TRUE;
-}
-
-static JSBool
-pgcancel_m_PQcancel(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       PGcancel        *pgc;
-       char            *str;
-       size_t          len;
-       JSString        *s;
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               goto err;
-       }
-       if (!JSVAL_IS_STRING(argv[0])) {
-               QUEUE_EXCEPTION("Argument 1 not a String");
-               goto err;
-       }
-
-       pgc = JS_GetInstancePrivate(cx, obj, &pgcancel_class, NULL);
-       assert(pgc != NULL);
-
-       s = JSVAL_TO_STRING(argv[0]);
-       str = JS_GetStringBytes(s);
-       len = JS_GetStringLength(s);
-
-       *rval = INT_TO_JSVAL(PQcancel(pgc, str, len));
-
-       return JS_TRUE;
-
-err:
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       return JS_FALSE;
-}
diff --git a/tests/js-test/src/classes/js_pgsql.h b/tests/js-test/src/classes/js_pgsql.h
deleted file mode 100644 (file)
index 935b85c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: js_pgsql.h,v 1.3 2006/07/11 10:25:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSPGSQL_H
-#define JSPGSQL_H
-
-#include <jsapi.h>
-
-extern JSObject        *js_InitPGClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/classes/js_signal.c b/tests/js-test/src/classes/js_signal.c
deleted file mode 100644 (file)
index c93cc69..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* $Id: js_signal.c,v 1.3 2005/12/12 18:34:46 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Basic UNIX signal services for ECMAScript
- *
- * XXX
- * I have to see what interface I want to export. There are several
- * possibilities we could use:
- * - Have the shell register signal handlers fore interesting events at
- *   startup and allow scripts to provide a handler function, which if
- *   exists upon reception of a signal, gets executed.  We might then
- *   need to add extra custom checks in the shell for special signals
- *   which if the script doesn't end, might still end the process
- *   i.e. function would be expected to cause the script to exit upon
- *   reception of a SIGTERM signal...
- * - Provide a sigaction-style interface so that the script would be
- *   able to define functions to execute upon reception of certain
- *   signals, or null or such for the signal to be ignored.
- *   This solution might allow better application customization.
- *   If assuming this interface, the following would be exported:
- *   - Signal class, through which static signal properties could be
- *     accessed for signal numbers I.E. Signal.SIGTERM.
- *   - A static method to create/set/unset/ignore a signal/handler
- *     Signal.sigaction()?
- *     It could be provided with the parameters:
- *     Signal.sigaction(FD.SIG*, obj);
- *      Where obj would contain fields sa_handler, sa_mask, sa_flags?
- *     Signal.kill(pid, sig);
- *     Signal.sigaltstack(...) ?
- *     Signal.sigprocmask(...)
- *     Signal.sigsuspend(mask)
- *    And maybe provide the sigsetops(3)?  We possibly could just allow an
- *    array or such instead of sigset_t though if wanted.
- *    I'm not sure I want to provide sigsetjmp()/siglongjmp(). JavaScript has
- *    exceptions anyways.  If allowing sigaltstack(), C would need to allocate
- *    the stacks, so a stack object would need to be exported or such.  I
- *    don't think I want to support this as it's probably not needed by any of
- *    the applications I'll write, I don't want to write a threading library
- *    in JS.
- * - I wonder if it would be safe to invoke a JS function in a signal handler.
- *   If it wasn't, I could simply queue the signal events and then call the
- *   functions for the queue in normal process context.
- *   If doing this, sigaction has to be called to catch any signal the
- *   application wishes, and we would be rolling our own signal handling,
- *   so if wanted we could potentially provide another interface than
- *   sigaction to ECMAScript...
- */
-
-
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jsapi.h>
-
-
-
-/* Utility macros */
-#define QUEUE_EXCEPTION(s)     do {                                    \
-       JS_SetPendingException(cx,                                      \
-           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
-} while (/* CONSTCOND */0)
-
-
-
-/* Prototypes */
-static JSBool  signal_sm_strerror(JSContext *, JSObject *, uintN, jsval *,
-                   jsval *);
-
-
-
-/* Actual class parameters */
-static JSClass signal_class = {
-       "Signal", 0, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
-};
-
-/* Provided static methods */
-static JSFunctionSpec signal_smethods[] = {
-       { "strerror", signal_sm_strerror, 1, 0, 0 },
-       { NULL, NULL, 0, 0, 0 }
-};
-
-/*
- * Provided static properties.
- * We use these to provide ECMAScript with the ability to use system-specific
- * standard C constant macros without us having to tidiously map them
- * individually, or to require other scripts to be used as headers to define
- * them.  Another possibility would have been to supply these parameters as
- * string, but this would have required even slower remapping because of the
- * parsing and string comparisions.
- * We only include those which we consider necessary for now, others may be
- * added easily as needed, provided that they are added in all three maps.
- * I might perhaps develop macros and/or functions to map all these easily
- * from a single map.
- */
-
-struct property_spec {
-       const char      *name;
-       int             value;
-};
-
-#define SP(n) \
-    { #n, n }
-
-static struct property_spec    signal_sprops[] = {
-       SP(SIGHUP),
-       SP(SIGINT),
-       SP(SIGQUIT),
-       SP(SIGILL),
-       SP(SIGTRAP),
-       SP(SIGABRT),
-       SP(SIGEMT),
-       SP(SIGFPE),
-       SP(SIGKILL),
-       SP(SIGBUS),
-       SP(SIGSEGV),
-       SP(SIGSYS),
-       SP(SIGPIPE),
-       SP(SIGALRM),
-       SP(SIGTERM),
-       SP(SIGURG),
-       SP(SIGSTOP),
-       SP(SIGTSTP),
-       SP(SIGCONT),
-       SP(SIGCHLD),
-       SP(SIGTTIN),
-       SP(SIGTTOU),
-       SP(SIGIO),
-       SP(SIGXCPU),
-       SP(SIGXFSZ),
-       SP(SIGVTALRM),
-       SP(SIGPROF),
-       SP(SIGWINCH),
-       SP(SIGINFO),
-       SP(SIGUSR1),
-       SP(SIGUSR2),
-       SP(SIGPWR),
-
-       { NULL, 0 }
-};
-
-#undef SP
-
-
-
-/*
- * Class control functions
- */
-
-JSObject *
-js_InitSignalClass(JSContext *cx, JSObject *obj)
-{
-       JSObject                *proto, *ctor;
-       struct property_spec    *sp;
-
-       if ((proto = JS_InitClass(cx, obj, NULL, &signal_class, NULL,
-           0, NULL, NULL, NULL, signal_smethods)) == NULL) {
-               (void) fprintf(stderr, "Error initializing Signal class\n");
-               return NULL;
-       }
-
-       /* Create static properties */
-       if ((ctor = JS_GetConstructor(cx, proto)) == NULL) {
-               (void) fprintf(stderr, "Signal: JS_GetConstructor == NULL\n");
-               return NULL;
-       }
-       for (sp = signal_sprops; sp->name != NULL; sp++) {
-               if (JS_DefineProperty(cx, ctor, sp->name,
-                   INT_TO_JSVAL(sp->value), NULL, NULL,
-                   JSPROP_READONLY | JSPROP_PERMANENT) == JS_FALSE) {
-                       (void) fprintf(stderr,
-                           "Signal: Error defining property %s\n", sp->name);
-                       return NULL;
-               }
-       }
-
-       return proto;
-}
-
-
-
-/*
- * Static properties functions
- */
-
-
-
-/*
- * Static methods
- */
-
-static JSBool
-signal_sm_strerror(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-    jsval *rval)
-{
-       int             error;
-       JSString        *string;
-
-       *rval = OBJECT_TO_JSVAL(NULL);
-
-       if (argc != 1) {
-               QUEUE_EXCEPTION("Wrong number of arguments");
-               return JS_FALSE;
-       }
-       if (!JSVAL_IS_INT(*argv)) {
-               QUEUE_EXCEPTION("Argument not an integer");
-               return JS_FALSE;
-       }
-       error = (int)JSVAL_TO_INT(*argv);
-
-       if ((string = JS_NewStringCopyZ(cx, "testXXX")) == NULL) {
-               QUEUE_EXCEPTION("Out of memory");
-               return JS_FALSE;
-       }
-
-       *rval = STRING_TO_JSVAL(string);
-
-       return JS_TRUE;
-}
diff --git a/tests/js-test/src/classes/js_signal.h b/tests/js-test/src/classes/js_signal.h
deleted file mode 100644 (file)
index 3690d12..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id: js_signal.h,v 1.1 2005/07/19 19:27:28 mmondor Exp $ */
-
-/*
- * Copyright (c) 2005, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#ifndef JSSIGNAL_H
-#define JSSIGNAL_H
-
-extern JSObject        *js_InitSignalClass(JSContext *, JSObject *);
-
-#endif
diff --git a/tests/js-test/src/js-server.c b/tests/js-test/src/js-server.c
deleted file mode 100644 (file)
index f0bfe38..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* $Id: js-server.c,v 1.7 2006/07/12 13:47:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2005, Matthew Mondor
- */
-
-/*
- * TODO:
- *
- * - Verify with Brendan Eich:
- *   - If reusing the context to execute several other scripts, it is
- *     important that they not be able to add global properties or methods.
- *     This seems to currently work using a custom api_class_property_add().
- *     This however also required standard properties to be shared
- *     (JS_PROP_SHARED), otherwise api_class_property_add() would be called
- *     and even setting values to existing API system properties would fail in
- *     user scripts.  Scealing was also too strict.
- *     I assumed that JS_AddNamedRoot() was required for the API class to
- *     never be freed, so that it can be reused after a call to
- *     js_context_reset().  Perhaps this is not necessary.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <assert.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <jsapi.h>
-
-#include <js_fd.h>
-#include <js_errno.h>
-#include <js_signal.h>
-#include <js_pgsql.h>
-
-
-
-/*
- * DEFINITIONS
- */
-
-/* Size runtime objects must take to run the GC */
-#define GCBYTES    1048576 /* 1MB */
-
-/* Size of stack to allocate for every context */
-#define STACKBYTES 8192    /* 8KB */
-
-/*
- * Structure used to link a context with custom objects we need to perform
- * some cleanup from before destroying the context.  Ideally managed via
- * mmpool(3) in a real world application for slap management and recycling.
- * We'll have one of these per process in our pool of processes.
- */
-typedef struct {
-       JSRuntime       *rt;
-       JSContext       *ctx;
-       JSObject        *global, *class_fd, *class_errno, *class_signal,
-                       *class_pgsql;
-} js_context_t;
-
-/*
- * To hold loaded file objects (actually mmap(2)ed)
- */
-typedef struct {
-       void            *data;
-       size_t          size;
-} file_t;
-
-/*
- * Defaults for the global class
- */
-static JSClass global_class = {
-       "global", 0, JS_PropertyStub, JS_PropertyStub,
-       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
-       JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
-};
-
-
-
-/*
- * PROTOTYPES
- */
-
-int                    main(int, char **);
-static JSBool          branch_callback(JSContext *, JSScript *);
-
-static file_t          *file_load(const char *);
-static void            file_free(file_t *);
-
-/* Could be an exported API later on */
-static js_context_t    *js_context_init(size_t, size_t);
-static void            js_context_destroy(js_context_t *);
-/* XXX static void             js_context_reset(js_context_t *);*/
-
-
-
-
-
-int
-main(int argc, char **argv)
-{
-       file_t          *file;
-       js_context_t    *cctx;
-
-       if (argc != 2) {
-               (void) fprintf(stderr, "Usage: test <scriptfile>\n");
-               exit(EXIT_FAILURE);
-       }
-       if ((file = file_load(argv[1])) == NULL) {
-               (void) fprintf(stderr, "Error loading '%s'\n", argv[1]);
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * We always need at least one runtime per process, at least one
-        * context per thread and at least a global object per context
-        * (standard classes, like Date).
-        */
-       if ((cctx = js_context_init(GCBYTES, STACKBYTES)) == NULL) {
-               file_free(file);
-               (void) fprintf(stderr, "js_context_init()\n");
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * This is a very useful and important feature, enable our callback
-        * function which will get called whenever the script branches
-        * backwards, returns from a function or exits. It allows us to
-        * even maintain control in cases where the script loops endlessly.
-        */
-       (void) JS_SetBranchCallback(cctx->ctx, branch_callback);
-
-       /*
-        * Now enable addProperty() protection for all classes using our
-        * custom api_class_property_add() function. This will prevent user
-        * code from adding properties or methods to the API class for
-        * instance.
-        * This however requires that properties use the JSPROP_SHARED flag
-        * since addProperty() method would internally get called to create
-        * shadow copies for the runtime otherwise.
-        */
-       /*
-       api_class_protect = JS_TRUE;
-       */
-
-       /*
-        * Now execute script loaded into our file_t.
-        * We simplify this process by calling JS_EvaluateScript() which
-        * will first tokenize/compile the result, and then interpret/run it.
-        * Moreover, it allows the script to optionally return a value
-        * directly like if it was a function.
-        * Alternatively, we could use JS_CompileFile() or JS_CompileScript()
-        * to pre-tokenize the script, and JS_ExecuteScript() to interpret it.
-        */
-       {
-               jsval           rval, pval;
-               JSString        *str;
-               int             i;
-
-               if (JS_EvaluateScript(cctx->ctx, cctx->global, file->data,
-                   file->size, argv[1], 1, &rval)) {
-                       str = JS_ValueToString(cctx->ctx, rval);
-                       (void) printf("Script result: %s\n",
-                           JS_GetStringBytes(str));
-                       /*
-                        * Attempt to call JS function "callMe" if the script
-                        * created it.
-                        */
-                       for (i = 0; i < 10; i++) {
-                               pval = INT_TO_JSVAL(i);
-                               if (!JS_CallFunctionName(cctx->ctx,
-                                   cctx->global, "callMe", 1, &pval, &rval))
-                                       break;
-                       }
-               } else {
-                       /* XXX how to obtain error and stack backtrace? */
-               }
-       }
-
-       /* Cleanup */
-       file_free(file);
-       js_context_destroy(cctx);
-
-       exit(EXIT_SUCCESS);
-}
-
-/*
- * This function is called during the execution of the script so that we can
- * remain in control of the application. If we only allow the scripts to
- * define functions for callbacks, we can use the first instance if this event
- * to abort the script if wanted, as well. We can then set an alternative
- * callback function and execute the script provided functions at specific
- * events. Of course, it also would be possible to use setitimer(2) to have
- * a SIGALRM signal trigger a function at regular set intervals.
- */
-/* ARGSUSED */
-static JSBool
-branch_callback(JSContext *ctx, JSScript *script)
-{
-       static int      count = 0;
-
-       if (++count > 1000) {
-               count = 0;
-               JS_MaybeGC(ctx);
-       }
-
-       /* Returning JS_FALSE here aborts the script */
-       return JS_TRUE;
-}
-
-
-
-/*
- * Could be an exported API
- */
-
-static js_context_t *
-js_context_init(size_t gc_size, size_t stack_size)
-{
-       js_context_t    *cctx;
-
-       if ((cctx = malloc(sizeof(js_context_t))) == NULL ||
-           (cctx->rt = JS_NewRuntime(gc_size)) == NULL ||
-           (cctx->ctx = JS_NewContext(cctx->rt, stack_size)) == NULL ||
-           (cctx->global = JS_NewObject(cctx->ctx, &global_class, NULL,
-               NULL)) == NULL ||
-           !JS_InitStandardClasses(cctx->ctx, cctx->global) ||
-           (cctx->class_fd = js_InitFDClass(cctx->ctx, cctx->global))
-               == NULL ||
-           (cctx->class_errno = js_InitErrnoClass(cctx->ctx, cctx->global))
-               == NULL ||
-           (cctx->class_signal = js_InitSignalClass(cctx->ctx, cctx->global))
-               == NULL ||
-           (cctx->class_pgsql = js_InitPGClass(cctx->ctx, cctx->global))
-               == NULL) {
-               /* An error, free any partially allocated resources */
-               if (cctx != NULL)
-                       js_context_destroy(cctx);
-
-               return NULL;
-       }
-
-       return cctx;
-}
-
-static void
-js_context_destroy(js_context_t *cctx)
-{
-
-       assert(cctx != NULL);
-
-       if (cctx->ctx != NULL)
-               JS_DestroyContext(cctx->ctx);
-       if (cctx->rt != NULL)
-               JS_DestroyRuntime(cctx->rt);
-
-       free(cctx);
-}
-
-/*
- * This function should permit to restore the context to a consistent, known
- * state before a new script can be executed using the same context instead of
- * having to destroy and recreate contexts everytime.
- */
-/* ARGSUSED */
-/* XXX
-static void
-js_context_reset(js_context_t *cctx)
-{
-
-}
-*/
-
-
-/*
- * Loads specified file and returns a file_t pointer.  Note that we only
- * internally keep the memory map for read access to the file, rather than an
- * open filedescriptor.
- */
-static file_t *
-file_load(const char *filename)
-{
-       int             fd;
-       struct stat     st;
-       file_t          *file;
-
-       assert(filename != NULL);
-
-       if ((fd = open(filename, O_RDONLY)) != -1) {
-               if (fstat(fd, &st) == 0) {
-                       if ((file = malloc(sizeof(file_t))) != NULL) {
-                               file->size = (size_t)st.st_size;
-
-                               if ((file->data = mmap(NULL, file->size,
-                                   PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0))
-                                   != MAP_FAILED) {
-                                       (void) close(fd);
-                                       return file;
-                               }
-
-                               free(file);
-                       }
-               }
-               (void) close(fd);
-       }
-
-       return NULL;
-}
-
-/*
- * Frees a file_t which was returned by a previous file_load() call.
- */
-static void
-file_free(file_t *file)
-{
-
-       assert(file != NULL);
-
-       (void) munmap(file->data, file->size);
-       free(file);
-}
diff --git a/tests/js-test/util/spidermonkey-config b/tests/js-test/util/spidermonkey-config
deleted file mode 100755 (executable)
index 6a3cc76..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/sh
-#
-# Configure script to help build scripts
-# by Matthew Mondor
-
-CFLAGS='-I/usr/local/spidermonkey/include -DXP_UNIX'
-LDFLAGS='-Wl,-R/usr/local/spidermonkey/lib -L/usr/local/spidermonkey/lib -ljs'
-
-DLDFLAGS='-Wl,-R/usr/local/spidermonkey/lib -L/usr/local/spidermonkey/lib -ljs_dbg'
-
-VERSION='SpiderMonkey 1.5-rc6A'
-
-usage()
-{
-       echo
-       echo 'Usage: spidermonkey-config [-v] [-c] [-l] [-d]'
-       echo
-       echo ' -v : Shows SpiderMonkey version'
-       echo ' -c : Shows flags suitable to append to $CFLAGS'
-       echo ' -l : Shows flags suitable to append to $LDFLAGS'
-       echo ' -d : Shows debugging versions of the flags'
-       echo
-}
-
-if [ -z $@ ]; then
-       usage
-       exit 0
-fi
-
-while getopts dclv c; do
-       case $c in
-       d)
-               LDFLAGS="$DLDFLAGS"
-               ;;
-       c)
-               echo $CFLAGS
-               ;;
-       l)
-               echo $LDFLAGS
-               ;;
-       v)
-               echo $VERSION
-               ;;
-       *)
-               usage
-               exit 0
-               ;;
-       esac
-done
diff --git a/tests/kqueue/GNUmakefile b/tests/kqueue/GNUmakefile
deleted file mode 100644 (file)
index 4ae0616..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# $Id: GNUmakefile,v 1.7 2006/04/23 04:40:14 mmondor Exp $
-
-MMLIB_PATH := ../../mmlib
-
-MMLIBS := $(addprefix ${MMLIB_PATH}/,mmpool.o mmstring.o mmarch.o)
-LIBS := -lc
-OBJS := main.o net.o kqueue.o sendq.o recvq.o packets.o daemon.o client.o
-CFLAGS += -Wall
-BINS := daemon
-
-all: $(BINS)
-
-%.o: %.c
-       cc -c ${CFLAGS} -I. -I${MMLIB_PATH} -o $@ $<
-
-
-daemon: $(MMLIBS) $(LIBS) $(OBJS)
-       cc -o $@ $(MMLIBS) $(OBJS) $(LIBS)
-
-
-clean:
-       rm -f $(BINS) $(OBJS) $(MMLIBS) $(LIBS)
diff --git a/tests/kqueue/README b/tests/kqueue/README
deleted file mode 100644 (file)
index 3d58fc4..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-$Id: README,v 1.3 2006/04/23 04:40:14 mmondor Exp $
-
-If this all works fine, it might be the basis of a multiplayer
-networking game.  However, this is primarily a test to learn kqueue
-and observe its efficiency, as well as to experiment using TCP for
-such massive multiplayer games on today's networks and internet.
-
-Many games that used TCP for LAN use a while back had to develop
-UDP based protocols to be efficient enough for dialup users or
-other internet users.  We will determine if this is still necessary
-on today's average internet latencies.
-
-We probably still want to prioritize some packets over others.
-For instance, we might drop outgoing position update packets which
-cannot be sent immediately instead of queueing them, allowing less
-frequent updates to slow connections while not needing to provide
-multiple independent game heart rates.
-
-We do not expect to have to port the server part of the game, wich
-is intended to run on BSD systems supporting the kqueue(2) system
-only.  We could have used an event library, however we wanted to
-avoid including non-BSD licensed components.  Although there is a
-BSD licensed libevent as part of NetBSD, using kqueue directly
-allows a few fancy optimization tricks which would require a new
-portable events library to be designed to allow to achieve the full
-advantages of kqueue using an abstracted library.
-
-The client code, however, will be portable and should be able to
-run on Win32 without needing the cygwin runtime libraries.  The
-SDL dependency is reasonable, and can be provided separately, so
-mingw will be used to create those executables.  The client will
-however primarily be developped on NetBSD.  Like SDL, OpenGL
-libraries shouldn't be a problem either.
-
-To avoid using cygwin, and because Win32 winsock does not conform
-to BSD sockets API standards, we expect to have to write a simple
-portable networking layer for use in the client.
-
-
-TODO
-
-- At this point to advance further a client needs to be written.
-- We probably don't need to align packets, we only need to make sure
-  that their size is 32-bit aligned, and that their 16-bit fields are
-  16-bit aligned, their 32-bit ones 32-bit aligned.  Packet type field
-  can be 8-bit.  If we allowed arbitrary offsets when buffering packets,
-  we would need to copy each packet to an aligned buffer as we process them.
-  Evaluate which is more advantageous.
diff --git a/tests/kqueue/client.c b/tests/kqueue/client.c
deleted file mode 100644 (file)
index 7fa0caa..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* $Id: client.c,v 1.9 2006/04/23 04:40:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "client.h"
-#include "kqueue.h"
-#include "conf.h"
-
-
-
-list_t                 clients_list;
-static list_t          clients_gc_list;
-static pool_t          clients_pool;
-
-
-
-void
-client_init(void)
-{
-       DLIST_INIT(&clients_list);
-       DLIST_INIT(&clients_gc_list);
-
-       if (!pool_init(&clients_pool, "clients_pool", malloc, free, NULL,
-           NULL, sizeof(client_t), MAX_CLIENTS + 1, 1, 1)) {
-               syslog(LOG_NOTICE, "pool_init() - %s", strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-
-}
-
-/*
- * Enables the write polling filter for the specified client.
- */
-void
-client_enable_write_polling(void *args)
-{
-       client_t        *c = (client_t *)args;
-
-       if (c->writepolling)
-               return;
-
-       kqueue_sev_alloc(1);
-       kqueue_sev_add(c->fd, EVFILT_WRITE, EV_ENABLE, 0, 0, (intptr_t)c);
-
-       c->writepolling = 1;
-}
-
-inline int
-client_write(client_t *c, uint8_t *buf, size_t size, int buffer)
-{
-
-       if (sendq_write(&c->sendq, buf, size, client_enable_write_polling, c,
-           buffer) == -1) {
-               syslog(LOG_NOTICE, "sendq_write(%u) - %s", size,
-                   strerror(errno));
-               return -1;
-       }
-
-       return 0;
-}
-
-/*
- * XXX We should do connection rate/concurrency checking on address here.
- */
-client_t *
-client_create(int fd, struct sockaddr *saddr)
-{
-       client_t        *c;
-
-       if (DLIST_NODES(&clients_list) > MAX_CLIENTS) {
-               syslog(LOG_NOTICE, "client_create() - MAX_CLIENTS reached");
-               return NULL;
-       }
-
-       if ((c = (client_t *)pool_alloc(&clients_pool, FALSE)) != NULL) {
-               if (sendq_init(&c->sendq, fd, SENDQ_SIZE) != -1) {
-                       if (recvq_init(&c->recvq, fd, RECVQ_SIZE) != -1) {
-                               c->fd = fd;
-                               (void) memcpy(&c->saddr, saddr,
-                                   sizeof(struct sockaddr));
-
-                               c->object.x = random() % WORLD_X_MAX;
-                               c->object.y = random() % WORLD_Y_MAX;
-                               c->object.direction = c->object.i_direction =
-                                  random() % 1000;
-                               c->object.thrust = c->object.i_thrust =
-                                  random() % 20;
-
-                               c->authenticated = c->todestroy =
-                                   c->toclose = 0;
-                               c->writepolling = 1;
-                               c->askedping = 0;
-
-                               DLIST_APPEND(&clients_list, &c->node);
-
-                               return c;
-                       }
-                       syslog(LOG_NOTICE,
-                           "client_create() - recvq_init() - %s",
-                           strerror(errno));
-                       sendq_destroy(&c->sendq);
-               }
-               syslog(LOG_NOTICE,
-                   "client_create() - sendq_init() - %s", strerror(errno));
-               pool_free((pnode_t *)c);
-       }
-       syslog(LOG_NOTICE, "client_create() - pool_alloc() - %s",
-           strerror(errno));
-
-       return NULL;
-}
-
-void
-client_destroy_mark(client_t *c)
-{
-
-       if (c->todestroy)
-               return;
-
-       c->todestroy = 1;
-       DLIST_SWAP(&clients_gc_list, &clients_list, &c->node, FALSE);
-}
-
-void
-client_destroy_marked(void)
-{
-       node_t          *i, *n;
-       client_t        *c;
-
-       for (i = DLIST_TOP(&clients_gc_list); i != NULL; i = n) {
-               n = DLIST_NEXT(i);
-
-               c = (client_t *)i;
-               /* Closing descriptor automatically deletes its kevents */
-               (void) close(c->fd);
-               recvq_destroy(&c->recvq);
-               sendq_destroy(&c->sendq);
-               pool_free((pnode_t *)c);
-       }
-       DLIST_INIT(&clients_gc_list);
-}
diff --git a/tests/kqueue/client.h b/tests/kqueue/client.h
deleted file mode 100644 (file)
index a9575fc..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* $Id: client.h,v 1.7 2006/04/03 08:56:45 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _CLIENT_H_
-#define _CLIENT_H_
-
-
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <mmpool.h>
-#include <mmlist.h>
-
-#include "sendq.h"
-#include "recvq.h"
-
-
-
-typedef struct object {
-       node_t          region;
-       int32_t         direction, thrust;
-       int32_t         i_direction, i_thrust;
-       int32_t         x, y;
-} object_t;
-
-typedef struct client {
-       node_t          node;
-       object_t        object;
-       sendq_t         sendq;
-       recvq_t         recvq;
-       int             fd;
-       struct sockaddr saddr;
-       int             authenticated, todestroy, toclose, writepolling,
-                       askedping;
-} client_t;
-
-
-
-extern list_t  clients_list;
-
-
-void           client_init(void);
-void           client_enable_write_polling(void *);
-inline int     client_write(client_t *, u_int8_t *, size_t, int);
-
-client_t       *client_create(int, struct sockaddr *);
-void           client_destroy_mark(client_t *);
-void           client_destroy_marked(void);
-
-
-
-#endif
diff --git a/tests/kqueue/conf.h b/tests/kqueue/conf.h
deleted file mode 100644 (file)
index 5720c1a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $Id: conf.h,v 1.9 2006/04/23 04:40:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _CONF_H_
-#define _CONF_H_
-
-
-
-#define SERVER_VERSION 1
-#define SERVER_STRING  "daemon/mmondor\n"
-
-#define FPS            10
-#define FPS_MS         (1000 / FPS)
-
-#define WORLD_X_MAX    640
-#define WORLD_Y_MAX    480
-
-#define MAX_CLIENTS    128
-#define R_EVENTS       (MAX_CLIENTS * 2)
-#define S_EVENTS       (MAX_CLIENTS * 2)
-
-#define SENDQ_SIZE     16384
-#define RECVQ_SIZE     1024
-
-/* In seconds */
-#define INPUT_TIMEOUT  30
-#define PING_TIMEOUT   5
-
-#define PIDFILE                "/tmp/daemon.pid"
-
-
-
-#endif
diff --git a/tests/kqueue/daemon.c b/tests/kqueue/daemon.c
deleted file mode 100644 (file)
index bd38e65..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $Id: daemon.c,v 1.3 2006/04/23 04:40:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Procedure for becoming an detached daemon, as well as to prepare process
- * signal handling.  Since we'll be catching signal events through kqueue(2),
- * We simply ignore all signals for which we don't want the default behavior.
- */
-
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include <mmstring.h>
-
-#include <conf.h>
-
-
-
-static int     signal_init(void);
-static void    pidfile_write(const char *);
-
-
-
-static int
-signal_init(void)
-{
-       struct sigaction        act;
-       int                     i;
-       int                     sigs[] = {
-               SIGHUP,
-               SIGINT,
-               SIGPIPE,
-               SIGALRM,
-               SIGTERM,
-               SIGTTIN,
-               SIGTTOU,
-               SIGIO,
-               SIGXCPU,
-               SIGXFSZ,
-               SIGVTALRM,
-               SIGPROF,
-               SIGUSR1,
-               SIGUSR2
-       };
-
-       act.sa_handler = SIG_IGN;
-       act.sa_flags = SA_NOCLDSTOP;
-       (void) sigemptyset(&act.sa_mask);
-
-       for (i = 0; i < (sizeof(sigs) / sizeof(int)); i++) {
-               if (sigaction(sigs[i], &act, NULL) != 0) {
-                       syslog(LOG_NOTICE,
-                           "signal_init() - sigaction(%d) - %s",
-                           sigs[i], strerror(errno));
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Writes our process ID number to specified file.  To be called before
- * chroot(2) or dropping privileges.
- */
-static void
-pidfile_write(const char *file)
-{       
-       char    str[16];
-       int     fd;
-
-       if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600)) != -1) {
-               (void) snprintf(str, 15, "%d\n", getpid());
-               (void) write(fd, str, mm_strlen(str));
-               (void) close(fd);
-       } else  
-               syslog(LOG_NOTICE, "pidfile_write() - open(%s) - %s",
-                   file, strerror(errno));
-}
-
-int
-daemon_init(void)
-{
-       pid_t   pid;
-       int     fd;
-
-       /* Create new process */
-       if ((pid = fork()) == -1) {
-               syslog(LOG_NOTICE, "fork() - %s", strerror(errno));
-               return -1;
-       }
-       if (pid != 0)
-               exit(EXIT_SUCCESS);
-
-       pidfile_write(PIDFILE);
-
-       /* Create new process group and detach */
-       (void) setsid();
-       (void) chdir("/");
-       if ((fd = open("/dev/null", O_RDWR)) != -1) {
-               (void) dup2(fd, STDIN_FILENO);
-               (void) dup2(fd, STDOUT_FILENO);
-               (void) dup2(fd, STDERR_FILENO);
-               if (fd > STDERR_FILENO)
-                       (void) close(fd);
-       } else
-               syslog(LOG_NOTICE, "daemon_init() - open(/dev/null) - %s",
-                   strerror(errno));
-
-       if (signal_init() != 0)
-               return -1;
-
-       return 0;
-}
diff --git a/tests/kqueue/daemon.h b/tests/kqueue/daemon.h
deleted file mode 100644 (file)
index 32ec407..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: daemon.h,v 1.2 2006/03/31 20:57:08 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _DAEMON_H_
-#define _DAEMON_H_
-
-
-
-int    daemon_init(void);
-
-
-
-#endif
diff --git a/tests/kqueue/kqueue.c b/tests/kqueue/kqueue.c
deleted file mode 100644 (file)
index a5a8628..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/* $Id: kqueue.c,v 1.11 2006/04/03 21:06:08 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <errno.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <mmarch.h>
-
-#include "kqueue.h"
-#include "client.h"
-#include "packets.h"
-#include "net.h"
-#include "conf.h"
-
-
-
-static struct kevent   rev[R_EVENTS], sev[S_EVENTS];
-static int             kqid, rev_cnt, sev_cnt;
-
-
-
-/* The following functions simply exit on failure, because they are critical */
-
-void
-kqueue_init(void)
-{
-
-       if ((kqid = kqueue()) == -1) {
-               syslog(LOG_NOTICE, "kqueue_init() - kqueue() - %s",
-                   strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-
-       sev_cnt = 0;
-}
-
-void
-kqueue_addlisten(int fd)
-{
-
-       EV_SET(sev, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, (intptr_t)NULL);
-       if (kevent(kqid, sev, 1, NULL, 0, NULL) == -1) {
-               syslog(LOG_NOTICE, "kqueue_addlisten() - kevent(%d) - %s",
-                   fd, strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-
-}
-
-void
-kqueue_addsignal(int sig)
-{
-
-       EV_SET(sev, sig, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0,
-           (intptr_t)NULL);
-       if (kevent(kqid, sev, 1, NULL, 0, NULL) == -1) {
-               syslog(LOG_NOTICE, "kqueue_addsignal() - kevent(%d) - %s",
-                   sig, strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-}
-
-void
-kqueue_addtimer0(int64_t ms)
-{
-
-       EV_SET(sev, 0, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, ms,
-           (intptr_t)NULL); 
-       if (kevent(kqid, sev, 1, NULL, 0, NULL) == -1) {
-               syslog(LOG_NOTICE, "kevent_addtimer0() - kevent(%lld) - %s",
-                   ms, strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-}
-
-void
-kqueue_main(void)
-{
-
-       for (;;) {
-               int             e, i;
-               struct kevent   *kev;
-               client_t        *c;
-
-               /*
-                * Fusion to only require one kevent(2) call if there are
-                * events to send.  Wait for events to occur.
-                * This also allows us to catch error events.
-                */
-               if ((rev_cnt = kevent(kqid, sev, sev_cnt, rev, R_EVENTS, NULL))
-                   == -1) {
-                       syslog(LOG_NOTICE, "kevent(1) - %s", strerror(errno));
-                       continue;
-               }
-               sev_cnt = 0;
-
-               /* Run through received events and process them */
-               for (e = 0; e < rev_cnt; e++) {
-                       kev = &rev[e];
-
-                       /* Report errors if any */
-                       if ((kev->flags & EV_ERROR) != 0) {
-                               syslog(LOG_NOTICE,
-                                   "EV_ERROR: ident=%d filter=%d flags=%d "
-                                   "fflags=%d data=%lld udata=%p",
-                                   kev->ident, kev->filter, kev->flags,
-                                   kev->fflags, kev->data,
-                                   (void *)kev->udata);
-                               continue;
-                       }
-
-                       /* Process signals if any */
-                       if (kev->filter == EVFILT_SIGNAL) {
-                               switch (kev->ident) {
-                               case SIGTERM:
-                                       syslog(LOG_NOTICE,
-                                           "Received SIGTERM, exiting");
-                                       exit(EXIT_SUCCESS);
-                                       break;
-                               }
-                               continue;
-                       }
-
-                       /* Process timeouts if any */
-                       if (kev->filter == EVFILT_TIMER) {
-                               if (kev->ident == 0) {
-                                       /* Main heartrate timer */
-                                       update();
-                                       continue;
-                               }
-                               /*
-                                * XXX input timeout timers?
-                                * We'll need an input timer per socket,
-                                * which gets canceled whenever input arrives,
-                                * but once expires launches a server ping
-                                * request which then should trigger another
-                                * timer, which if pong occurs gets restarted,
-                                * but if it exceeds client gets dropped.
-                                * We'll also need to match timer events with
-                                * filedescriptors, as well as reason for
-                                * timeout...  And we'll need to make sure to
-                                * clean out any pending timers when marking a
-                                * client to be destroyed (or when destroying
-                                * them, at least).
-                                */
-                       }
-
-                       if (kev->ident == listen_fd) {
-                               int     t;
-
-                               /*
-                                * Accept new connections, create clients and
-                                * add new descriptors to the kqueue set,
-                                * buffering them to minimize syscalls.
-                                */
-                               for (i = 0, t = kev->data; i < t; i++) {
-                                       struct sockaddr saddr;
-                                       socklen_t       saddrl;
-                                       client_t        *c;
-                                       int             fd;
-
-                                       saddrl = sizeof(struct sockaddr);
-                                       if ((fd = accept(listen_fd, &saddr,
-                                           &saddrl)) == -1)
-                                               continue;
-
-                                       if ((c = client_create(fd, &saddr))
-                                           == NULL) {
-                                               (void) close(fd);
-                                               continue;
-                                       }
-
-                                       kqueue_sev_alloc(2);
-                                       kqueue_sev_add(fd, EVFILT_READ,
-                                           EV_ADD | EV_EOF | EV_ENABLE, 0, 0,
-                                           (intptr_t)c);
-                                       kqueue_sev_add(fd, EVFILT_WRITE,
-                                           EV_ADD | EV_EOF | EV_ENABLE, 0, 0,
-                                           (intptr_t)c);
-
-                                       /* Send auth request packet */
-                                       if (spacket_auth_send(c) == -1) {
-                                               client_destroy_mark(c);
-                                               continue;
-                                       }
-                               }
-                               continue;
-                       }
-
-                       /*
-                        * Don't process any more events for marked to be
-                        * destroyed clients, or those without an associated
-                        * udata.  When client descriptor must be closed and
-                        * client structure freed, we make sure to first mark
-                        * it as to destroy within this loop, since it's
-                        * possible for more than one event to occur for a
-                        * single descriptor.  We use client_destroy_mark()
-                        * for this purpose.
-                        */
-                       if ((c = (client_t *)kev->udata) == NULL) {
-                               /* XXX */
-                               syslog(LOG_NOTICE, "udata == NULL");
-                               continue;
-                       }
-                       if (c->todestroy)
-                               continue;
-
-                       if ((kev->flags & EV_EOF) != 0) {
-                               client_destroy_mark(c);
-                               continue;
-                       }
-
-                       if (kev->filter == EVFILT_WRITE) {
-                               int     f;
-
-                               /*
-                                * If there's a sendq for the client,
-                                * attempt to flush it.  If there's an error,
-                                * drop client.
-                                * If client was marked to be closed, and we
-                                * finished flusing data, also mark it to be
-                                * destroyed, since were done with it.
-                                */
-                               if ((f = sendq_flush(&c->sendq, kev->data))
-                                   == -1 || (f == 0 && c->toclose))
-                                       client_destroy_mark(c);
-                               else if (f == 0) {
-                                       /*
-                                        * No more data to send, we can thus
-                                        * temporarily disable write events
-                                        * for this descriptor.  client_write()
-                                        * will re-enable it as necessary.
-                                        */
-                                       kqueue_sev_alloc(1);
-                                       kqueue_sev_add(c->fd, EVFILT_WRITE,
-                                           EV_DISABLE, 0, 0, (intptr_t)c);
-                                       c->writepolling = 0;
-                               }
-                               continue;
-                       }
-
-                       if (kev->filter == EVFILT_READ) {
-                               int16_t         *buf;
-                               size_t          size;
-
-                               /*
-                                * Data to read from client.  Simply read it
-                                * into a queue to process it at the next
-                                * server heartbeat event.
-                                * XXX We should be able to process ping
-                                * requests immediately.  This means that
-                                * we need recvq_read() to report more
-                                * information.
-                                */
-                               if (recvq_read(&c->recvq, &buf, &size) == -1) {
-                                       client_destroy_mark(c);
-                                       continue;
-                               }
-
-                               /* Convert packet_type to host endian */
-                               *buf = BYTEORDER_HOST16(*buf);
-
-                               /*
-                                * If ping packet, process immediately
-                                * and discard packet from recvq.
-                                * We only allow ping if c->askedping
-                                * is unset, and we set it.  It will be unset
-                                * at the next server heart beat.  This way,
-                                * we only allow clients to ping once per
-                                * frame at most.
-                                */
-                               if (*buf == CPACKET_PING &&
-                                   size == sizeof(struct cpacket_ping)) {
-                                       if (!c->authenticated ||
-                                           c->askedping ||
-                                           spacket_pong_send(c) == -1) {
-                                               client_destroy_mark(c);
-                                               continue;
-                                       }
-                                       recvq_rewind(&c->recvq, size);
-                               }
-
-                               continue;
-                       }
-
-               }
-               /* Destroy marked to be destroyed clients */
-               client_destroy_marked();
-       }
-       /* NOTREACHED */
-}
-
-
-/* Utility functions */
-
-inline void
-kqueue_sev_alloc(int n)
-{
-
-       if (sev_cnt > S_EVENTS - n) {
-               if (kevent(kqid, sev, sev_cnt, NULL, 0, NULL) == -1)
-                       syslog(LOG_NOTICE,
-                           "kqueue_sev_alloc() - kevent() - %s",
-                           strerror(errno));
-               sev_cnt = 0;
-       }
-}
-
-inline void
-kqueue_sev_add(uintptr_t ident, uint32_t filter, uint32_t flags,
-    uint32_t fflags, int64_t data, intptr_t udata)
-{
-
-       /*
-        * Be careful to avoid macro side effects, do not use &sev[sev_cnt++]
-        */
-       EV_SET(&sev[sev_cnt], ident, filter, flags, fflags, data, udata);
-       sev_cnt++;
-}
diff --git a/tests/kqueue/kqueue.h b/tests/kqueue/kqueue.h
deleted file mode 100644 (file)
index 700e063..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id: kqueue.h,v 1.4 2006/04/01 00:46:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _KQUEUE_H_
-#define _KQUEUE_H_
-
-
-
-#include <sys/event.h>
-#include <sys/time.h>
-
-
-
-void           kqueue_init(void);
-void           kqueue_addlisten(int);
-void           kqueue_addsignal(int);
-void           kqueue_addtimer0(int64_t);
-void           kqueue_main(void);
-inline void    kqueue_sev_alloc(int);
-inline void    kqueue_sev_add(uintptr_t, uint32_t, uint32_t, uint32_t,
-                   int64_t, intptr_t);
-
-
-
-#endif
diff --git a/tests/kqueue/main.c b/tests/kqueue/main.c
deleted file mode 100644 (file)
index 24611a0..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $Id: main.c,v 1.10 2006/04/01 00:46:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include <mmpool.h>
-#include <mmlist.h>
-
-#include "daemon.h"
-#include "net.h"
-#include "sendq.h"
-#include "packets.h"
-#include "client.h"
-#include "conf.h"
-#include "kqueue.h"
-
-
-
-int                    main(int, char **);
-
-
-
-int
-main(int argc, char **argv)
-{
-
-       (void) openlog("daemon", LOG_NDELAY | LOG_PID, LOG_USER);
-
-       if (daemon_init() != 0)
-               exit(EXIT_FAILURE);
-       syslog(LOG_NOTICE, "Started");
-
-       /*
-        * The following funtions exit whenever there's a problem, because
-        * they set up critical things.
-        */
-       client_init();
-       kqueue_init();
-       net_init();
-       kqueue_addlisten(listen_fd);
-       kqueue_addsignal(SIGTERM);
-       kqueue_addtimer0(FPS_MS);
-
-       kqueue_main();
-       /* NOTREACHED */
-
-       return EXIT_SUCCESS;
-}
diff --git a/tests/kqueue/net.c b/tests/kqueue/net.c
deleted file mode 100644 (file)
index 6202c98..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* $Id: net.c,v 1.2 2006/04/01 00:46:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <sys/types.h>
-#include <syslog.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <netdb.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <mmstring.h>
-
-#include "net.h"
-#include "conf.h"
-
-
-
-static int     net_listen(const char *, int, int);
-
-
-
-int    listen_fd;
-
-
-
-void
-net_init(void)
-{
-
-       if ((listen_fd = net_listen("0.0.0.0", 7777, MAX_CLIENTS)) == -1) {
-               syslog(LOG_NOTICE, "net_listen() - %s", strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-}
-
-static int
-net_listen(const char *addr, int port, int backlog)
-{
-       int                     fd, opt;
-       struct linger           linger;
-       struct protoent         *pent;
-       struct sockaddr_in      server;
-
-       fd = -1;
-
-       mm_memclr(&server, sizeof(struct sockaddr_in));
-       server.sin_family = AF_INET;
-       if (inet_pton(AF_INET, addr, &server.sin_addr) != 1) {
-               syslog(LOG_NOTICE, "inet_pton(%s) - %s", addr,
-                   strerror(errno));
-               goto err;
-       }
-       server.sin_port = htons((short)port);
-
-       if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-               syslog(LOG_NOTICE, "socket() - %s", strerror(errno));
-               goto err;
-       }
-
-       opt = 1;
-       if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)))
-           == -1)
-               syslog(LOG_NOTICE, "setsockopt(SO_REUSEADDR) - %s",
-                   strerror(errno));
-       if ((setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(int)))
-           == -1)
-               syslog(LOG_NOTICE, "setsockopt(SO_KEEPALIVE) - %s",
-                   strerror(errno));
-
-       linger.l_onoff = 0;
-       linger.l_linger = 0;
-       if ((setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger,
-           sizeof(struct linger))) == -1)
-               syslog(LOG_NOTICE, "setsockopt(SO_LINGER) - %s",
-                   strerror(errno));
-
-       /* XXX Set buffer sizes? */
-
-       if ((pent = getprotobyname("TCP")) != NULL) {
-               opt = 1;
-               if ((setsockopt(fd, pent->p_proto, TCP_NODELAY, &opt,
-                   sizeof(int))) == -1)
-                       syslog(LOG_NOTICE, "setsockopt(TCP_NODELAY) - %s",
-                           strerror(errno));
-       } else
-               syslog(LOG_NOTICE, "getprotobyname(TCP) - %s",
-                   strerror(errno));
-
-       if ((opt = fcntl(fd, F_GETFL, NULL)) != -1) {
-               if (fcntl(fd, F_SETFL, opt | O_NONBLOCK) == -1) {
-                       syslog(LOG_NOTICE, "fcntl(F_SETFL) - %s",
-                           strerror(errno));
-                       goto err;
-               }
-       } else
-               syslog(LOG_NOTICE, "fcntl(F_GETFL) - %s", strerror(errno));
-
-       if ((bind(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)))
-           != 0) {
-               syslog(LOG_NOTICE, "bind(%s:%d) - %s", addr, port,
-                   strerror(errno));
-               goto err;
-       }
-
-       if (listen(fd, backlog) == -1) {
-               syslog(LOG_NOTICE, "listen(%s:%d) - %s", addr, port,
-                   strerror(errno));
-               goto err;
-       }
-
-       return fd;
-
-err:
-       if (fd != -1)
-               (void) close(fd);
-
-       return -1;
-}
diff --git a/tests/kqueue/net.h b/tests/kqueue/net.h
deleted file mode 100644 (file)
index 3607cc9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* $Id: net.h,v 1.2 2006/04/01 00:46:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _NET_H_
-#define _NET_H_
-
-
-
-void           net_init(void);
-
-
-
-extern int     listen_fd;
-
-
-
-#endif
diff --git a/tests/kqueue/packets.c b/tests/kqueue/packets.c
deleted file mode 100644 (file)
index 83da958..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/* $Id: packets.c,v 1.14 2006/04/03 20:38:43 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * To validate a received packet, we'll make sure that it's larger than
- * sizeof(int), and that the first integer consists of a valid expected packet
- * type ID within range.  If so, we verify if packet length really corresponds
- * to the packet type, and then can interpret the packet information.
- * An actual network packet may contain a number of these packets.
- * We thus must be able to efficiently determine each packet's length.
- * Since we're using TCP, it should be enough.  However, on the server side
- * especially, proper sanity checking on input must be done to avoid crashing
- * the server because of unexpected data processing.
- */
-
-
-
-#include <stdlib.h>
-
-#include <mmstring.h>
-#include <mmarch.h>
-
-#include "packets.h"
-#include "client.h"
-#include "sendq.h"
-#include "conf.h"
-
-
-
-static int     cpacket_auth_handler(client_t *, uint16_t *);
-static int     cpacket_ping_handler(client_t *, uint16_t *);
-static int     cpacket_pong_handler(client_t *, uint16_t *);
-static int     cpacket_direction_handler(client_t *, uint16_t *);
-static int     cpacket_thrust_handler(client_t *, uint16_t *);
-static int     cpacket_torp_handler(client_t *, uint16_t *);
-static int     cpacket_quit_handler(client_t *, uint16_t *);
-
-
-
-static struct packet_index     cpacket_index[CPACKET_MAX] = {
-       {sizeof(struct cpacket_auth), cpacket_auth_handler},
-       {sizeof(struct cpacket_ping), cpacket_ping_handler},
-       {sizeof(struct cpacket_pong), cpacket_pong_handler},
-       {sizeof(struct cpacket_direction), cpacket_direction_handler},
-       {sizeof(struct cpacket_thrust), cpacket_thrust_handler},
-       {sizeof(struct cpacket_torp), cpacket_torp_handler},
-       {sizeof(struct cpacket_quit), cpacket_quit_handler}
-};
-
-
-
-void
-update(void)
-{
-       node_t          *nod, *next;
-       client_t        *c;
-       uint8_t         *data;
-       size_t          size, off;
-
-       for (nod = DLIST_TOP(&clients_list); nod != NULL; nod = next) {
-               next = DLIST_NEXT(nod);
-               c = (client_t *)nod;
-
-               if (c->todestroy || c->toclose)
-                       continue;
-
-               /* Reset ping request throttling flag */
-               c->askedping = 0;
-
-               /* First process incomming packets */
-               recvq_content(&c->recvq, &data, &size);
-               for (off = 0; off < size; ) {
-                       int16_t *id;
-
-                       /*
-                        * Verify packet type ID. It already has been
-                        * converted to host endian byte order, unlike other
-                        * packet fields.
-                        */
-                       id = (int16_t *)&data[off];
-                       *id = BYTEORDER_HOST16(*id);
-                       if (*id < 0 || *id > CPACKET_MAX) {
-                               client_destroy_mark(c);
-                               break;
-                       }
-
-                       /* There must be enough data for packet size */
-                       if (size - off < cpacket_index[*id].size) {
-                               /*
-                                * Kill authentucated client if other packets
-                                * than CPACKET_AUTH
-                                */
-                               if (!c->authenticated && *id != CPACKET_AUTH)
-                                       goto k;
-
-                               /*
-                                * XXX We'll need to also do special
-                                * processing for chat packets, since they'll
-                                * have arbitrary length.  They'll still need
-                                * to be 16-bit aligned, too.
-                                */
-
-                               /* Kill client on packet processing error */
-                               if (cpacket_index[*id].handler(c,
-                                   (uint16_t *)off) == -1)
-                                       goto k;
-                       } else
-                               goto k;
-
-                       /* Process next packet if any */
-                       off += cpacket_index[*id].size;
-                       continue;
-
-k:
-                       client_destroy_mark(c);
-                       break;
-               }
-
-               /*
-                * XXX I don't like having to run the clients list all over,
-                * to then run through all objects (including clients) to
-                * update them, and then yet again through all objects to send
-                * updates to all clients.
-                */
-
-               /* Run game frame on all objects */
-               DLIST_FOREACH(&clients_list, nod) {
-                       client_t        *c = (client_t *)nod;
-
-                       /*
-                       if (!c->authenticated)
-                               continue;
-                        */
-
-                       /*
-                        * First update direction and thrust.
-                        * XXX I could do a small function or macro to deal
-                        * with similar situations, i.e.
-                        * change_update(int goal, int *current, int steps);
-                        */
-                       if (c->object.direction < c->object.i_direction)
-                               c->object.direction++;
-                       else if (c->object.direction > c->object.i_direction)
-                               c->object.direction--;
-                       if (c->object.thrust < c->object.i_thrust)
-                               c->object.thrust++;
-                       else if (c->object.thrust > c->object.i_thrust)
-                               c->object.thrust--;
-
-                       /*
-                        * Translate object x/y position according to
-                        * trust/direction.  When reaching borders we simply
-                        * bounce for now.
-                        * (I need to review my trigonometry a bit again :)
-                        */
-                       /* XXX */
-                       c->object.x += 1 - (random() & 2);
-                       if (c->object.x < 0)
-                               c->object.x = 0;
-                       else if (c->object.x > WORLD_X_MAX - 1)
-                               c->object.x = WORLD_X_MAX - 1;
-                       c->object.y += 1 - (random() & 2);
-                       if (c->object.y < 0)
-                               c->object.y = 0;
-                       else if (c->object.y > WORLD_Y_MAX - 1)
-                               c->object.y = WORLD_Y_MAX - 1;
-               }
-
-               /* Send update frame information packets */
-               DLIST_FOREACH(&clients_list, nod) {
-                       client_t        *c = (client_t *)nod;
-                       node_t          *nod2;
-
-                       /*
-                       if (!c->authenticated)
-                               continue;
-                        */
-
-                       DLIST_FOREACH(&clients_list, nod2) {
-                               if (spacket_position_send(c,
-                                   &((client_t *)nod2)->object) == -1)
-                                       break;
-                       }
-                       (void) sendq_flush(&c->sendq, -1);
-               }
-       }
-}
-
-
-int
-spacket_auth_send(client_t *c)
-{
-       struct spacket_auth     p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_AUTH);
-       mm_memclr(p.string, 32);
-       mm_strncpy(p.string, SERVER_STRING, 31);
-       p.protocol_version = BYTEORDER_NETWORK16(SERVER_VERSION);
-       /* XXX */
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 0);
-}
-
-int
-spacket_pong_send(client_t *c)
-{
-       struct spacket_pong     p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_PONG);
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 0);
-}
-
-int
-spacket_position_send(client_t *c, object_t *o)
-{
-       struct spacket_position p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_POSITION);
-       p.object_id = p.object_type = BYTEORDER_NETWORK16(0);   /* XXX */
-       p.x = BYTEORDER_NETWORK16(o->x);
-       p.y = BYTEORDER_NETWORK16(o->y);
-       p.direction - BYTEORDER_NETWORK16(o->direction);
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 1);
-}
-
-
-/* Note that only the packet_type field is endian converted yet. */
-
-static int
-cpacket_auth_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_auth     *p = (struct cpacket_auth *)ptr;
-
-       p->protocol_version = BYTEORDER_HOST16(p->protocol_version);
-
-       if (c->authenticated || p->protocol_version < SERVER_VERSION)
-               return -1;
-
-       /*
-        * XXX For now.  Eventually also check user/password
-        * We could use APOP-like authentication where server sends random
-        * data as part of the authentication greeting/request, and expect
-        * client to append password to random data and send hashed result.
-        * We also should do user concurrency checking here.
-        */
-       c->authenticated = 1;
-
-       return 0;
-}
-
-/*
- * Note: Following function is never used, since pings are handled in the
- * kqueue main loop code.
- */
-/* ARGSUSED */
-static int
-cpacket_ping_handler(client_t *c, uint16_t *ptr)
-{
-       /* NOOP */
-
-       return 0;
-}
-
-static int
-cpacket_pong_handler(client_t *c, uint16_t *ptr)
-{
-/*     struct cpacket_pong     *p = (struct cpacket_pong *)ptr;*/
-
-       /* XXX */
-
-       return 0;
-}
-
-static int
-cpacket_direction_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_direction        *p = (struct cpacket_direction *)ptr;
-
-       p->direction = BYTEORDER_HOST16(p->direction);
-
-       /* Radians */
-       if (p->direction < 0 || p->direction > 1000)
-               return -1;
-
-       c->object.i_direction = p->direction;
-
-       return 0;
-}
-
-static int
-cpacket_thrust_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_thrust   *p = (struct cpacket_thrust *)ptr;
-
-       p->thrust = BYTEORDER_HOST16(p->thrust);
-
-       if (p->thrust < 0 || p->thrust > 20)
-               return -1;
-
-       c->object.i_thrust = p->thrust;
-
-       return 0;
-}
-
-static int
-cpacket_torp_handler(client_t *c, uint16_t *ptr)
-{
-/*     struct cpacket_torp     *p = (struct cpacket_torp *)ptr;*/
-
-       /* XXX */
-
-       return 0;
-}
-
-/* ARGSUSED */
-static int
-cpacket_quit_handler(client_t *c, uint16_t *ptr)
-{
-
-       return -1;
-}
diff --git a/tests/kqueue/packets.h b/tests/kqueue/packets.h
deleted file mode 100644 (file)
index ea668d1..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $Id: packets.h,v 1.9 2006/04/03 20:37:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * All packets must begin with an int16_t packet_type.  All fields of a packet
- * must either be [u]int8_t, [u]int16_t, [u]int32+t or [u]int64_t.  Moreover,
- * all fields will be passed in network/big endian byte order when sent over
- * the network.  We could have used a union, but this would have resulted in
- * larger, fixed sized packets wasting bandwidth.  Since a server to client
- * update will generally involve sending more than one such packet in a row,
- * it is important to minimize their size.
- * Note: If using 32-bit fields within a packet, make sure that they are
- * 32-bit aligned.
- */
-
-
-
-#ifndef _PACKETS_H_
-#define _PACKETS_H_
-
-
-
-#include <sys/types.h>
-
-#include "client.h"
-
-
-
-/*
- * For every server packet type we support, an index array will be used
- * with this structure to call the associated handler function, which will
- * perform sanity checking and process the packet, returning 0 on success or
- * -1 on error.  The size field will allow to perform sanity checking on
- * data size prior to calling the handler function, as well as to increase the
- * buffer pointer.
- */
-struct packet_index {
-       size_t  size;
-       int     (*handler)(client_t *, uint16_t *);
-};
-
-
-
-/*
- * Server to client packets
- */
-
-enum spacket_types {
-       SPACKET_AUTH = 0,
-       SPACKET_PING,
-       SPACKET_PONG,
-       SPACKET_POSITION,
-       SPACKET_COLLISION,
-       SPACKET_MAX
-};
-
-/* Used to request client authentication and respond success/failure */
-struct spacket_auth {
-       int16_t packet_type;
-       int16_t protocol_version;
-       char    string[32];
-       /* XXX */
-} __attribute__((__packed__));
-
-/* And for server to test idle connections */
-struct spacket_ping {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* And clients to test latency */
-struct spacket_pong {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* Object position/direction update to client */
-struct spacket_position {
-       int16_t packet_type;
-       int16_t object_id, object_type;
-       int16_t x, y, direction;
-} __attribute__((__packed__));
-
-/* Collision/detonation update to client */
-struct spacket_collision {
-       int16_t packet_type;
-       int16_t collision_type;
-       int16_t object1_id, object2_id;
-} __attribute__((__packed__));
-
-
-
-/*
- * Client to server packets
- */
-
-enum cpacket_tyoes {
-       CPACKET_AUTH = 0,
-       CPACKET_PING,
-       CPACKET_PONG,
-       CPACKET_DIRECTION,
-       CPACKET_THRUST,
-       CPACKET_TORP,
-       CPACKET_QUIT,
-       CPACKET_MAX
-};
-
-/* Used to respond to server authentication request */
-struct cpacket_auth {
-       int16_t packet_type;
-       int16_t protocol_version;
-       char    string[32];
-       /* XXX */
-} __attribute__((__packed__));
-
-/* To ping server for latency mesurement */
-struct cpacket_ping {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* To respond to server ping requests */
-struct cpacket_pong {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* Angle/direction change request */
-struct cpacket_direction {
-       int16_t packet_type;
-       int16_t direction;
-} __attribute__((__packed__));
-
-/* Speed change request */
-struct cpacket_thrust {
-       int16_t packet_type;
-       int16_t thrust;
-} __attribute__((__packed__));
-
-/* Torpedo fire request */
-struct cpacket_torp {
-       int16_t packet_type;
-       int16_t direction;
-} __attribute__((__packed__));
-
-/* Game quit request */
-struct cpacket_quit {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-
-
-void           update(void);
-int            spacket_auth_send(client_t *);
-int            spacket_pong_send(client_t *);
-int            spacket_position_send(client_t *, object_t *);
-
-
-
-#endif
diff --git a/tests/kqueue/recvq.c b/tests/kqueue/recvq.c
deleted file mode 100644 (file)
index 663ecba..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $Id: recvq.c,v 1.5 2006/04/05 09:19:16 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "recvq.h"
-
-
-
-int
-recvq_init(recvq_t *q, int fd, size_t size)
-{
-
-       if ((q->buffer = malloc(size)) == NULL)
-               return -1;
-
-       q->fd = fd;
-       q->size = size;
-       q->tail = 0;
-
-       return 0;
-}
-
-void
-recvq_destroy(recvq_t *q)
-{
-
-       free(q->buffer);
-}
-
-int
-recvq_read(recvq_t *q, int16_t **buf, size_t *size)
-{
-       ssize_t s;
-
-       if (q->tail == q->size)
-               return -1;
-
-       if (((s = read(q->fd, &q->buffer[q->tail], q->size - q->tail)) == -1 &&
-           errno != EAGAIN) || s == 0)
-               return -1;
-
-       /*
-        * Verify that s is a multiple of 2 before accepting it.  This will
-        * allow all packets and their fields to be 16-bit aligned.
-        */
-       if (((uint16_t)s & 1) != 0) {
-               syslog(LOG_NOTICE, "Uneven packet from %d", q->fd);
-               return -1;
-       }
-
-       *buf = (int16_t *)&q->buffer[q->tail];
-       *size = s;
-       q->tail += s;
-
-       return 0;
-}
-
-/*
- * Useful to discard ping packets which we process on the fly
- */
-void
-recvq_rewind(recvq_t *q, size_t size)
-{
-
-       if (q->tail >= size)
-               q->tail -= size;
-}
-
-void
-recvq_content(recvq_t *q, uint8_t **buf, size_t *size)
-{
-
-       *buf = (uint8_t *)q->buffer;
-       *size = q->tail;
-       q->tail = 0;
-}
diff --git a/tests/kqueue/recvq.h b/tests/kqueue/recvq.h
deleted file mode 100644 (file)
index 54e6eee..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $Id: recvq.h,v 1.4 2006/04/03 20:37:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _RECVQ_H_
-#define _RECVQ_H_
-
-
-
-#include <sys/types.h>
-
-
-
-typedef struct recvq {
-       int     fd;
-       uint8_t *buffer;
-       size_t  size, tail;
-} recvq_t;
-
-
-
-int    recvq_init(recvq_t *, int, size_t);
-void   recvq_destroy(recvq_t *);
-int    recvq_read(recvq_t *, int16_t **, size_t *);
-void   recvq_rewind(recvq_t *, size_t);
-void   recvq_content(recvq_t *, uint8_t **, size_t *);
-
-
-
-#endif
diff --git a/tests/kqueue/sendq.c b/tests/kqueue/sendq.c
deleted file mode 100644 (file)
index 7ea0052..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/* $Id: sendq.c,v 1.5 2006/04/03 20:37:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <mmlist.h>
-#include <mmstring.h>
-
-#include "sendq.h"
-
-
-
-/*
- * Initializes a sendq object, allocating the queue buffer
- */
-int
-sendq_init(sendq_t *q, int fd, size_t size)
-{
-
-       if ((q->buffer = malloc(size)) == NULL)
-               return -1;
-
-       q->fd = fd;
-       q->size = size;
-       q->head = q->tail = 0;
-
-       return 0;
-}
-
-/*
- * Destroys a sendq object, freeing the queue buffer
- */
-void
-sendq_destroy(sendq_t *q)
-{
-
-       free(q->buffer);
-}
-
-/*
- * Attempts to write to the non-blocking socket.  In the case of a partial
- * write, queue the remaining of the buffer.  In case where the buffer is
- * full, return an error (-1), in which case the sendq has been exceeded and
- * client should be dropped.  We only write(2) if there is no pending buffers
- * already, of course.  If bfunc is not NULL, it will be called with passed
- * argument bfuncarg whenever data that couldn't be written immediately is
- * buffered.  If buffer is true, no attempt will be made at a real write; Data
- * will simply be buffered if possible.
- *
- * XXX There is a potential problem where if the client is lagged enough to
- * have filled the buffer, although not enough to exceed the queue but that
- * the client cannot recoup, we could consider the queue filled and drop the
- * client.  This because we aren't really using a real FIFO buffer.  This code
- * should probably use the mmfifo(3) library after the multiple bytes buffer
- * functions in it have been debugged and tested properly.
- * However, since if the user was this behind this would in practice mean that
- * his commands would take a while to be reflected, this is probably okay for
- * the time being.
- */
-int
-sendq_write(sendq_t *q, uint8_t *buf, size_t size,
-    void (*bfunc)(void *), void *bfuncarg, int buffer)
-{
-
-       /* Sendq empty?  Attempt to write(2) immediately */
-       if (!buffer && q->head == q->tail) {
-               ssize_t s;
-
-               /* Only allow EAGAIN */
-               if ((s = write(q->fd, buf, size)) == -1 && errno != EAGAIN)
-                       return -1;
-
-               /*
-                * If we wrote everything, simply return successfuly.
-                * Otherwise, fix our arguments to the unwritten buffer.
-                */
-               if (s == size)
-                       return 0;
-               else {
-                       size -= s;
-                       buf += s;
-               }
-       }
-
-       /*
-        * If the sendq buffer wasn't empty, or that there remains bytes
-        * after a partial write(2), queue the buffer if there's enough room.
-        * If there isn't enough room, return error.  If a function was
-        * supplied with an argument, also call this function if we buffer
-        * data.  This may allow our caller to enable back write polling
-        * events for this descriptor.
-        */
-       if (size > 0) {
-               if (q->tail + size > q->size)
-                       return -1;
-
-               (void) mm_memcpy(&q->buffer[q->tail], buf, size);
-               q->tail += size;
-               if (bfunc != NULL)
-                       bfunc(bfuncarg);
-       }
-
-       return 0;
-}
-
-/*
- * If any pending buffers exist, attempts to write them.  In the case of an
- * error, returns -1, in which case the client should be dropped.  If there
- * still remains unflushed data, 1 is returned.  Otherwise, 0 is.
- */
-int
-sendq_flush(sendq_t *q, size_t room)
-{
-
-       if (q->head != q->tail) {
-               ssize_t ns;
-               size_t  os = q->tail - q->head;
-
-               /* Only attempt write(2) syscall if there is room */
-               if (room == 0)
-                       return 1;
-
-               if ((ns = write(q->fd, &q->buffer[q->head], os)) == -1) {
-                       if (errno == EAGAIN)
-                               return 1;
-                       else
-                               return -1;
-               }
-
-               if ((q->head += ns) == q->tail)
-                       q->head = q->tail = 0;
-               else
-                       return 1;
-       }
-
-       return 0;
-}
diff --git a/tests/kqueue/sendq.h b/tests/kqueue/sendq.h
deleted file mode 100644 (file)
index 022543f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $Id: sendq.h,v 1.5 2006/04/03 20:37:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef _SENDQ_H_
-#define _SENDQ_H_
-
-
-
-#include <sys/types.h>
-
-#include <mmlist.h>
-
-
-
-typedef struct sendq {
-       int     fd;
-       uint8_t *buffer;
-       size_t  size, head, tail;
-} sendq_t;
-
-
-
-int    sendq_init(sendq_t *, int, size_t);
-void   sendq_destroy(sendq_t *);
-int    sendq_write(sendq_t *, uint8_t *, size_t, void (*)(void *), void *,
-           int);
-int    sendq_flush(sendq_t *, size_t);
-
-
-
-#endif
diff --git a/tests/memory/README b/tests/memory/README
deleted file mode 100644 (file)
index 52e022f..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-$Id: README,v 1.1 2005/11/14 01:55:20 mmondor Exp $
-
-The goal of this project is to create new memory allocation functions
-which can work on arbitrary pools of memory, while making sure to always
-favor low, already used pages.
-
-For instance, let's consider the case where multiple processes need to
-use a fair amount of shared memory.  The master process can allocate a
-region of memory using mmap(2) with MAP_ANON, making sure to use a large
-enough block that'll ever be used by the application.  This region can
-be shared.
-
-UVM lazily allocates pages which need to be accessed on-the-fly. This
-means that we must use a system similar to brk(2)/sbrk(2) and favor reusing
-already allocated memory in order to avoid the application growing too much.
-The process stack is for instance allocated this way;  A single very large
-region is mapped, and the actual memory in use increases with the process'
-requirements for more stack space.  In the case of stacks, since they are
-indeed stacks, the growing problem is not critical and easily determined.
-
-In the case of a general purpose memory allocator, this is more complex.
-mmpool(3) library allows to allocate fixed sized objects efficiently and
-makes sure to favor recently used pages in the allocations, which is okay.
-However, mmpool(3) must also be given allocation/freeing functions which
-it must use to allocate more pages as needed, or to free pages which haven't
-been used for some time.  This is where the general purpose allocators
-are used.
-
-In the case where a whole fixed large region can be used to allocate a single
-type of objects, we can simply use mmpool(3) and let it manage the large
-memory page.  However, needing to allocate a new memory segment per memory
-pool or object type appears problematic in some situations.  Moreover, being
-able to use a single large region for shared memory, another one for
-process-specific or shared mlocked memory per application, makes things
-easier.  It also allows server administrators to more easily modify various
-parameters relating to application scalibility.
-
-So this general purpose memory allocator should work on arbitrary regions
-of memory, and should automatically perform any necessary locking for
-synchronization.  This is quite similar to the libmm library in use by the
-Apache server.  This however should be released under BSD license, and
-especially favor reusing of previously allocated pages.
diff --git a/tests/pthread/README b/tests/pthread/README
deleted file mode 100644 (file)
index 3e70865..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-$Id: README,v 1.2 2007/03/04 08:32:31 mmondor Exp $
- vim:tw=66:ai:
-
-Copyright (c) 2007, Matthew Mondor
-ALL RIGHTS RESERVED.
-
-
-The status of POSIX threads on the NetBSD operating system
-==========================================================
-
-For a long while (until 2.0 release) NetBSD had no native POSIX
-threading interface.  It had support for kernel threads and
-processes only, and required external user 1:N thread library
-packages to support the pthread interface (using sigaltstack(2) or
-equivalent and a polling scheduler around select(2) or equivalent,
-nor providing pre-emptive threads).  This means that special care
-had to be taken by the programmer not to starve other threads
-performing number crunching without yielding explicitely, or block
-the whole process by using unwrapped blocking syscalls.
-Unproven-threads, and GNU Pth could be used, which would provide
-non-blocking wrappers around the blocking I/O syscalls.
-
-Starting from 2.0, NetBSD shipped with a native M:N POSIX threads
-implementation using Scheduler Activations.  This implementation,
-still used in a more mature form in NetBSD 4.x, works with an
-impressive performance on uniprocessor systems.  It also conforms
-very well to the standard on various tricky aspects on which
-LinuxThreads failed to comply (one of the reasons LPTL replaced
-them on Linux).  However, the multiprocessor support or adjustable
-PTHREAD_CONCURRENCY still has stability issues on v4.
-
-That M:N model relied on a userland library making use of
-Scheduler Activations in order to only spawn as many Light Weight
-Processes (actual real kernel supported threads in the same
-process) as required, such that non-blocking I/O operations and
-such done by many threads may be done more efficiently with fewer
-CPU/kernel context switches.
-
-On NetBSD -current (4.99.x), it was considered that the Scheduler
-Activations system on which the previous M:N model was implemented
-had scalibility issues as well as major problems to adapt to
-multi-processor systems.  Since the SA author and other developers
-did not put efforts into re-writing or major rehauling SA, the
-threading model was changed to a 1:1 model.
-
-This occurred as major work was being done on better locking (in
-an effort to eliminate the big lock).  To prevent M:N from hindering
-SMP enhancements a migration was made from M:N to a 1:1 model,
-that-is, one LWP per thread such as is the case for Linux, Solaris
-(which used to support an M:N model but dropped it at some point,
-apparently because of complexity issues), and other BSDs.
-
-
-M:N could scale in all situations
-=================================
-
-Although the current 1:1 model is all good for SMP, the performance
-on uniprocessors was still unprecendented by the M:N model.
-Moreover, if SA was re-written, or that another M:N threading model
-was developped, it could still benefit both uniprocessor and
-multiprocessor ones while scaling potentially even better than 1:1
-with SMP.
-
-Therefore while thinking about the problem here and then and
-through various tests, notes will be taken here on various ideas
-through which a new M:N model could be developped.  If I am
-eventually able to dedicate enough time and resources, an
-alternative pthread library might be written here as well, which
-could potentially be submitted for testing and review to NetBSD
-developers for eventual inclusion in v5 or v6 release.
-
-
-Various challenges and ideas
-============================
-
-- A kqueue userland thread scheduler could be written, although it
-  would probably need some support similar to AIO for disk I/O
-  operations which could be blocking.
-
-- A function can be called by libc prior to main() call to setup
-  the threading library.  However, a non-threading process is
-  considered to be a process with one single thread but which must
-  behave like traditionally.
-  Perhaps that the thread scheduler could be launched when the
-  first pthread_init() call is made.  The main LWP could become
-  the thread scheduler LWP.
-
-- Special minimal kernel support might be necessary for the
-  scheduler to detect efficiently when to spawn a new LWP in its
-  queue.
-
-- The scheduler should be able to automatically permanently bind
-  to a LWP a number-crunching thread which requires pre-emptive
-  yielding.
-  It is possible that we simply need to delegate to another LWP
-  any pre-empted operation done in the first LWP (which is also
-  the userland scheduler).
-
-- Actually, as long as pthread_create() was at least called once,
-  as soon as a all LWPs are preempted or blocked, a new LWP must
-  become available...
-
-- If the main LWP scheduler could perform all operations in a
-  non-blocking manner, only threads requireing pre-emption would
-  need to be mapped to a new LWP especially created for them...
-  However there may also be non-I/O blocking system and libc
-  calls.
-
-- The current LWP system doesn't have provision for asynchroneous
-  _lwp_wait() which would be needed for M:N pthread_join()
-  implementation.
-
-- It would also be nice to have configurable per-LWP CPU afinity.
diff --git a/tests/pthread_utils/GNUmakefile b/tests/pthread_utils/GNUmakefile
deleted file mode 100644 (file)
index dd75e9c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# $Id: GNUmakefile,v 1.5 2005/11/22 09:24:42 mmondor Exp $
-
-MMLIB_PATH := ../../mmlib
-MMLIBS := $(addprefix ${MMLIB_PATH}/,mmlog.o mmpool.o mmstring.o)
-OBJS := mm_pthread_msg.o mm_pthread_sleep.o mm_pthread_pool.o mm_pthread_poll.o
-BINS := tests/msg_test tests/poll_test
-
-CFLAGS += -Wall
-#CFLAGS += -DDEBUG -DPTHREAD_DEBUG -g3
-
-LDFLAGS += -lc -lpthread
-#LDFLAGS += -lpthread_dbg
-
-
-all: $(BINS)
-
-
-%.o: %.c
-       cc -c ${CFLAGS} -I. -I$(MMLIB_PATH) -o $@ $<
-
-
-tests/msg_test: tests/msg_test.o $(MMLIBS) $(OBJS)
-       cc ${CFLAGS} -o $@ $@.c $(OBJS) -I. -I$(MMLIB_PATH) ${LDFLAGS} \
-               $(MMLIBS)
-
-tests/poll_test: tests/poll_test.o $(MMLIBS) $(OBJS)
-       cc ${CFLAGS} -o $@ $@.c $(OBJS) -I. -I$(MMLIB_PATH) ${LDFLAGS} \
-               $(MMLIBS)
-
-
-install: all
-
-
-clean:
-       rm -f tests/msg_test.o tests/poll_test.o $(BINS) $(OBJS) $(MMLIBS)
diff --git a/tests/pthread_utils/README b/tests/pthread_utils/README
deleted file mode 100644 (file)
index 8054ac7..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-This library is an attempt to provide pth library like API to NetBSD SA
-threads and kqueue.
-
-What we find are missing from the POSIX standard are added here:
-
-- Implementation of efficient messages to communicate among threads. These
-  messages are queued using an efficient pointer linking mechanism. It must be
-  possible for a thread to wait for messages while sleeping and to be awaken
-  when a message is available. It also must be possible to observe a maximum
-  timeout to wait for.
-- Implementation of filedescriptors and above mentionned thread messages
-  notification multiplexing, with support for timer. An example of this is
-  pth library's pth_poll_ev(). A timer event can interrupt thread-safe
-  filedescriptor polling, as well as thread messages arriving on a port.
-
-We beleive that it is possible to implement this using the kqueue(2)/kevent(2)
-system. The new call would be similar to:
-
-pthread_poll(struct pollfd *fds, int nfds,
-       struct pthread_port *ports, int nports,
-       struct pthread_sigs *sigs, int nsigs,
-       struct pthread_timers *timers, int ntimers)
-
-or similar system. This would allow multiplexing of various events into a
-single application loop.
-
-
-pthread_cond_timedwait() seems especially useful, either with a signal handler
-or perhaps using kqueue concurrently... pthread_cond_timedwait() will allow
-processes to wait for message arrival though a port, while
-pthread_cond_signal() or pthread_cond_broadcast() will be able to awaken them
-as messages are queued to the message port. However, we would ideally want to
-only signal a wanted thread waiting for a port... But, normally only one
-thread should be listening for messages on any given port. I have to see what
-I'll do for a thread listening for messages on multiple ports at a time...
-Perhaps that multiple ports could use the same conditional wait variable so
-that the process would only wait on that one, and then verify the message
-queue for each before going back in waiting mode.
-
-
-TODO:
-====
-- Replace mutex and conditonal variable initializers, as well as attributes,
-  with static initializers.
-- Provide similar static intializer macros as part of our API where possible.
-- I have a working message passing implementation, with possibility of a
-  waiter on as many ports as wanted. I however still have a challenge:
-  Multiplex system calls such as select(2), poll(2), connect(2) and accept(2)
-  with the messaging capability. One must be able to cause the other to
-  return. This could be tricky to properly implement. Maybe think about the
-  following ideas:
-  - Dedicate a thread to serve a syscall, with which communication is solely
-    done using messages. This however implies that only a single syscall at a
-    time can be processed by such a thread. This probably means that a pool of
-    such threads would become necessary. This also assumes that the syscall in
-    question do not block the whole process, but only the intended thread.
-    Alot of assumptions, but this would now work properly on all BSDs and
-    on Linux. Possibly also on Solaris.
-  - Use a mix of signals and syscalls, since signals can interrupt syscalls.
-    However, this implies adding capability in our message system to trigger
-    signals rather than only using a conditional variable to notify of message
-    arrival. This also probably means that the same signal handler must be
-    shared by the whole process, that is, all the threads.
-  - Use kqueue in a thread-safe manner with thread-specific signals (if
-    possible). kqueue can be used to track signals without the need for an
-    actual signal handler. It would also track filedescriptor changes at the
-    same time. This also probably means that we need to use kqueue user
-    events if possible, triggered from the message passing system. It also
-    means non-portable code outside of the realm of BSD systems.
-
-
-
-RECENT REVIEW AFTER SOME REFLECTION
-===================================
-
-Currently, pth_accept_ev() and pth_connect_ev() are the only two cases of
-special PTh functions which my software uses, notably mmftpd(8). These could
-easily be implemented using a random thread in the pool whenever necessary,
-with which communication would entirely use messages only. This thread could
-be told: Perform syscall in non-blocking mode using the supplied
-filedescriptor and notify me weither it succeeded, failed because of a timeout,
-if any, or was interrupted by a message event occuring on the specified ring,
-if any. The application however has to know that if it was interrupted by
-an event, the connection still occurs asynchroneously within the system.
-We should verify what could be done to cancel a not yet completed connection,
-if possible. This call could also report if the call was interrupted by a
-signal arrival (EINTR), optionally. If the socket was supplied in blocking
-mode, it would have to be switched to non-blocking mode by the system and
-then back into blocking mode. The caller could ensure to set it into
-non-blocking mode for enhanced performance if no blocking mode is required.
-The challenge would be finding a both efficient and portable solution to
-have select()/poll() awake upon reception of notification events on a ring.
-Perhaps that a global filedescriptor could be used for this, SOCK_DGRAM and
-one byte sent, or that a signal handler with a signal generation should be
-used... Both methods would probably awake the whole process, however.
-pthread_sigmask() could be used perhaps... I wouldn't want to have a special
-fd required for each ready thread of the pool, ideally.
-
-Implement:
-mm_pthread_io          pthread_poll_ev(), pthread_accept_ev(),
-                               pthread_connect_ev()
-mm_pthread_alarm       pthread_sleep(), etc.
-
-or maybe:
-
-mm_pthread_misc                For all of them
-
-Perhaps reimplement the system I worked on in mmserver(3) as well. This might
-be necessary for operations which really should be dedicated to a non-threaded
-process at occasions, and the subsystem should be available. It should probably
-use a pool using mmpool(3) as well, just like we are doing with threads.
-
-It would be interesting to implement better GC for mmpool(3)'s. Currently,
-pool_free() will discard pages which are no longer in use since some time,
-but the time cannot be linear, since it only accounts a certain number of
-calls made to it. It should instead be possible to use time intervals, and
-to let the application invoke the GC at wanted fixed intervals. This would
-allow to use time based average statistics rather than function call times
-based ones, without clobbering process or thread timers which the application
-might need. It simply has to provide its own and to call the GC function
-regularily.
-
-Hmm also, would be nice to be able to store the port_t pointer of the port
-which triggered notification on a ring_t, so that callers don't need to
-run through several ports attached on a ring... Maybe that it would be
-problematic however, since we can't guarantee atomicity between messages and
-messages processing, unless we kludged the whole thing with locks and lost
-efficiency. And because we only trigger notification to wakeup a waiting
-thread when a message is queued on an empty port, it's possible that the
-applicaton sleeps forever on a port if it didn't totally empty it, unless
-there was a way for the sleep function to immediately return if called on
-non-empty ports (as it's only alled on rings, and that rings don't have
-access to a list of ports in current implementation (only the ports can
-know which ring they are tied to)... I could implement something to have
-rings see their attached ports with a list, however. But this again means
-looping among ports to see if they're non-empty, heh, so why not let the
-application do it as they do now.
-
-
-
-IMPORTANT
-=========
-
-I did a test where multiple threads were polling on a single filedescriptor
-consisting of a socketpair, which other side was used to wake them up.
-Only one random thread would wake up.
-
-Using a signal to cause all threads to wake would not work either, because
-then again only a random thread will awake.
-
-It appears that the only way to ensure to wake wanted threads is using
-conditional variables and for them to only sleep on these.
-
-SIGIO possibility... threads would be sleeping on a conditional wait variable
-corresponding to the filedescriptor. For polling, the fd would be made in
-non-blocking I/O, with SIGIO sent to process. The fd and associated cond var
-would be added to a table. The SIGIO signal handler would need to check all
-fds in the set for possible I/O and awake corresponding threads waiting on
-cond var. A problem exists: How to check a filedescriptor for pending event?
-How to know if event is read or write, or hup, etc? Maybe using more ore less
-standard FION ioctls? poll/select with 0 timeout maybe, but that is still
-troublesome in terms of performance I beleive.
-
-fd     cond    interesting_events      occured_events?
-
-Hmm and what if a thread was allocated to start polling, and another wrapper
-thread wait for it sleeping on a cond var? Would it be sane to do this?
-When a timeout or message occurs however detected by the wrapper thread,
-how would we stop the other thread polling? We still have a problem.
-If we left pending polling threads, how would a future thread with successful
-polling on the same descriptor ever wake up, a random one would.
-Why does POSIX threads suck so much as to not provide any decent way to
-work with filedescriptors!? If at least I had pthread_signal() it would
-help. I could send a signal to interrupt the wanted thread when it was polling.
-Or if only there was a way to set the wanted signal mask for wanted processes
-as necessary, so that I would only have the wanted one process a particular
-signal I could send to interrupt it and then restore the masks, and do this
-somehow atomically. If POSIX had any of these requirements in mind while
-developing the standard, pthread_poll_condwait() or pthread_signal() would
-already exist anyways!
-
-
-HMM
-===
-
-A thread reserved for polling would seem best. We need to be able to interrupt
-that thread whenever needed using a signal, which all other processes must
-be blocking. We could use SIGIO, or SIGUSR2 for instance. That thread would
-process thread messages and go back to polling. It probably could handle
-timeouts as well, but this is probably not necessary. If it did, would
-probably free other threads from calling gettimeofday() too often. The thread
-has to remove the fd from the polling list when an event returned on it
-anyways, and so it could also send a reply message for timeout. It has to
-be interrupted anyways when a new fd is to be added, and this means that
-it could fix the poll timer before calling it each time to fit the soonest
-to expire fd... I could probably use kqueue too, or libevent in that thread
-to make it high performance as possible.
diff --git a/tests/pthread_utils/mm_pthread_debug.h b/tests/pthread_utils/mm_pthread_debug.h
deleted file mode 100644 (file)
index 2db67bc..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $Id: mm_pthread_debug.h,v 1.2 2006/02/05 13:00:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2004-2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef MM_PTHREAD_DEBUG_H
-#define MM_PTHREAD_DEBUG_H
-
-
-
-#include <pthread.h>
-#include <syslog.h>
-
-
-
-#ifdef PTHREAD_DEBUG
-
-#define DEBUG_PTHREAD_ENTRY()  \
-       syslog(LOG_NOTICE, "> TID=%p FN=%s", pthread_self(), __func__)
-
-#define DEBUG_PTHREAD_EXIT()   \
-       syslog(LOG_NOTICE, "< TID=%p FN=%s", pthread_self(), __func__)
-
-#else
-#define DEBUG_PTHREAD_ENTRY()
-#define DEBUG_PTHREAD_EXIT()
-#endif
-
-
-
-#endif
diff --git a/tests/pthread_utils/mm_pthread_msg.c b/tests/pthread_utils/mm_pthread_msg.c
deleted file mode 100644 (file)
index d1fc7f0..0000000
+++ /dev/null
@@ -1,466 +0,0 @@
-/* $Id: mm_pthread_msg.c,v 1.14 2006/02/05 13:00:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * It is almost a shame that POSIX did not define a standard API for
- * inter-thread asynchroneous and synchroneous messaging.  So, here is my
- * implementation.  Note that for asynchroneous operation it is recommended to
- * use a memory pool such as mmpool(3) to allocate and free messages in an
- * efficient way, in cases where messages will need to be sent to the other
- * end without expecting a response back before the current function ends
- * (in which case a message obviously can't be on the stack).
- */
-
-
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <mmtypes.h>
-#include <mmlog.h>
-
-#include <mm_pthread_debug.h>
-#include <mm_pthread_msg.h>
-/*#include <mm_pthread_poll.h>*/
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mm_pthread_msg.c,v 1.14 2006/02/05 13:00:48 mmondor Exp $");
-
-
-
-/*
- * Allows to initialize a polling notification handle.  When attached to a
- * port, a message arriving on an empty port causes the associated ring to
- * wake the thread from pthread_ring_wait().
- */
-int
-pthread_ring_init(pthread_ring_t *ring)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(ring != NULL && ring->magic != PRING_MAGIC);
-
-       if ((error = pthread_cond_init(&ring->cond, NULL)) == 0) {
-               if ((error = pthread_mutex_init(&ring->mutex, NULL)) == 0) {
-                       ring->magic = PRING_MAGIC;
-                       ring->event = ring->mevent = 0;
-                       DEBUG_PTHREAD_EXIT();
-                       return 0;
-               }
-               (void) pthread_cond_destroy(&ring->cond);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Returns TRUE if the supplied ring is a valid/usable one, or FALSE
- * otherwise.  Useful to conditionally destroy it.
- */
-int
-pthread_ring_valid(pthread_ring_t *ring)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-
-       DEBUG_PTHREAD_EXIT();
-       return (ring != NULL && ring->magic == PRING_MAGIC);
-}
-
-/*
- * Destroys a ring.  Note that all message ports attached to this ring should
- * first be detached or destroyed.
- */
-int
-pthread_ring_destroy(pthread_ring_t *ring)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       if ((error = pthread_mutex_destroy(&ring->mutex)) == 0)
-               error = pthread_cond_destroy(&ring->cond);
-       ring->magic = 0;
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Causes the current thread to sleep until a message arrives on an empty port
- * associated with this ring.  In normal operation, a thread only goes in wait
- * mode after it processed all queued messages on all interesting ports.
- * However, provision is made so that a the function returns immediately if
- * messages already were received on a port attached to this ring since the
- * last call to pthread_ring_wait().
- * Although using such an absolute time timespec might be disadvantageous for
- * the API compared to a timeout in milliseconds for instance, this was chosen
- * to remain API-compatible with pthread_cond_timedwait(), and upwards
- * compatible with systems where nanosecond precision can be achieved.
- */
-int
-pthread_ring_wait(pthread_ring_t *ring, const struct timespec *abstime)
-{
-       int     error = 0;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       /* We must hold the condition variable's mutex */
-       if (pthread_mutex_lock(&ring->mutex) != 0) {
-               error = -1;
-               goto err;
-       }
-
-       /* As long as we don't have confirmation that we must stop waiting */
-       for (ring->event = 0; ring->mevent == 0 &&
-           !ring->event && error == 0; ) {
-               /*
-                * Wait on conditional variable, which will automatically
-                * and atomically release the mutex and return with the mutex
-                * locked again, as soon as the conditional variable gets
-                * signaled.
-                */
-               if (abstime != NULL) {
-                       error = pthread_cond_timedwait(&ring->cond,
-                           &ring->mutex, abstime);
-               } else
-                       error = pthread_cond_wait(&ring->cond, &ring->mutex);
-       }
-       ring->mevent = 0;
-
-       /*
-        * And we know that conditional waiting functions returned with mutex
-        * locked, so now release it back.
-        */
-       (void) pthread_mutex_unlock(&ring->mutex);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Allows to wake up waiter(s) on the specified ring, which are sleeping
- * threads within pthread_ring_wait().  This can be used to simulate the
- * arrival of a message on an empty port.  Also useful to use rings as a
- * notification system only when no message passing is needed.
- */
-int
-pthread_ring_notify(pthread_ring_t *ring)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       if ((error = pthread_mutex_lock(&ring->mutex)) == 0) {
-               ring->mevent++;
-               ring->event = 1;
-               (void) pthread_cond_signal(&ring->cond);
-               (void) pthread_mutex_unlock(&ring->mutex);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Allows to initialize/create a message port.
- */
-int
-pthread_port_init(pthread_port_t *port)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic != PPORT_MAGIC);
-
-       if ((error = pthread_mutex_init(&port->lock, NULL)) != 0)
-               goto err;
-
-       port->magic = PPORT_MAGIC;
-       port->ring = NULL;
-       DLIST_INIT(&port->messages);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Returns TRUE if the supplied port is valid/usable, or FALSE otherwise.
- * Useful to conditionally destroy a port, for instance.
- */
-int
-pthread_port_valid(pthread_port_t *port)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-
-       DEBUG_PTHREAD_EXIT();
-       return (port != NULL && port->magic == PPORT_MAGIC);
-}
-
-/*
- * Destroys the specified port, previously created using pthread_port_init().
- */
-int
-pthread_port_destroy(pthread_port_t *port)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       port->magic = 0;
-
-       DEBUG_PTHREAD_EXIT();
-       return pthread_mutex_destroy(&port->lock);
-}
-
-/*
- * Attaches a port to a ring.  Multiple ports may be attached to a ring.  A
- * message arriving on an empty port will cause the attached ring to be
- * notified, if any, and as such to cause a thread waiting on the ring to
- * be awakened.
- */
-int
-pthread_port_set_ring(pthread_port_t *port, pthread_ring_t *ring)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic == PPORT_MAGIC &&
-           (ring == NULL || ring->magic == PRING_MAGIC));
-
-       port->ring = ring;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-}
-
-/*
- * Allows to initialize a message before it can be sent over a port.  The
- * message only needs to be initialized once in general, even if it will be
- * used for bidirectional transmission for synchronous operation.  If the
- * reply port needs to be changed, however, this function should be used again
- * to set the new reply port.
- */
-int
-pthread_msg_init(pthread_msg_t *msg, pthread_port_t *rport)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(msg != NULL && msg->magic != PMESG_MAGIC &&
-           (rport == NULL || rport->magic == PPORT_MAGIC));
-
-       msg->magic = PMESG_MAGIC;
-       msg->reply = rport;
-       msg->size = 0;
-       msg->message = NULL;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-}
-
-/*
- * Returns TRUE if supplied message is valid/usable or FALSE otherwise.
- */
-int
-pthread_msg_valid(pthread_msg_t *msg)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-
-       DEBUG_PTHREAD_EXIT();
-       return (msg != NULL && msg->magic == PMESG_MAGIC);
-}
-
-/*
- * Invalidates a message, so that it can no longer be sent over ports.
- */
-int
-pthread_msg_destroy(pthread_msg_t *msg)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(msg != NULL && msg->magic == PMESG_MAGIC);
-
-       msg->magic = 0;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-}
-
-/*
- * If any message exists in the queue of the specified port, unqueues it and
- * returns it.  Otherwise, NULL is returned.  In normal operation, all messages
- * queued to a port are processed before putting the thread back into sleep,
- * mainly for efficiency, but also because it eases synchronization.
- */
-pthread_msg_t *
-pthread_msg_get(pthread_port_t *port)
-{
-       pthread_msg_t   *msg = NULL;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       if (pthread_mutex_lock(&port->lock) != 0)
-               goto err;
-
-       if ((msg = DLIST_TOP(&port->messages)) != NULL) {
-               DEBUG_ASSERT(msg->magic == PMESG_MAGIC);
-               DLIST_UNLINK(&port->messages, (node_t *)msg);
-       }
-
-       (void) pthread_mutex_unlock(&port->lock);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return (pthread_msg_t *)msg;
-}
-
-/*
- * Queues the specified message to the specified port, returning 0 on success.
- * Note that the message data is not copied or moved, but that a pointer
- * system is used to queue the message.  Thus, the message's shared memory
- * region is leased temporarily to the other end.  One has to be careful to
- * not allocate this message space on the stack when asynchroneous operation
- * is needed.  In synchroneous operation mode, it is not a problem, since the
- * sender does not have to modify the data until the other end replies back
- * with the same message after modifying the message if necessary.  In
- * synchroneous mode, we simply delegate that message memory region to the
- * other end until it notifies us with a reply that it is done working with
- * it.  Returns 0 on success, or an error number.
- */
-int
-pthread_msg_put(pthread_port_t *port, pthread_msg_t *msg)
-{
-       int     error = 0;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic == PPORT_MAGIC &&
-           msg != NULL && msg->magic == PMESG_MAGIC);
-
-       if ((error = pthread_mutex_lock(&port->lock)) != 0)
-               goto err;
-
-       DLIST_APPEND(&port->messages, (node_t *)msg);
-       if (port->ring != NULL) {
-               if (DLIST_NODES(&port->messages) == 1) {
-                       /*
-                        * We know that there previously were no messages,
-                        * and that the reading thread then waits for any
-                        * message to be available.  Signal it that there at
-                        * least is one message ready.  The other end should
-                        * normally process all available messages before
-                        * going back into waiting.
-                        */
-                       if ((error = pthread_mutex_lock(&port->ring->mutex))
-                           == 0) {
-                               port->ring->event = 1;
-                               (void) pthread_cond_signal(&port->ring->cond);
-                               (void) pthread_mutex_unlock(
-                                   &port->ring->mutex);
-                       }
-               }
-               /*
-                * If the other end, however, is already locked
-                * waiting for the ring to be notified while
-                * there already are messages, we still trigger mevent
-                * to cause it to unlock, however.  This behavior is
-                * useful in the polling system code, for instance.
-                */
-               /* XXX We don't use a mutex for now... */
-               port->ring->mevent++;
-       }
-
-       (void) pthread_mutex_unlock(&port->lock);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Meant to be used in synchroneous message transfer mode.  The initial sender
- * sends a message to the other end, which then uses this function to notify
- * back the initial sender that it is done, often with a success/failure
- * result as part of the message.  Returns 0 on success, or an error number.
- */
-int
-pthread_msg_reply(pthread_msg_t *msg)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(msg != NULL && msg->magic == PMESG_MAGIC &&
-           msg->reply != NULL);
-
-       DEBUG_PTHREAD_EXIT();
-       return pthread_msg_put(msg->reply, msg);
-}
-
-/*
- * Returns the number of pending messages tied to the port, if any, or -1
- * on error.
- */
-int
-pthread_port_pending(pthread_port_t *port)
-{
-       int     pending = -1;
-
-       DEBUG_PTHREAD_ENTRY();
-       DEBUG_ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       if (pthread_mutex_lock(&port->lock) != 0)
-               goto err;
-
-       pending = (int)DLIST_NODES(&port->messages);
-
-       (void) pthread_mutex_unlock(&port->lock);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return pending;
-}
diff --git a/tests/pthread_utils/mm_pthread_msg.h b/tests/pthread_utils/mm_pthread_msg.h
deleted file mode 100644 (file)
index 287bc2e..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* $Id: mm_pthread_msg.h,v 1.3 2005/09/15 11:46:58 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef MM_PTHREAD_MSG_H
-#define MM_PTHREAD_MSG_H
-
-
-
-#include <pthread.h>
-
-#include <mmtypes.h>
-#include <mmlist.h>
-
-
-
-#define PRING_MAGIC    0x50524e47
-#define        PPORT_MAGIC     0x50505254
-#define PMESG_MAGIC    0x504d5347
-
-typedef struct {
-       u_int32_t       magic;
-       pthread_cond_t  cond;
-       pthread_mutex_t mutex;
-       int             mode;
-       int             event;
-       int             mevent;
-} pthread_ring_t;
-
-enum pthread_ring_modes {
-       PTHREAD_RMOD_NOWAIT,
-       PTHREAD_RMOD_CONDWAIT,
-       PTHREAD_RMOD_FDWAIT
-};
-
-typedef struct {
-       u_int32_t       magic;
-       pthread_ring_t  *ring;
-       pthread_mutex_t lock;
-       list_t          messages;
-} pthread_port_t;
-
-typedef struct {
-       node_t          node;
-       u_int32_t       magic;
-       pthread_port_t  *reply;
-       size_t          size;
-       void            *message;
-} pthread_msg_t;
-
-
-
-extern int             pthread_ring_init(pthread_ring_t *);
-extern int             pthread_ring_valid(pthread_ring_t *);
-extern int             pthread_ring_destroy(pthread_ring_t *);
-extern int             pthread_ring_wait(pthread_ring_t *,
-                           const struct timespec *);
-extern int             pthread_ring_notify(pthread_ring_t *);
-
-extern int             pthread_port_init(pthread_port_t *);
-extern int             pthread_port_valid(pthread_port_t *);
-extern int             pthread_port_destroy(pthread_port_t *);
-extern int             pthread_port_set_ring(pthread_port_t *,
-                           pthread_ring_t *);
-extern int             pthread_msg_init(pthread_msg_t *,
-                           pthread_port_t *);
-extern int             pthread_msg_valid(pthread_msg_t *);
-extern int             pthread_msg_destroy(pthread_msg_t *);
-extern pthread_msg_t   *pthread_msg_get(pthread_port_t *);
-extern int             pthread_msg_put(pthread_port_t *,
-                           pthread_msg_t *);
-extern int             pthread_msg_reply(pthread_msg_t *);
-extern int             pthread_port_pending(pthread_port_t *);
-
-
-
-#endif
diff --git a/tests/pthread_utils/mm_pthread_poll.c b/tests/pthread_utils/mm_pthread_poll.c
deleted file mode 100644 (file)
index 36508b4..0000000
+++ /dev/null
@@ -1,1116 +0,0 @@
-/* $Id: mm_pthread_poll.c,v 1.15 2006/02/05 13:00:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * I consider this code to be a major hack around the inherent problems unix
- * systems face because of the lack of support for filedescriptor polling in
- * the POSIX threads API.  Although pthread defines methods for thread
- * synchronization and polling waiting for events (using conditionnal
- * variables), and that unix provides polling on filedescriptors using
- * select(2), poll(2), kqueue(2) and other mechanisms, both are totally
- * distinct entities which can be considered to either conflict with
- * eachother or to not be related enough in a unified way.  The current
- * situation makes it almost impossible for a thread to both be polling for
- * interthread efficient messages implementations built upon pthread, and
- * filedescriptor events, concurrently.
- *
- * The GNU PTH library implements non-standard functions which allow to
- * multiplex interthread messages and filedescriptor events, using for
- * instance pth_poll_ev(), pth_select_ev(), pth_accept_ev(), pth_connect_ev(),
- * etc.  However, this is internally implemented using a single large select(2)
- * based loop along with a slow large loop looking for non-fd events based on
- * the principles of libevent.  This threading library has other disadventages,
- * such as not providing a preemptive scheduler (being a fully userspace
- * implementation) and not allowing to scale to multiple processors on SMP
- * systems.  This interface however shows how good the POSIX threads API could
- * have been, if it was better designed with unix systems in mind.  This
- * library also being the most portable threads library alternative for quite
- * some time, because of the fact that Operating Systems implemented POSIX
- * threads inconsistently, or not at all, caused us to use PTH during some
- * time to develop software in cases where a pool of processes was not ideal
- * because of the frequency of shared memory synchronization needs.
- *
- * With the advent of POSIX threads implementations on more unix and unix-like
- * systems and of modern implementations behaving more consistently, which can
- * scale on SMP systems and provide preemptive scheduling, it was considered
- * worthwhile for us to adapt our software again to use the standard POSIX
- * API.  Especially considering that NetBSD which had no OS provided threads
- * implementation for applications now has an awesome pthreads implementation
- * starting with version 2.0. However, we encountered difficulties with some
- * software which used the complex multiplexing of thread events and
- * filedescriptor ones.  This module provides a solution to port this software.
- * It however is somewhat a hack.
- *
- * The downsides of this implementation are as follows.  We originally intended
- * to develop a system which would scale among an increasing number of threads
- * in a ready pool of threads, scaling with concurrency of the polling calls.
- * This however proved difficult, or impossible to achieve, the main reasons
- * being that 1) A signal delivered to a process is only received by a random
- * thread that is not blocking it.  2) In the case where multiple threads are
- * polling on a common file descriptor, similarily only one random thread
- * is awaken.  3) pthread_cond_signal() and pthread_cond_broadcast() cannot
- * wake threads waiting in filedescriptor polling.  4) to achieve what we
- * needed, two descriptors would have been necessary per notification ring.
- * this was considered an aweful solution and was promptly rejected.  5) The
- * POSIX API does not define a way for a process to set or change the signal
- * blocking masks of other threads on the fly.
- *
- * Our solution then had to rely on a main descriptor polling manager thread
- * which would be used to poll file descriptors, and would as a device serve
- * client threads via efficient interthread messages.  An issue still arises
- * when a client thread sends a message to the polling thread to add new
- * descriptors for polling or to cancel polling and remove descriptors.
- * The polling thread must be able to immediately process these events
- * awaking from filedescriptor polling.  Two possible hacks could be used for
- * this.  1) Use an AF_LOCAL SOCK_DGRAM socketpair(), which one side would
- * be used to trigger an event writing some data, and the other side always
- * included by the polling thread within the set of descriptors.  2) Send a
- * signal to the process which only the polling thread is not blocking,
- * to ensure that it be the one catching it, as such to awake from polling
- * with an EINTR error code.  This second solution was considered more elegant
- * and is used as the basis of this implementation.  We currently are
- * clubbering the SIGUSR2 signal to achieve this.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <poll.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <mmtypes.h>
-#include <mmlog.h>
-#include <mmlist.h>
-
-#include <mm_pthread_debug.h>
-#include <mm_pthread_msg.h>
-#include <mm_pthread_pool.h>
-#include <mm_pthread_poll.h>
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mm_pthread_poll.c,v 1.15 2006/02/05 13:00:48 mmondor Exp $");
-
-
-
-/*
- * Synchroneous communications message between arbitrary threads and the
- * polling thread.  Since communication is synchroneous, we only need to
- * allocate one such message per thread.  We are always expecting a reply
- * back after sending a query before reusing the buffer.  In fact, the
- * message passing system only serves as a means for synchronization around
- * the message, which is a shared memory object.
- */
-struct poll_msg {
-       pthread_msg_t   msgnode;
-       /* Passed as parameters */
-       bool            cancel;
-       struct pollfd   *fds;
-       nfds_t          nfds;
-       int             timeout;
-       /* Returned as result */
-       int             ready, error;
-       /* Internally used */
-       struct timeval  expires;
-};
-
-/*
- * An index is maintained of descriptor number -> poll_msg_index
- * structures.  Each of wich has information on the message the descriptor
- * belongs to, and the index into the pollfd array so that it be easy to
- * efficiently do per-fd work.
- */
-struct poll_idx {
-       int             idx;
-       struct poll_msg *msg;
-};
-
-/*
- * Thread specific needed resources to use our special polling
- */
-struct poll_data {
-       pthread_port_t  port;
-       struct poll_msg msg;
-};
-
-
-
-#define                        POLLWAKE()      do {                            \
-       pollingevents++;                                                \
-       if (polling != 0)                                               \
-               (void) kill(process_id, SIGUSR2);                       \
-} while (/* CONSTCOND */0)
-
-
-
-/*
- * Static functions prototypes
- */
-static int             pthread_poll_proc_init(void);
-static void            pthread_poll_proc_init2(void);
-static int             pthread_poll_thread_init(struct poll_data **);
-static void            pthread_poll_thread_exit(void *);
-static void            *poll_thread(void *);
-static int             poll_thread_attach_fds(struct poll_msg *);
-static void            poll_thread_detach_fds(struct poll_msg *);
-static void            poll_thread_sighandler(int);
-
-/*
- * Static process specific storage
- */
-static bool            pthread_poll_initialized = FALSE;
-static pthread_once_t  pthread_poll_proc_initialized = PTHREAD_ONCE_INIT;
-static pthread_key_t   pthread_poll_proc_key;
-static pthread_ring_t  pthread_poll_thread_started_ring;
-static pthread_port_t  pthread_poll_thread_port;
-static pid_t           process_id;
-static int             polling = 0;
-static int             pollingevents = 0;
-
-/*
- * Static global poll_thread storage.  No synhronization is necessary when
- * using these, since only the polling thread does.
- */
-static struct poll_idx *poll_idx;
-static nfds_t          poll_idx_size;
-static struct pollfd   *poll_fds;
-static nfds_t          poll_fds_size;
-static nfds_t          poll_nfds;
-
-
-
-/*
- * Static internal functions
- */
-
-static int
-pthread_poll_proc_init(void)
-{
-       int                     error;
-       struct sigaction        act;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if ((error = pthread_key_create(&pthread_poll_proc_key,
-           pthread_poll_thread_exit)) != 0)
-               goto err;
-
-       act.sa_handler = poll_thread_sighandler;
-       act.sa_flags = 0;
-       (void) sigemptyset(&act.sa_mask);
-       (void) sigaddset(&act.sa_mask, SIGUSR2);
-       if (sigaction(SIGUSR2, &act, NULL) != 0) {
-               error = errno;
-               goto err;
-       }
-
-       process_id = getpid();
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-static void
-pthread_poll_proc_init2(void)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if ((error = pthread_poll_proc_init()) != 0) {
-               (void) fprintf(stderr, "pthread_poll_proc_init() - %s\n",
-                   strerror(error));
-               DEBUG_PTHREAD_EXIT();
-               exit(EXIT_FAILURE);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-static int
-pthread_poll_thread_init(struct poll_data **res)
-{
-       int                     error;
-       struct poll_data        *data;
-       sigset_t                set;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       (void) sigemptyset(&set);
-       (void) sigaddset(&set, SIGUSR2);
-       (void) pthread_sigmask(SIG_BLOCK, &set, NULL);
-
-       if ((data = malloc(sizeof(struct poll_data))) == NULL) {
-               error = ENOMEM;
-               goto err;
-       }
-
-       if ((error = pthread_port_init(&data->port)) != 0)
-               goto err;
-       if ((error = pthread_msg_init(&data->msg.msgnode, &data->port)) != 0)
-               goto err;
-
-       if ((error = pthread_setspecific(pthread_poll_proc_key, data)) != 0)
-               goto err;
-
-       *res = data;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       if (data != NULL) {
-               (void) pthread_port_destroy(&data->port);
-               free(data);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-static void
-pthread_poll_thread_exit(void *specific)
-{
-       struct poll_data        *data = (struct poll_data *)specific;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       (void) pthread_port_destroy(&data->port);
-       (void) pthread_msg_destroy(&data->msg.msgnode);
-       free(data);
-
-       /*
-        * Some implementations need this
-        */
-       (void) pthread_setspecific(pthread_poll_proc_key, NULL);
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-
-/*
- * Actual polling thread, with which we communicate using messages polling on
- * pthread_port_t and pthread_ring_t.  This is the only thread that should be
- * catching SIGUSR2 signals (used to wake us up and reiterate our main loop.
- * Note: Although less efficient than using kqueue(2) or libevent(3), after
- * discussion with 3s4i we settled to using poll(2) for now, which minimizes
- * OS dependencies as well as third party software dependencies.  Because
- * pthread_poll_ring(2) is only sparsely used by our software (migrating from
- * using PTH library which provided pth_poll_ev()), and that we only provide
- * it small pollfd arrays, this implementation was considered to meet our
- * needs using poll(2). This also met the requirements for Tact group.
- */
-/* ARGSUSED */
-static void *
-poll_thread(void *args)
-{
-       sigset_t        set;
-       pthread_ring_t  ring;
-       list_t          msg_list;
-       register int    i;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       /*
-        * This initialization shouldn't fail.  If it did, it would be nice to
-        * be able to simply panic eventually. XXX
-        */
-
-       /*
-        * Create set for SIGUSR2 which we'll unblock/block
-        */
-       (void) sigemptyset(&set);
-       (void) sigaddset(&set, SIGUSR2);
-
-       /*
-        * Allocate an initial buffer size for our pollfd array as well as for
-        * our descriptor based index.  We'll double these buffers as
-        * necessary at runtime.
-        */
-       poll_fds_size = 64;
-       poll_fds = malloc(sizeof(struct pollfd) * poll_fds_size);
-       poll_nfds = 0;
-       poll_idx_size = 64;
-       poll_idx = malloc(sizeof(struct poll_msg) * poll_idx_size);
-       for (i = 0; i < poll_idx_size; i++)
-               poll_idx[i].msg = NULL;
-       DLIST_INIT(&msg_list);
-
-       /*
-        * Initialize message port and associated ring.  The message port is
-        * module global, so that it be public to pthread_poll_ring().
-        */
-       (void) pthread_port_init(&pthread_poll_thread_port);
-       (void) pthread_ring_init(&ring);
-       (void) pthread_port_set_ring(&pthread_poll_thread_port, &ring);
-
-       /*
-        * Notify parent that we're ready.
-        */
-       (void) pthread_ring_notify(&pthread_poll_thread_started_ring);
-
-       /*
-        * Main loop from which we never exit
-        */
-       for (;;) {
-               register int    n;
-               int             timeout;
-               struct timeval  tv, ttv;
-               struct poll_msg *msg, *nextmsg;
-
-               /*
-                * Get time of day in a rather high resolution.  We need to
-                * do this to be able to evaluate timeouts later on.  We
-                * attempt to only require one time syscall per loop.
-                */
-               (void) gettimeofday(&tv, NULL);
-
-               pollingevents = 0;
-
-               /*
-                * Process any messages.  We need to add the descriptors if
-                * they aren't already added.  Also store yet unsatisfied
-                * request messages into a list.
-                */
-               while ((msg = (struct poll_msg *)pthread_msg_get(
-                   &pthread_poll_thread_port)) != NULL) {
-                       if (msg->cancel) {
-                               /*
-                                * Immediately satisfy request on demand
-                                */
-                               msg->error = ECANCELED;
-                               DLIST_UNLINK(&msg_list, (node_t *)msg);
-                               poll_thread_detach_fds(msg);
-                               (void) pthread_msg_reply(&msg->msgnode);
-                               continue;
-                       }
-                       if (poll_thread_attach_fds(msg) == 0) {
-                               msg->ready = msg->error = 0;
-                               if (msg->timeout != -1) {
-                                       /*
-                                        * Convert millisecond timeout to an
-                                        * absolute time timeval
-                                        */
-                                       msg->expires.tv_sec = tv.tv_sec;
-                                       msg->expires.tv_usec = tv.tv_usec;
-                                       ttv.tv_sec = msg->timeout / 1000;
-                                       ttv.tv_usec = (msg->timeout % 1000)
-                                          * 1000;
-                                       timeradd(&msg->expires, &ttv,
-                                           &msg->expires);
-                               }
-                               DLIST_APPEND(&msg_list, (node_t *)msg);
-                       } else {
-                               msg->ready = 0;
-                               msg->error = EINVAL;
-                               (void) pthread_msg_reply(&msg->msgnode);
-                       }
-               }
-
-               /*
-                * Process timeouts.  For request messages which timed out,
-                * satisfy them immediately using ETIMEDOUT error.
-                * This also allows to evaluate which is the soonest to expire
-                * entry, which poll(2) will have to use as timeout.
-                */
-               ttv.tv_sec = ttv.tv_usec = 99999;
-               for (msg = DLIST_TOP(&msg_list); msg != NULL; msg = nextmsg) {
-                       nextmsg = DLIST_NEXT(msg);
-
-                       if (msg->timeout == -1)
-                               continue;
-                       if (timercmp(&msg->expires, &tv, <)) {
-                               msg->error = ETIMEDOUT;
-                               DLIST_UNLINK(&msg_list, (node_t *)msg);
-                               poll_thread_detach_fds(msg);
-                               (void) pthread_msg_reply(&msg->msgnode);
-                       } else if (timercmp(&msg->expires, &ttv, <)) {
-                               ttv.tv_sec = msg->expires.tv_sec;
-                               ttv.tv_usec = msg->expires.tv_usec;
-                       }
-               }
-
-               /*
-                * If there are no registered descriptors to poll for, wait
-                * using the thread friendly ring until messages occur, and
-                * reiterate.
-                */
-               if (poll_nfds == 0) {
-                       (void) pthread_ring_wait(&ring, NULL);
-                       continue;
-               }
-
-               /*
-                * Perform polling.  poll(2) for as much time as possible,
-                * although making sure to allow the soonest to expire query
-                * to stop polling.  Next to expire entry time is in ttv and
-                * current time in tv.  Calculate difference and convert to
-                * milliseconds.
-                */
-               if (ttv.tv_sec == 99999 && ttv.tv_usec == 99999)
-                       timeout = -1;
-               else {
-                       timersub(&ttv, &tv, &ttv);
-                       timeout = (ttv.tv_sec * 1000) + (ttv.tv_usec / 1000);
-               }
-
-               /*
-                * Unblock the SIGUSR2 signal, which we should be the only
-                * thread to receive, all other threads blocking it.
-                * Only leave it unblocked for the duration of the poll(2)
-                * syscall.  We cause our loop to reiterate in any case of
-                * error, EINTR or no file descriptor with pending event.
-                */
-               (void) pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-               polling++;
-
-               n = 0;
-               if (pollingevents != 0)
-                       goto unblock;
-
-               n = poll(poll_fds, poll_nfds, timeout);
-
-unblock:
-               polling--;
-               (void) pthread_sigmask(SIG_BLOCK, &set, NULL);
-               if (pollingevents != 0 || n < 1)
-                       continue;
-
-               /*
-                * Verify which descriptors have interesting events set,
-                * increasing events counter of corresponding requests.
-                */
-               for (i = 0; n != 0 && i < poll_nfds; i++) {
-                       if (poll_fds[i].revents != 0) {
-                               (poll_idx[poll_fds[i].fd].msg->ready)++;
-                               n--;
-                       }
-               }
-               /*
-                * Now verify pending request messages for events, and satisfy
-                * the requests of those who do.
-                */
-               for (msg = DLIST_TOP(&msg_list); msg != NULL; msg = nextmsg) {
-                       nextmsg = DLIST_NEXT(msg);
-
-                       if (msg->ready != 0) {
-                               /*
-                                * ready and error fields are already set
-                                */
-                               DLIST_UNLINK(&msg_list, (node_t *)msg);
-                               poll_thread_detach_fds(msg);
-                               (void) pthread_msg_reply(&msg->msgnode);
-                       }
-               }
-       }
-
-       /* NOTREACHED */
-       DEBUG_PTHREAD_EXIT();
-       pthread_exit(NULL);
-       return NULL;
-}
-
-/*
- * Permits to merge supplied pollfd set with the main set
- */
-static int
-poll_thread_attach_fds(struct poll_msg *msg)
-{
-       register int    i, fd, idx;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       for (i = 0; i < msg->nfds; i++) {
-               fd = msg->fds[i].fd;
-
-               /*
-                * Ignore unset descriptors
-                */
-               if (fd == -1)
-                       continue;
-
-               /*
-                * Grow index buffer if necessary.  Either grow by doubling
-                * size, or even more if necessary to hold index to fd.
-                * If we only grew to hold fd, we might need to realloc(3) too
-                * often.  Take care to also NULL msg field of new entries.
-                */
-               if (poll_idx_size <= fd) {
-                       struct poll_idx *idx;
-                       int             size, i2;
-
-                       size = poll_idx_size * 2;
-                       if (fd > size)
-                               size = fd;
-                       if ((idx = realloc(poll_idx,
-                           sizeof(struct poll_idx) * size)) == NULL)
-                               goto err;
-                       poll_idx = idx;
-                       for (i2 = poll_idx_size; i2 < size; i2++)
-                               poll_idx[i2].msg = NULL;
-                       poll_idx_size = size;
-               }
-
-               /*
-                * Error if descriptor not unique before adding to set.
-                * We do not allow multiple threads polling on the same
-                * descriptor at the same time in our system.  We would
-                * otherwise need to gracefully handle duplicates,
-                * multiplexing them, which isn't required at all by our
-                * applications.  So let's keep things simple.
-                */
-               if (poll_idx[fd].msg != NULL)
-                       goto err;
-
-               /*
-                * Resize pollfd array if needed.  Grow by doubling.
-                * This should happen very rarely.
-                * XXX We could check this condition only once at the
-                * top of this fonction and take in consideration the
-                * number of descriptors to add, if wanted for optimization.
-                */
-               if (poll_fds_size <= poll_nfds) {
-                       struct pollfd   *ptr;
-
-                       if ((ptr = realloc(poll_fds,
-                           sizeof(struct pollfd) * (poll_fds_size * 2)))
-                           == NULL)
-                               goto err;
-                       poll_fds = ptr;
-                       poll_fds_size *= 2;
-               }
-
-               /*
-                * Finally add descriptor to set and register it for indexing.
-                * We simply need to append it to the existing entries in our
-                * global polling set array.
-                */
-               idx = poll_nfds;
-               poll_fds[idx].fd = fd;
-               poll_fds[idx].events = msg->fds[i].events;
-               poll_fds[idx].revents = 0;
-               poll_idx[fd].msg = msg;
-               poll_idx[fd].idx = idx;
-               poll_nfds = ++idx;
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       (void) poll_thread_detach_fds(msg);
-
-       DEBUG_PTHREAD_EXIT();
-       return -1;
-}
-
-/*
- * Permits to disunite supplied pollfd set from the main set.  Also sets the
- * revents fields of the supplied set to the ones of the main set.
- */
-static void
-poll_thread_detach_fds(struct poll_msg *msg)
-{
-       register int    i, fd, idx;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       for (i = 0; i < msg->nfds; i++) {
-               fd = msg->fds[i].fd;
-
-               /*
-                * Make sure fd was properly registered
-                */
-               if (poll_idx[fd].msg != msg)
-                       continue;
-
-               /*
-                * Find index in global pollfd set for this fd
-                */
-               idx = poll_idx[fd].idx;
-
-               /*
-                * Update pollfd entry according to global one
-                */
-               msg->fds[i].revents = poll_fds[idx].revents;
-
-               /*
-                * Unlink fd from the global set.  The removal method is
-                * simple; Take the last entry of the global set and move it
-                * over the current entry, updating index links, and lower
-                * the gobal nfds by one.  If we're the last entry, simply
-                * remove it invalidating its index entry lowering the global
-                * nfds.
-                */
-
-               if (--poll_nfds != idx) {
-                       /*
-                        * Not last entry, move last entry over entry to
-                        * delete.
-                        */
-                       register struct pollfd  *deleted, *last;
-                       int                     deleted_fd, deleted_idx;
-
-                       last = &poll_fds[poll_nfds];
-                       deleted = &poll_fds[idx];
-                       deleted_fd = deleted->fd;
-                       deleted_idx = poll_idx[deleted_fd].idx;
-
-                        /* Copy last entry over deleted one */
-                       deleted->fd = last->fd;
-                       deleted->events = last->events;
-                       deleted->revents = last->revents;
-
-                       /*
-                        * Reindex last entry which was moved, don't touch
-                        * the msg pointer though.
-                        */
-                       poll_idx[last->fd].idx = deleted_idx;
-
-                       /* And finally invalidate last entry */
-                       poll_idx[deleted_fd].msg = NULL;
-               } else {
-                       /* Invalidate last entry */
-                       poll_idx[poll_fds[poll_nfds].fd].msg = NULL;
-               }
-       }
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-/*
- * Called upon reception of SIGUSR2
- */
-/* ARGSUSED */
-static void
-poll_thread_sighandler(int sig)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-
-       pollingevents++;
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-
-
-/*
- * Public API exported functions
- */
-
-/*
- * Must be called before launching any thread.  Sets up the signal mask and
- * launches the dedicated poll slave thread.  Important note: this system
- * clobbers the SIGUSR2 signal, which the application can no longer use for
- * other purposes.  The only solution to wake the thread manager thread from
- * poll(2) is either to trigger an event through a dedicated filedescriptor,
- * or to send a signal to the process which only the polling thread allows.
- */
-int
-pthread_poll_init(void)
-{
-       int             error;
-       sigset_t        set;
-       pthread_attr_t  attr;
-       pthread_t       thread;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (pthread_poll_initialized) {
-               error = 0;
-               goto err;
-       }
-
-       /*
-        * First block SIGUSR2 signal in the parent.  The reason why this must
-        * be called before the application launches any thread is that
-        * threads inherit the sigmask of their parent, and that all threads,
-        * but the polling thread, must block the signal.  This ensures that
-        * only the wanted thread wakes up when a SIGUSR2 signal is received.
-        * This way, we can interrupt the polling thread in poll(2), for
-        * instance, and cause it to reiterate its main loop.
-        */
-       (void) sigemptyset(&set);
-       (void) sigaddset(&set, SIGUSR2);
-       if ((error = pthread_sigmask(SIG_BLOCK, &set, NULL)) != 0)
-               goto err;
-
-       /*
-        * We'll use this pthread_ring_t to get notification from child that
-        * it is ready to process requests before proceeding.
-        */
-       if ((error = pthread_ring_init(&pthread_poll_thread_started_ring))
-           != 0)
-               goto err;
-
-       /*
-        * We may now launch the poll thread and wait for notification from it
-        * that it is ready to serve requests.  We won't need to exit this
-        * thread, so it can be launched in detached state.
-        */
-       if ((error = pthread_attr_init(&attr)) != 0)
-               goto err;
-       if ((error = pthread_attr_setdetachstate(&attr, TRUE)) != 0)
-               goto err;
-       if ((error = pthread_create(&thread, &attr, poll_thread, NULL)) != 0)
-               goto err;
-
-       /*
-        * Wait until thread is ready to serve requests
-        */
-       (void) pthread_ring_wait(&pthread_poll_thread_started_ring, NULL);
-
-       pthread_poll_initialized = TRUE;
-
-       return 0;
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * poll(2) replacement which can also be awakened by a notification happening
- * on the specified ring.  This for instance allows to process thread messages
- * as well as descriptor events.  Like poll(2), returns the number of
- * descriptors with events on success (can be 0), or returns -1 with the
- * specified error set in errno.  Unlike poll, the error ETIMEDOUT will occur
- * if the timeout expires before an event existed, or ECANCELLED if a ring
- * notification event occurred instead of a filedescriptor one.  Can also
- * return errors such as EINVAL.
- * XXX Check for ETIMEDOUT!  We probably don't do this yet.  Also, we could
- * return 0 in this case like poll(2).
- */
-int
-pthread_poll_ring(struct pollfd *fds, nfds_t nfds, int timeout,
-    pthread_ring_t *ring)
-{
-       int                     error;
-       struct poll_data        *data;
-       pthread_ring_t          *oring;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (!pthread_poll_initialized) {
-               error = EINVAL;
-               goto err;
-       }
-
-       /*
-        * Implicit process and thread specific initializations
-        */
-       if ((error =  pthread_once(&pthread_poll_proc_initialized,
-           pthread_poll_proc_init2)) != 0)
-               goto err;
-       /*
-        * XXX Use a mutex or pthread_once() equivalent here too?
-        */
-       if ((data = pthread_getspecific(pthread_poll_proc_key)) == NULL) {
-               if ((error = pthread_poll_thread_init(&data)) != 0)
-                       goto err;
-       }
-
-       /*
-        * Perform some sanity checking on supplied arguments
-        */
-       if (fds == NULL || nfds < 1 || ring == NULL || ring->magic !=
-           PRING_MAGIC) {
-               error = EINVAL;
-               goto err;
-       }
-
-       /*
-        * Ensure that our message port's ring uses the same ring which
-        * the user supplies us.  If we didn't do this we would need to
-        * be able to wait for events on more than one ring simultaneously.
-        * Because we don't have a ring multiplexer object yet (which would
-        * be needed since a ring maps to a conditional variable among other
-        * things), we need to do process this way.
-        * XXX Could there be a race condition here?  It needs to be stressed.
-        */
-       {
-               int     mevent;
-
-               mevent = (data->port.ring != NULL ?
-                   data->port.ring->mevent : 0);
-               oring = data->port.ring;
-               (void) pthread_port_set_ring(&data->port, ring);
-               data->port.ring->mevent = mevent;
-       }
-
-       /*
-        * Send query to polling thread.  It is safe to simply reuse our
-        * message since we then expect a reply back and synchronize it.
-        */
-       data->msg.cancel = FALSE;
-       data->msg.fds = fds;
-       data->msg.nfds = nfds;
-       data->msg.timeout = timeout;
-       if ((error = pthread_msg_put(&pthread_poll_thread_port,
-           &data->msg.msgnode)) != 0)
-               goto err;
-
-       /*
-        * Interrupt polling thread which may still be waiting in poll(2).
-        * We do this by sending SIGUSR2 to the process, which only the
-        * polling thread is not blocking.  This causes the thread to reiterate
-        * its main loop, thus processing this message and going back to
-        * sleep in poll(2).
-        */
-       POLLWAKE();
-
-       /*
-        * Wait until en event occurs and notifies our ring.  An event could
-        * either be triggered by the poll request ending or by another
-        * interrupting event on the supplied ring.  If a message is queued
-        * on the port between pthread_port_set_ring() and
-        * pthread_ring_wait(), the latter immediately returns.
-        */
-       if ((error = pthread_ring_wait(ring, NULL)) != 0)
-               goto err;
-       if (pthread_msg_get(&data->port) == NULL) {
-               /*
-                * No message replied back from poll thread yet, this means
-                * that our ring was notified by another event.  Cancel request
-                * by sending event back with the cancel flag, and wait for
-                * reply message to occur (which will be the original request
-                * results we were waiting for).  error field will be set to
-                * ECANCELED by the poll thread.
-                */
-               data->msg.cancel = TRUE;
-               (void) pthread_msg_put(&pthread_poll_thread_port,
-                   &data->msg.msgnode);
-               POLLWAKE();
-               while (pthread_msg_get(&data->port) == NULL)
-                       (void) pthread_ring_wait(ring, NULL);
-       }
-       /* Unclobber user supplied ring from our port events */
-       (void) pthread_port_set_ring(&data->port, oring);
-
-       /*
-        * Error, return error number.
-        */
-       if (data->msg.error != 0) {
-               error = data->msg.error;
-               goto err;
-       }
-
-       /*
-        * Success, return number of descriptors with detected events.
-        */
-       DEBUG_PTHREAD_EXIT();
-       return data->msg.ready;
-
-err:
-       errno = error;
-
-       DEBUG_PTHREAD_EXIT();
-       return -1;
-}
-
-/*
- * accept(2) replacement which can both observe a timeout and be interrupted
- * via pthread_ring_t events.  Internally implemented using
- * pthread_poll_ring().  Will internally set the descriptor in non-blocking
- * mode if necessary, then reverting it to the mode it was supplied in.
- * Returns a new descriptor on success, or -1 on error, in which case errno
- * is set.  errno can then be EINVAL, ETIMEDOUT, ECANCELED, or others.
- * Timeout is in milliseconds, like for poll(2) and can be -1.
- */
-int
-pthread_accept_ring(int s, struct sockaddr *addr, socklen_t *addrlen,
-    int timeout, pthread_ring_t *ring)
-{
-       int             oflags, nflags, d, error = 0;
-       struct pollfd   fd;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (!pthread_poll_initialized) {
-               errno = EINVAL;
-               goto err;
-       }
-
-       /*
-        * First get current fcntl status flags, and set descriptor to
-        * non-blocking mode if necessary.
-        */
-       if ((oflags = nflags = fcntl(s, F_GETFL)) == -1)
-               goto err;
-       if ((oflags & O_NONBLOCK) == 0) {
-               nflags |= O_NONBLOCK;
-               if (fcntl(s, F_SETFL, nflags) == -1)
-                       goto err;
-       }
-
-       if ((d = accept(s, addr, addrlen)) == -1) {
-               if (errno != EAGAIN) /* XXX Add others? */
-                       goto end;
-       } else
-               goto end;
-
-       /*
-        * EAGAIN, poll until completion, timeout or ring event.
-        */
-       fd.fd = d;
-       fd.events = POLLIN;
-       if ((error = pthread_poll_ring(&fd, 1, timeout, ring)) == 1 &&
-           (fd.revents & POLLIN) != 0)
-               error = 0;
-       else
-               error = errno;
-
-end:
-       /*
-        * Restore supplied descriptor fcntl status flags if necessary
-        */
-       if (nflags != oflags)
-               (void) fcntl(s, F_SETFL, oflags);
-
-       if (error != 0) {
-               if (d != -1) {
-                       (void) close(d);
-                       d = -1;
-               }
-               errno = error;
-               goto err;
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return d;
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return -1;
-}
-
-/*
- * connect(2) replacement which can both observe a timeout and be interrupted
- * via pthread_ring_t events.  Internally implemented using
- * pthread_poll_ring().  Will internally set the descriptor in non-blocking
- * mode if necessary, then reverting it back to the mode it was supplied in.
- * Returns 0 on success, or -1, in which case errno is set.  errno can be
- * EINVAL, ETIMEDOUT, ECANCELED or others.
- * Timeout is in milliseconds, like for poll(2) and can be -1.
- * For the application to know the actual connection status result, it should
- * poll until completion and verify the status using getsockopt(2) with
- * SOL_SOCKET level and SO_ERROR option.  It can alternatively continue to call
- * this function in a loop until completion.  Calling the function on an
- * already connected socket will result in EISCONN.
- */
-int
-pthread_connect_ring(int s, const struct sockaddr *name, socklen_t namelen,
-    int timeout, pthread_ring_t *ring)
-{
-       int             oflags, nflags, error = 0;
-       struct pollfd   fd;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (!pthread_poll_initialized) {
-               errno = EINVAL;
-               goto err;
-       }
-
-       /*
-        * First get current fcntl status flags, and set descriptor to
-        * non-blocking mode if necessary.
-        */
-       if ((oflags = nflags = fcntl(s, F_GETFL)) == -1)
-               goto err;
-       if ((oflags & O_NONBLOCK) == 0) {
-               nflags |= O_NONBLOCK;
-               if (fcntl(s, F_SETFL, nflags) == -1)
-                       goto err;
-       }
-
-       if ((error = connect(s, name, namelen)) == -1) {
-               if (errno != EINPROGRESS && errno != EALREADY) {
-                       error = errno;
-                       goto end;
-               }
-       } else
-               goto end;
-
-       /*
-        * EINPROGRESS or EALREADY, poll until completion, timeout or ring
-        * event.
-        */
-       fd.fd = s;
-       fd.events = POLLOUT;
-       if (pthread_poll_ring(&fd, 1, timeout, ring) == 1 &&
-           (fd.revents & POLLOUT) != 0) {
-               socklen_t       l;
-
-               /*
-                * connect(2) completed, return result
-                */
-               if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &l) == -1)
-                       error = errno;
-       }
-
-end:
-       /*
-        * Restore supplied descriptor fcntl status flags if necessary
-        */
-       if (nflags != oflags)
-               (void) fcntl(s, F_SETFL, oflags);
-
-       if (error != 0) {
-               errno = error;
-               goto err;
-       }
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return -1;
-}
diff --git a/tests/pthread_utils/mm_pthread_poll.h b/tests/pthread_utils/mm_pthread_poll.h
deleted file mode 100644 (file)
index 77af18a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* $Id: mm_pthread_poll.h,v 1.6 2005/11/22 18:03:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef MM_PTHREAD_POLL_H
-#define MM_PTHREAD_POLL_H
-
-
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <poll.h>
-
-#include <mm_pthread_msg.h>
-
-
-
-extern int     pthread_poll_init(void);
-extern int     pthread_poll_ring(struct pollfd *, nfds_t, int,
-                   pthread_ring_t *);
-extern int     pthread_accept_ring(int, struct sockaddr *, socklen_t *, int,
-                   pthread_ring_t *);
-extern int     pthread_connect_ring(int, const struct sockaddr *, socklen_t,
-                   int, pthread_ring_t *);
-
-
-
-#endif
diff --git a/tests/pthread_utils/mm_pthread_pool.c b/tests/pthread_utils/mm_pthread_pool.c
deleted file mode 100644 (file)
index 80ba5fb..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-/* $Id: mm_pthread_pool.c,v 1.7 2006/02/05 13:00:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2004-2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Implementation of a pool of ready threads which adapts with concurrency
- * needs.  These ready threads can serve requests passed through efficient
- * inter-thread messaging.  mmpool(3) is used for the pool functionality.
- */
-
-
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <mm_pthread_debug.h>
-#include <mm_pthread_pool.h>
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2004-2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mm_pthread_pool.c,v 1.7 2006/02/05 13:00:48 mmondor Exp $");
-
-
-
-/*
- * STATIC FUNCTIONS PROTOTYPES
- */
-
-inline static pthread_object_t *thread_object_alloc(void);
-inline static void             thread_object_free(pthread_object_t *);
-static bool                    thread_object_constructor(pnode_t *);
-static void                    thread_object_destructor(pnode_t *);
-static void                    *thread_object_main(void *);
-
-
-
-/*
- * GLOBALS
- */
-
-static bool                    thread_object_initialized = FALSE;
-static pthread_attr_t          thread_object_attr;
-static pool_t                  thread_object_pool;
-static pool_t                  thread_object_msg_pool;
-static pthread_mutex_t         thread_object_pool_mutex =
-                                   PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t         thread_object_msg_pool_mutex =
-                                   PTHREAD_MUTEX_INITIALIZER;
-static pthread_ring_t          thread_started_ring;
-
-
-
-/*
- * EXPORTED PUBLIC FUNCTIONS
- */
-
-/*
- * Must be called to initialize the pthreads pool subsystem, before calling
- * any other function of this API.  Returns 0 on success, or an error number.
- * <initial> threads are launched, and more will be launched in increments
- * of <initial> whenever necessary.  These will also only be destroyed in
- * decrements of <initial> whenever that many threads have not been in use for
- * some time, and a minimum of <initial> threads will always be kept.
- * Setting <initial> to high values may actually degrade performance with some
- * unefficient threading implementations.  It is not recommended to use more
- * than 8 using the pth(3) library.  Using NetBSD 2.0+ SA threads, a high
- * number does not reduce performance.  We current do not observe any limit
- * whatsoever according to the number of threads launched over time.  It is the
- * application's responsibility to ensure to observe decent concurrency limits
- * before calling pthread_object_call().
- */
-int
-pthread_object_init(int initial)
-{
-       int     error = 0;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (thread_object_initialized) {
-               error = EINVAL;
-               goto err;
-       }
-
-       /*
-        * Create attributes which will be used for threads of the pool.
-        * We want them to be joinable.
-        */
-       if ((error = pthread_attr_init(&thread_object_attr)) != 0)
-               goto err;
-       if ((error = pthread_attr_setdetachstate(&thread_object_attr, 0))
-           != 0)
-               goto err;
-
-       /*
-        * We use this ring to obtain notification of ready children when
-        * launching them.  This is required for proper synchronization to
-        * avoid aweful race conditions.
-        */
-       if ((error = pthread_ring_init(&thread_started_ring)) != 0)
-               goto err;
-
-       /*
-        * First initialize the message subsystem pool
-        */
-       if (!pool_init(&thread_object_msg_pool, "thread_object_msg_pool",
-           malloc, free, NULL, NULL, sizeof(pthread_object_msg_t),
-           32768 / sizeof(pthread_object_msg_t), 1, 0)) {
-               error = ENOMEM;
-               goto err;
-       }
-
-       /*
-        * Now initialize the threads pool.  This creates threads, uses
-        * synchronization with thread_started_ring, and uses the message
-        * subsystem, which all must be initialized and ready.
-        */
-       if (!pool_init(&thread_object_pool, "thread_object_pool",
-           malloc, free, thread_object_constructor, thread_object_destructor,
-           sizeof(pthread_object_t), initial, 1, 0)) {
-               error = ENOMEM;
-               goto err;
-       }
-
-       thread_object_initialized = TRUE;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       if (POOL_VALID(&thread_object_msg_pool))
-               pool_destroy(&thread_object_msg_pool);
-       if (POOL_VALID(&thread_object_pool))
-               pool_destroy(&thread_object_pool);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Allows allocation/creation of a message suitable for asynchronous requests
- * with the threads via their main message port provided by this system.
- * Returns new message, or NULL on error.
- */
-inline pthread_object_msg_t *
-pthread_object_msg_alloc(void)
-{
-       pthread_object_msg_t    *msg = NULL;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (pthread_mutex_lock(&thread_object_msg_pool_mutex) != 0)
-               goto err;
-       msg = (pthread_object_msg_t *)pool_alloc(&thread_object_msg_pool,
-           FALSE);
-       (void) pthread_mutex_unlock(&thread_object_msg_pool_mutex);
-
-       (void) pthread_msg_init(&msg->message, NULL);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return msg;
-}
-
-/*
- * Permits to free/destroy a message which was allocated using
- * pthread_object_msg_alloc() and sent asynchroneously.
- */
-inline int
-pthread_object_msg_free(pthread_object_msg_t *msg)
-{
-       int     error = 0;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       (void) pthread_msg_destroy(&msg->message);
-
-       if ((error = pthread_mutex_lock(&thread_object_msg_pool_mutex)) != 0)
-               goto err;
-       (void) pool_free((pnode_t *)msg);
-       (void) pthread_mutex_unlock(&thread_object_msg_pool_mutex);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Allows to invoke a thread of the pool to perform execution of the wanted
- * function.  This is very efficient since the threads are already created and
- * are waiting for requests.  There is no maximum concurrency limit enforced by
- * this system; It is the responsibility of the application to restrict
- * concurrency as necessary by keeping internal information on the current
- * number of requests.  0 is returned on success, or an error number.
- * XXX Add support for synchroneous and asynchroneous operation.  Current
- * operation is only asynchroneous, but we would like to add a boolean here to
- * decide.  We also could add back the result value of the thread function
- * which would only be useful in synchroneous operation, when we are waiting
- * until the task ends...  Of course, it's still easy for applications to use
- * these in a synchroneous manner, by using a message and/or ring,
- * conditionnal variable, etc.
- * Also evaluate if a callback function to be called to notify end of
- * asynchroneous operation would be useful.
- */
-int
-pthread_object_call(pthread_port_t **port,
-    void (*function)(pthread_object_t *, void *), void *args)
-{
-       pthread_object_t        *obj = NULL;
-       pthread_object_msg_t    *msg = NULL;
-       int                     error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (function == NULL) {
-               error = EINVAL;
-               goto err;
-       }
-
-       /*
-        * Allocate a thread from the pool to reserve it, and tell it to call
-        * a function via a message.  The message cannot be on the stack in
-        * this case, since it holds arguments to be passed to a thread, and
-        * also consists of an asynchroneous message for wich we do not expect
-        * a response back, waiting for it.  We just dispatch it and go on.
-        */
-       if ((obj = thread_object_alloc()) == NULL) {
-               error = ENOMEM;
-               goto err;
-       }
-       if ((msg = pthread_object_msg_alloc()) == NULL) {
-               error = ENOMEM;
-               goto err;
-       }
-
-       msg->command = PTHREAD_OBJ_CALL;
-       msg->u.call.function = function;
-       msg->u.call.arguments = args;
-       if ((error = pthread_msg_put(obj->port, &msg->message)) != 0)
-               goto err;
-
-       /*
-        * Everything successful;
-        * If caller wants the message port of the thread, supply it
-        */
-       if (port != NULL)
-               *port = obj->port;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       if (msg != NULL)
-               pthread_object_msg_free(msg);
-       if (obj != NULL)
-               thread_object_free(obj);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-
-
-/*
- * INTERNAL STATIC FUNCTIONS
- */
-
-/*
- * Internally used to allocate a ready thread from the pool.
- */
-inline static pthread_object_t *
-thread_object_alloc(void)
-{
-       pthread_object_t        *obj = NULL;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (pthread_mutex_lock(&thread_object_pool_mutex) != 0)
-               goto err;
-       obj = (pthread_object_t *)pool_alloc(&thread_object_pool, FALSE);
-       (void) pthread_mutex_unlock(&thread_object_pool_mutex);
-
-err:
-       return obj;
-}
-
-/*
- * Internally used to free a no longer needed thread back to the pool of ready
- * threads.
- */
-inline static void
-thread_object_free(pthread_object_t *obj)
-{
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if (pthread_mutex_lock(&thread_object_pool_mutex) == 0) {
-               (void) pool_free((pnode_t *)obj);
-               (void) pthread_mutex_unlock(&thread_object_pool_mutex);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-/*
- * Internally called by mmpool(3) to create a thread object.
- */
-static bool
-thread_object_constructor(pnode_t *pnode)
-{
-       pthread_object_t        *obj = (pthread_object_t *)pnode;
-       int                     success = TRUE;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       /*
-        * Note that we leave thread_object_main() initialize the port field
-        * when it creates its port and ring.
-        */
-       if (pthread_create(&obj->thread, &thread_object_attr,
-           thread_object_main, obj) != 0) {
-               success = FALSE;
-               goto err;
-       }
-
-       /*
-        * Wait until new thread ready notification.  Without this, at least
-        * with NetBSD 2.0 SA threads, hell would break loose.  Thread creation
-        * isn't really a bottleneck in our case anyways, since we only need
-        * to do it when all threads of the pool are already busy.
-        */
-       (void) pthread_ring_wait(&thread_started_ring, NULL);
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return success;
-}
-
-/*
- * Internally called by mmpool(3) to destroy a thread object.
- */
-static void
-thread_object_destructor(pnode_t *pnode)
-{
-       pthread_object_t        *obj = (pthread_object_t *)pnode;
-       pthread_object_msg_t    *msg;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       /*
-        * To be freed, the thread has to be terminated.  We thus send it a
-        * quit message and then wait for it to exit using pthread_join().
-        * Note that we let the thread destroy the port field.  Although we
-        * theoretically could use a message on the stack here, let's be safe.
-        * Thread destruction is only performed rarely anyways, so this isn't
-        * a performance problem.
-        */
-       if ((msg = pthread_object_msg_alloc()) != NULL) {
-               msg->command = PTHREAD_OBJ_QUIT;
-               (void) pthread_msg_put(obj->port, &msg->message);
-       }
-       (void) pthread_join(obj->thread, NULL);
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-/*
- * Actual thread's main loop.  We create a message port and listen for command
- * messages (quit and call).  When we obtain a quit request, we destroy the
- * port and exit cleanly.  The quit event can never occur during the execution
- * of a call command, since it is only called on already freed thread nodes
- * (by mmpool(3) pool_free()).  It is advized to applications which need to
- * obtain and use the port of the thread after thread_object_call() to only
- * send proper user messages, not system reserved ones.
- */
-static void *
-thread_object_main(void *args)
-{
-       pthread_object_t        *obj = (pthread_object_t *)args;
-       pthread_port_t          port;
-       pthread_ring_t          ring;
-       pthread_msg_t           *imsg;
-       pthread_object_msg_t    *msg;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       /*
-        * Create our incomming message port as well as its corresponding
-        * notification ring we can sleep on.  Then advertize our port address.
-        * Ideally, we should somehow panic if any of this initialization
-        * fails. XXX
-        */
-       (void) pthread_port_init(&port);
-       (void) pthread_ring_init(&ring);
-       (void) pthread_port_set_ring(&port, &ring);
-       obj->port = &port;
-
-       /*
-        * Notify parent that we are ready, so that it may proceed
-        */
-       (void) pthread_ring_notify(&thread_started_ring);
-
-       /*
-        * Main loop, which keeps executing until we obtain a PTHREAD_OBJ_QUIT
-        * message, at which event we cleanly exit.
-        */
-       for (;;) {
-               /*
-                * Wait for any message(s) to be available, without taking any
-                * CPU time.
-                */
-               (void) pthread_ring_wait(&ring, NULL);
-
-               /*
-                * We were awaken because at least one message is available.
-                * Process all messages in the queue.
-                */
-               while ((imsg = pthread_msg_get(&port)) != NULL) {
-                       msg = (pthread_object_msg_t *)(&((pnode_t *)imsg)[-1]);
-                       if (msg->command == PTHREAD_OBJ_QUIT) {
-                               /*
-                                * We are ordered to exit by the object
-                                * destructor.
-                                */
-                               pthread_object_msg_free(msg);
-                               goto end;
-                       }
-                       if (msg->command == PTHREAD_OBJ_CALL) {
-                               /*
-                                * Request to execute a function.  This means
-                                * that we were allocated/reserved first.
-                                */
-                               msg->u.call.function(obj,
-                                   msg->u.call.arguments);
-                               pthread_object_msg_free(msg);
-                               /*
-                                * Free/release us back, so that we be
-                                * available again to process further
-                                * requests.  It is possible that freeing
-                                * ourselves cause a PTHREAD_OBJ_QUIT message
-                                * to be queued soon on our port by the
-                                * destructor function.  This is safe, since
-                                * the destructor does not cause us to be
-                                * destroyed until it waits for us to have
-                                * ended cleanly using pthread_join().
-                                */
-                               thread_object_free(obj);
-                       }
-               }
-       }
-
-end:
-       /*
-        * Discard messages that are still queued on our port (if any)
-        */
-       while ((imsg = pthread_msg_get(&port)) != NULL) {
-               msg = (pthread_object_msg_t *)(&((pnode_t *)imsg)[-1]);
-               pthread_object_msg_free(msg);
-       }
-       /*
-        * Free our resources and exit.
-        */
-       (void) pthread_port_destroy(&port);
-       (void) pthread_ring_destroy(&ring);
-
-       DEBUG_PTHREAD_EXIT();
-       pthread_exit(NULL);
-
-       /* NOTREACHED */
-       return NULL;
-}
diff --git a/tests/pthread_utils/mm_pthread_pool.h b/tests/pthread_utils/mm_pthread_pool.h
deleted file mode 100644 (file)
index 2a46ebd..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* $Id: mm_pthread_pool.h,v 1.1 2004/12/27 11:16:16 mmondor Exp $ */
-
-/*
- * Copyright (C) 2004-2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef MM_PTHREAD_POOL_H
-#define MM_PTHREAD_POOL_H
-
-
-
-#include <pthread.h>
-
-#include <mmtypes.h>
-#include <mmpool.h>
-
-#include <mm_pthread_msg.h>
-
-
-
-typedef struct {
-       pnode_t         node;
-       pthread_t       thread;
-       pthread_port_t  *port;
-} pthread_object_t;
-
-typedef struct {
-       pnode_t         node;
-       pthread_msg_t   message;
-       int             command;
-       union {
-               /* PTHREAD_OBJ_CALL, sent to thread_object_main() */
-               struct {
-                       void    (*function)(pthread_object_t *, void *);
-                       void    *arguments;
-               } call;
-               /* PTHREAD_OBJ_QUIT, sent to thread_oject_reaper() */
-               pthread_object_t *quit;
-               /* PTHREAD_OBJ_USER, custom user messages */
-               struct {
-                       int     user_command;
-                       void    *user_data;
-               } user;
-       } u;
-} pthread_object_msg_t;
-
-enum pthread_object_commands {
-       PTHREAD_OBJ_CALL,
-       PTHREAD_OBJ_QUIT,
-       PTHREAD_OBJ_USER,
-       PTHREAD_OBJ_MAX
-};
-
-
-
-extern int                             pthread_object_init(int);
-extern inline pthread_object_msg_t     *pthread_object_msg_alloc(void);
-extern inline int                      pthread_object_msg_free(
-                                           pthread_object_msg_t *);
-extern int                             pthread_object_call(pthread_port_t **,
-                                           void (*)(pthread_object_t *,
-                                           void *), void *);
-
-
-
-#endif
diff --git a/tests/pthread_utils/mm_pthread_sleep.c b/tests/pthread_utils/mm_pthread_sleep.c
deleted file mode 100644 (file)
index a9f8c58..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/* $Id: mm_pthread_sleep.c,v 1.5 2006/02/05 13:00:48 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <mm_pthread_debug.h>
-#include <mm_pthread_msg.h>
-#include <mm_pthread_sleep.h>
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mm_pthread_sleep.c,v 1.5 2006/02/05 13:00:48 mmondor Exp $");
-
-
-
-static int             pthread_sleep_proc_init(void);
-static void            pthread_sleep_proc_init2(void);
-static int             pthread_sleep_thread_init(pthread_ring_t **);
-static void            pthread_sleep_thread_exit(void *);
-
-static pthread_key_t   pthread_sleep_proc_key;
-static pthread_once_t  pthread_sleep_proc_initialized = PTHREAD_ONCE_INIT;
-
-
-
-static int
-pthread_sleep_proc_init(void)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       error = pthread_key_create(&pthread_sleep_proc_key,
-           pthread_sleep_thread_exit);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-static void
-pthread_sleep_proc_init2(void)
-{
-       int     error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if ((error = pthread_sleep_proc_init()) != 0) {
-               (void) fprintf(stderr, "pthread_sleep_proc_init() - %s\n",
-                   strerror(error));
-               DEBUG_PTHREAD_EXIT();
-               exit(EXIT_FAILURE);
-       }
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-static int
-pthread_sleep_thread_init(pthread_ring_t **res)
-{
-       int             error;
-       pthread_ring_t  *ring;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       if ((ring = malloc(sizeof(pthread_ring_t))) == NULL) {
-               error = ENOMEM;
-               goto err;
-       }
-
-       if ((error = pthread_ring_init(ring)) != 0)
-               goto err;
-
-       if ((error = pthread_setspecific(pthread_sleep_proc_key, ring)) != 0)
-               goto err;
-
-       *res = ring;
-
-       DEBUG_PTHREAD_EXIT();
-       return 0;
-
-err:
-       if (ring != NULL)
-               free(ring);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-static void
-pthread_sleep_thread_exit(void *specific)
-{
-       pthread_ring_t  *ring = (pthread_ring_t *)specific;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       (void) pthread_ring_destroy(ring);
-       free(ring);
-
-       /*
-        * Although NetBSD threads don't need this, some pthread
-        * implementations do.  Some will crash for attempting to reference the
-        * already freed memory twice calling us again until we NULL the
-        * pointer for the data.  Lame, but the POSIX standard was unclear
-        * about this.
-        */
-       (void) pthread_setspecific(pthread_sleep_proc_key, NULL);
-
-       DEBUG_PTHREAD_EXIT();
-}
-
-
-
-/*
- * Suspends the calling thread for duration specified in supplied timespec.
- * Returns 0 on success, or an error number.
- */
-int
-pthread_nanosleep(struct timespec *ts)
-{
-       int             error;
-       struct timeval  tv;
-       struct timespec its;
-       pthread_ring_t  *ring;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       /*
-        * Process specific initialization if needed
-        */
-       if ((error = pthread_once(&pthread_sleep_proc_initialized,
-           pthread_sleep_proc_init2)) != 0)
-               goto err;
-       /*
-        * Thread specific initialization if needed
-        * XXX Use pthread_once() here too, or mutex around ring?
-        */
-       if ((ring = pthread_getspecific(pthread_sleep_proc_key)) == NULL) {
-               if ((error = pthread_sleep_thread_init(&ring)) != 0)
-                       goto err;
-       }
-
-       /*
-        * Generate absolute time timespec using current time and supplied
-        * timespec delay.
-        */
-       if (gettimeofday(&tv, NULL) == -1) {
-               error = errno;
-               goto err;
-       }
-       TIMEVAL_TO_TIMESPEC(&tv, &its);
-       timespecadd(&its, ts, &its);
-
-       /*
-        * We can finally sleep.  We expect ETIMEDOUT to be the normal return
-        * value in this case, which we convert to a no-error.  Other errors
-        * will be returned un changed.
-        */
-       if ((error = pthread_ring_wait(ring, &its)) == ETIMEDOUT)
-               error = 0;
-
-err:
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Suspends the current thread for the duration specified into supplied
- * timeval.  Returns 0 on success or an error number.
- */
-int
-pthread_microsleep(struct timeval *tv)
-{
-       struct timespec ts;
-       int             error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       TIMEVAL_TO_TIMESPEC(tv, &ts);
-       error = pthread_nanosleep(&ts);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Suspends execution of current thread for duration of specified
- * milliseconds.  Returns 0 on success or an error number.
- */
-int
-pthread_millisleep(unsigned int ms)
-{
-       struct timeval  tv;
-       int             error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       tv.tv_sec = ms / 1000;
-       tv.tv_usec = (ms % 1000) * 1000;
-       error = pthread_microsleep(&tv);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Suspends execution of thread for duration of specified number of seconds.
- * Returns 0 on success or an error number.
- */
-unsigned int
-pthread_sleep(unsigned int seconds)
-{
-       struct timespec ts;
-       int             error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       ts.tv_sec = seconds;
-       ts.tv_nsec = 0;
-       error = pthread_nanosleep(&ts);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
-
-/*
- * Suspends execution of thread for durection of specified number of
- * microseconds.  Like usleep(3).
- */
-int
-pthread_usleep(useconds_t ms)
-{
-       struct timeval  tv;
-       int             error;
-
-       DEBUG_PTHREAD_ENTRY();
-
-       tv.tv_sec = 0;
-       tv.tv_usec = ms;
-       error = pthread_microsleep(&tv);
-
-       DEBUG_PTHREAD_EXIT();
-       return error;
-}
diff --git a/tests/pthread_utils/mm_pthread_sleep.h b/tests/pthread_utils/mm_pthread_sleep.h
deleted file mode 100644 (file)
index 93b6766..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $Id: mm_pthread_sleep.h,v 1.2 2005/09/16 08:49:06 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef MM_PTHREAD_SLEEP_H
-#define MM_PTHREAD_SLEEP_H
-
-
-
-#include <sys/time.h>
-#include <pthread.h>
-#include <unistd.h>
-
-
-
-extern int             pthread_nanosleep(struct timespec *);
-extern int             pthread_microsleep(struct timeval *);
-extern int             pthread_millisleep(unsigned int);
-extern unsigned int    pthread_sleep(unsigned int);
-extern int             pthread_usleep(useconds_t);
-
-
-
-#endif
diff --git a/tests/pthread_utils/tests/msg_test.c b/tests/pthread_utils/tests/msg_test.c
deleted file mode 100644 (file)
index bb7e918..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* $Id: msg_test.c,v 1.3 2005/11/18 10:54:58 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include <mm_pthread_msg.h>
-#include <mm_pthread_pool.h>
-#include <mm_pthread_poll.h>
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: msg_test.c,v 1.3 2005/11/18 10:54:58 mmondor Exp $");
-
-
-
-#define        THREADS                 32
-#define ROUNDS                 8
-#define TIMEOUT                        1
-/*#define PRINTLOCK*/
-/*#define NOPRINT*/
-
-
-
-struct message {
-       pthread_msg_t   node;
-       int             id, i;
-};
-
-
-
-int            main(void);
-static void    threadfunc(pthread_object_t *, void *);
-static void    printfunc(const char *, ...);
-
-
-
-static pthread_port_t  main_port;
-static pthread_mutex_t print_lock;
-
-
-
-int
-main(void)
-{
-       pthread_ring_t  ring;
-       struct message  *msg;
-       int             i, err;
-       int             threads_args[THREADS];
-       struct timeval  tv;
-       struct timespec ts, ts1;
-
-       if ((err = pthread_mutex_init(&print_lock, NULL)) != 0) {
-               (void) printf("main() - stdout lock - %s\n", strerror(err));
-               exit(EXIT_FAILURE);
-       }
-
-       if ((err = pthread_port_init(&main_port)) != 0 ||
-           (err = pthread_ring_init(&ring)) != 0 ||
-           (err = pthread_port_set_ring(&main_port, &ring)) != 0) {
-               printfunc("main() - initialization - %s\n", strerror(err));
-               exit(EXIT_FAILURE);
-       }
-
-       printfunc("Main: launching threads\n");
-
-       if ((err = pthread_poll_init()) != 0) {
-               printfunc("main() - pthread_poll_init() - %s\n",
-                   strerror(err));
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * Initializes a poll of ready threads which can be dispatched
-        * functions to execute.
-        */
-       if ((err = pthread_object_init(THREADS + 1)) != 0) {
-               printfunc("main() - pthread_object_init() - %s\n",
-                   strerror(err));
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * Now dispatch a main reentrant function to many threads, without
-        * waiting for them to complete, in an asynchroneous manner.
-        * XXX Because of the way this works, the parent main thread should
-        * actually already be listening to messages...  We did create a port
-        * however, which should queue messages until we reach the main loop.
-        */
-       for (i = 0; i < THREADS; i++) {
-               threads_args[i] = i;
-               if ((err = pthread_object_call(NULL, threadfunc,
-                   &threads_args[i])) != 0)
-                       printfunc("main() - pthread_object_call() - %s\n",
-                           strerror(errno));
-       }
-
-       ts1.tv_sec = TIMEOUT;
-       ts1.tv_nsec = 0;
-       for (;;) {
-               /*
-                * Read messages as long as there are any, and reply to each
-                * of them in a synchroneous manner.
-                */
-               while ((msg = (struct message *)pthread_msg_get(&main_port))
-                   != NULL) {
-
-                       printfunc(
-                           "Main: Received message %d from thread #%d\n",
-                           msg->i, msg->id);
-
-                       if ((err = pthread_msg_reply((pthread_msg_t *)msg))
-                           != 0)
-                               printfunc(
-                                   "Main: pthread_message_reply() - %s\n",
-                                   strerror(err));
-               }
-
-               /*
-                * No more messages to process; Wait for any message(s) to be
-                * available.
-                * Note that there is special provision in the event where
-                * this loop first polling for new messages before processing
-                * them, which causes waiting for the ring to immediately
-                * return instead of actually waiting if any messages already
-                * have been sent.
-                */
-               printfunc("Main: Waiting for messages\n");
-
-               (void) gettimeofday(&tv, NULL);
-               TIMEVAL_TO_TIMESPEC(&tv, &ts);
-               timespecadd(&ts, &ts1, &ts);
-               if ((err = pthread_ring_wait(&ring, &ts)) != 0) {
-                       printfunc("Main: pthread_ring_wait() - %s\n",
-                           strerror(err));
-                       break;
-               }
-       }
-
-       (void) pthread_mutex_destroy(&print_lock);
-       (void) pthread_port_destroy(&main_port);
-       (void) pthread_ring_destroy(&ring);
-
-       return 0;
-}
-
-static void
-threadfunc(pthread_object_t *obj, void *args)
-{
-       int             id = *(int *)args;
-       int             i, err;
-       struct message  msg;
-       pthread_port_t  rport;
-       pthread_ring_t  rring;
-
-       if ((err = pthread_port_init(&rport)) != 0 ||
-           (err = pthread_ring_init(&rring)) != 0 ||
-           (err = pthread_port_set_ring(&rport, &rring)) != 0 ||
-           (err = pthread_msg_init((pthread_msg_t *)&msg, &rport)) != 0) {
-               printfunc("threadfunc() - initialization - %s\n",
-                   strerror(err));
-               return;
-       }
-
-       msg.id = id;
-
-       (void) printfunc("Thread #%d started\n", id);
-
-       for (i = 0; i < ROUNDS; i++) {
-               /*
-                * Prepare and send synchronous message.  For asynchronous
-                * operation, we would need to allocate a message and to send
-                * it, and not expect a reply back immediately, even letting
-                * the other end free the message as necessary.  In synchronous
-                * mode we can use the same message over and over and share
-                * its memory area using proper send/reply methods for
-                * synchronization.
-                */
-               msg.i = i;
-               if ((err = pthread_msg_put(&main_port, (pthread_msg_t *)&msg))
-                   != 0)
-                       printfunc("Thread: pthread_message_put() - %s\n",
-                           strerror(err));
-
-               /* Now wait for synchronous reply and discard it */
-               if ((err = pthread_ring_wait(&rring, NULL)) != 0) {
-                       printfunc("Thread: pthread_ring_wait() - %s\n",
-                           strerror(err));
-                       break;
-               }
-               if (pthread_msg_get(&rport) == NULL)
-                       printfunc("Thread: pthread_msg_get() == NULL!?\n");
-               printfunc("Thread #%d received reply message for %d\n",
-                   id, i);
-       }
-
-       printfunc("Thread #%d ending\n", id);
-
-       (void) pthread_port_destroy(&rport);
-       (void) pthread_ring_destroy(&rring);
-       (void) pthread_msg_destroy((pthread_msg_t *)&msg);
-}
-
-static void
-printfunc(const char *fmt, ...)
-{
-       char    buf[1024];
-       va_list arg_ptr;
-       int     len;
-
-#ifdef NOPRINT
-       return;
-#endif
-
-       *buf = '\0';
-       va_start(arg_ptr, fmt);
-       if ((len = vsnprintf(buf, 1023, fmt, arg_ptr)) < 1)
-               return;
-       va_end(arg_ptr);
-
-#ifdef PRINTLOCK
-       (void) pthread_mutex_lock(&print_lock);
-#endif
-       (void) fwrite(buf, len, 1, stdout);
-#ifdef PRINTLOCK
-       (void) fflush(stdout);
-       (void) pthread_mutex_unlock(&print_lock);
-#endif
-}
diff --git a/tests/pthread_utils/tests/poll_test.c b/tests/pthread_utils/tests/poll_test.c
deleted file mode 100644 (file)
index 7be14bc..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $Id: poll_test.c,v 1.1 2005/09/14 23:48:10 mmondor Exp $ */
-
-/*
- * Copyright (C) 2005, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include <mm_pthread_msg.h>
-#include <mm_pthread_pool.h>
-#include <mm_pthread_poll.h>
-
-
-
-MMCOPYRIGHT("@(#) Copyright (c) 2005\n\
-\tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: poll_test.c,v 1.1 2005/09/14 23:48:10 mmondor Exp $");
-
-
-
-int    main(void);
-
-
-
-int
-main(void)
-{
-       int     err;
-
-       if ((err = pthread_poll_init()) != 0) {
-               (void) fprintf(stderr, "main() - pthread_poll_init() - %s\n",
-                   strerror(err));
-               exit(EXIT_FAILURE);
-       }
-
-       return 0;
-}
diff --git a/tests/pthread_utils/tests/polltest.c b/tests/pthread_utils/tests/polltest.c
deleted file mode 100644 (file)
index ceedfd5..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * The goal of this program is to verify if it is valid for multiple threads
- * to poll(2) on the same filedescriptor, and if so, what happens whenever
- * an event is triggered on that descriptor.
- *
- * XXX Problems:
- * - Only one of the polling threads seems to be awaken when an event occurs
- *   on the descriptor. This probably means that using a signal would be
- *   better... I sure don't want to need a filedescriptor per ring...
- *   If I did however, would this really hurt? Are there that many rings?
- *   But oops, this actually means two filedescriptors for each!
- *   using a signal is probably better. However, we then need to clobber some
- *   signal... We could use SIGUSR2.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-#define THREADS        8
-
-
-
-int            main(void);
-static void    *thread_poll(void *);
-static void    *thread_notify(void *);
-static void    thread_print(int, const char *);
-
-
-
-static int             sockets[2];
-static int             threadargs[THREADS];
-static pthread_mutex_t print_mutex;
-static pthread_mutex_t sockets_mutex;
-
-
-
-int
-main(void)
-{
-       pthread_t       threadid;
-       int             i;
-
-       /*
-        * Create socketpair which will be used to trigger events to awaken
-        * polling threads.
-        */
-       if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, sockets) != 0) {
-               perror("socketpair()");
-               exit(EXIT_FAILURE);
-       }
-       if (fcntl(sockets[0], F_SETFL, O_NONBLOCK) != 0 ||
-           fcntl(sockets[1], F_SETFL, O_NONBLOCK) != 0) {
-               perror("fcntl()");
-               exit(EXIT_FAILURE);
-       }
-
-       pthread_mutex_init(&print_mutex, NULL);
-       pthread_mutex_init(&sockets_mutex, NULL);
-
-       /*
-        * First launch THREADS polling threads
-        */
-       for (i = 0; i < THREADS; i++) {
-               threadargs[i] = i;
-               pthread_create(&threadid, NULL, thread_poll, &threadargs[i]);
-       }
-       sleep(1);
-
-       /*
-        * And finally launch notifyer thread
-        */
-       pthread_create(&threadid, NULL, thread_notify, NULL);
-
-       /*
-        * Now just wait
-        */
-       for (;;)
-               (void) pause();
-}
-
-static void *
-thread_poll(void *args)
-{
-       struct pollfd   fds[1];
-       int             n;
-       int             id = *(int *)args;
-       char            c;
-
-       fds[0].fd = sockets[1];
-       fds[0].events = POLLIN;
-       for (;;) {
-               thread_print(id, "Polling");
-               if ((n = poll(fds, 1, -1)) == -1) {
-                       perror("poll()");
-                       return NULL;
-               }
-               thread_print(id, "Poll returned");
-               if (n == 0) {
-                       thread_print(id, "Woke up! (no data)");
-                       continue;
-               }
-               if ((fds[0].revents & POLLIN) != 0) {
-                       /* Attempt to read event/byte */
-                       thread_print(id, "Woke up! (with data)");
-                       pthread_mutex_lock(&sockets_mutex);
-                       while ((n = read(sockets[1], &c, 1)) == 1)
-                               thread_print(id, "Read data!");
-                       if (n == -1)
-                               thread_print(id, strerror(errno));
-                       pthread_mutex_unlock(&sockets_mutex);
-               }
-       }
-}
-
-/* ARGSUSED */
-static void *
-thread_notify(void *args)
-{
-       char            c = '\0';
-       struct pollfd   fds[1];
-
-       fds[0].fd = sockets[0];
-       fds[0].events = POLLOUT;
-       for (;;) {
-               sleep(1);
-               thread_print(-1, "Notifying");
-               pthread_mutex_lock(&sockets_mutex);
-               if (write(sockets[0], &c, 1) != 1) {
-                       /* Poll until we can send data */
-                       (void) poll(fds, 1, -1);
-               }
-               pthread_mutex_unlock(&sockets_mutex);
-       }
-}
-
-static void
-thread_print(int id, const char *str)
-{
-
-       pthread_mutex_lock(&print_mutex);
-       printf("%d: %s\n", id, str);
-       pthread_mutex_unlock(&print_mutex);
-}
diff --git a/tests/pthread_utils/tests/sigtest.c b/tests/pthread_utils/tests/sigtest.c
deleted file mode 100644 (file)
index cc4b681..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * The goal of this program is to verify if it is valid for multiple threads
- * to be awaken from a poll(2) call by a single process-wide signal. This
- * would allow the notifyer of a thread message event to generate this signal
- * if needed to cause interested treads to wake up. Threads which do not want
- * to receive the signal can simply ignore it using pthread_sigmask().
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-
-#define THREADS        8
-
-
-
-int            main(void);
-static void    *thread_poll(void *);
-static void    *thread_notify(void *);
-static void    thread_print(int, const char *);
-
-
-
-static int             sockets[2];
-static int             threadargs[THREADS];
-static pthread_mutex_t print_mutex;
-static pthread_mutex_t sockets_mutex;
-
-
-
-int
-main(void)
-{
-       pthread_t       threadid;
-       int             i;
-
-       /*
-        * Create socketpair which will be used to trigger events to awaken
-        * polling threads.
-        */
-       if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, sockets) != 0) {
-               perror("socketpair()");
-               exit(EXIT_FAILURE);
-       }
-       if (fcntl(sockets[0], F_SETFL, O_NONBLOCK) != 0 ||
-           fcntl(sockets[1], F_SETFL, O_NONBLOCK) != 0) {
-               perror("fcntl()");
-               exit(EXIT_FAILURE);
-       }
-
-       pthread_mutex_init(&print_mutex, NULL);
-       pthread_mutex_init(&sockets_mutex, NULL);
-
-       /*
-        * First launch THREADS polling threads
-        */
-       for (i = 0; i < THREADS; i++) {
-               threadargs[i] = i;
-               pthread_create(&threadid, NULL, thread_poll, &threadargs[i]);
-       }
-       sleep(1);
-
-       /*
-        * And finally launch notifyer thread
-        */
-       pthread_create(&threadid, NULL, thread_notify, NULL);
-
-       /*
-        * Now just wait
-        */
-       for (;;)
-               (void) pause();
-}
-
-static void *
-thread_poll(void *args)
-{
-       struct pollfd   fds[1];
-       int             n;
-       int             id = *(int *)args;
-       char            c;
-
-       fds[0].fd = sockets[1];
-       fds[0].events = POLLIN;
-       for (;;) {
-               thread_print(id, "Polling");
-               if ((n = poll(fds, 1, -1)) == -1) {
-                       perror("poll()");
-                       return NULL;
-               }
-               thread_print(id, "Poll returned");
-               if (n == 0) {
-                       thread_print(id, "Woke up! (no data)");
-                       continue;
-               }
-               if ((fds[0].revents & POLLIN) != 0) {
-                       /* Attempt to read event/byte */
-                       thread_print(id, "Woke up! (with data)");
-                       pthread_mutex_lock(&sockets_mutex);
-                       while ((n = read(sockets[1], &c, 1)) == 1)
-                               thread_print(id, "Read data!");
-                       if (n == -1)
-                               thread_print(id, strerror(errno));
-                       pthread_mutex_unlock(&sockets_mutex);
-               }
-       }
-}
-
-/* ARGSUSED */
-static void *
-thread_notify(void *args)
-{
-       char            c = '\0';
-       struct pollfd   fds[1];
-
-       fds[0].fd = sockets[0];
-       fds[0].events = POLLOUT;
-       for (;;) {
-               sleep(1);
-               thread_print(-1, "Notifying");
-               pthread_mutex_lock(&sockets_mutex);
-               if (write(sockets[0], &c, 1) != 1) {
-                       /* Poll until we can send data */
-                       (void) poll(fds, 1, -1);
-               }
-               pthread_mutex_unlock(&sockets_mutex);
-       }
-}
-
-static void
-thread_print(int id, const char *str)
-{
-
-       pthread_mutex_lock(&print_mutex);
-       printf("%d: %s\n", id, str);
-       pthread_mutex_unlock(&print_mutex);
-}
diff --git a/tests/rlookup/GNUmakefile b/tests/rlookup/GNUmakefile
deleted file mode 100644 (file)
index e35d47b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# $Id: GNUmakefile,v 1.1 2007/03/01 03:51:20 mmondor Exp $
-
-MMLIB_PATH := ../../mmlib
-
-MMLIBS := $(addprefix ${MMLIB_PATH}/,mmpool.o mmhash.o mmarch.o mmstring.o mmlog.o)
-LIBS := -lc
-OBJS := rlc.o main.o
-CFLAGS += -Wall -g -DDEBUG
-BINS := test
-
-all: $(BINS)
-
-%.o: %.c
-       cc -c ${CFLAGS} -I. -I${MMLIB_PATH} -o $@ $<
-
-
-test: $(MMLIBS) $(OBJS)
-       cc -o $@ $(MMLIBS) $(OBJS) $(LIBS)
-
-
-clean:
-       rm -f $(BINS) $(OBJS) $(MMLIBS)
diff --git a/tests/rlookup/main.c b/tests/rlookup/main.c
deleted file mode 100644 (file)
index 7e96976..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* $Id: main.c,v 1.2 2007/03/01 11:18:01 mmondor Exp $ */
-
-/*
- * Copyright (c) 2007, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-/*
- * Headers
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <rlc.h>
-
-
-
-#define        PATH    "/nfs/hal/usr/pkgsrc"
-
-
-
-int            main(void);
-
-
-
-int
-main(void)
-{
-       unsigned long long      l1, l2;
-       int                     i;
-
-       (void) printf("Initializing\n");
-       if (rlc_init() == -1)
-               exit(EXIT_FAILURE);
-
-       (void) printf("Adding\n");
-       if (rlc_device_add(PATH) == -1)
-               exit(EXIT_FAILURE);
-
-       (void) printf("Query testing\n");
-       while ((i = scanf("%llu,%llu", &l1, &l2)) != EOF) {
-               rlc_results_t   *r;
-
-               if (i != 2) {
-                       (void) printf("Format: dev_t, ino_t\n");
-                       (void) fpurge(stdin);
-                       continue;
-               }
-               if ((r = rlc_lookup((dev_t)l1, (ino_t)l2)) != NULL) {
-                       for (i = 0; i < r->results; i++)
-                               (void) printf(" -> %s\n", r->result[i]);
-                       rlc_free_results(r);
-               } else
-                       (void) printf("No match\n");
-       }
-
-       (void) printf("Removing\n");
-       if (rlc_device_rem(PATH) == -1)
-               exit(EXIT_FAILURE);
-
-       (void) printf("Done, exiting\n");
-       rlc_exit();
-       exit(EXIT_SUCCESS);
-}
diff --git a/tests/rlookup/rlc.c b/tests/rlookup/rlc.c
deleted file mode 100644 (file)
index 83e1a61..0000000
+++ /dev/null
@@ -1,619 +0,0 @@
-/* $Id: rlc.c,v 1.2 2007/03/01 11:18:01 mmondor Exp $ */
-
-/*
- * Copyright (c) 2007, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * TODO:
- * - We should scan all currently mounted file systems and obtain their dev_t
- *   getvfsstat(2) could be used for this.
- * - We should obtain the base path name for a mounted file system.
- * - We should verify if the dev_t is the same when a new mountpoint is
- *   created for a new file system (when we get notified by mount).
- * - We should be able to monitor mount/unmount operations as well as
- *   obtain lookup requests easily via a library.  Possibly via kqueue or
- *   another such mechanism.
- * - We also should be able to obtain all modification events for a monitored
- *   file system via similar kernel notification.  While we're initially
- *   scanning we should be able to catch those events to apply them to your
- *   table once we complete scanning.
- * - How should we process rename events?  We would need to be provided both
- *   original and target paths, or we wouldn't be able to process them.
- *   I'm not sure if kqueue can provide that much information in its current
- *   form.
- * - Verify how ifwatchd(8) obtains its notifications.  Verify how usb
- *   attach/detach events are sent to userland as well.  If those all use
- *   different systems, verify if kqueue couldn't be improved to support all
- *   of this or if a new unified notification system should be developped.
- * - A form of compression could be used so that path names compress very
- *   well in memory rather than storing full pathnames (despite the fact that
- *   we only store the upto-mountpoint path once per dnode).
- *   A per-path element tree-based compression system would be great.
- */
-
-/*
- * NOTES:
- * - This test program implements a userspace inode to path lookup daemon.
- * - No pool really requires constructor/destructor support because we really
- *   want to free all resources associated with an object when freeing it,
- *   and that other than memory resources there are no heavy passes other than
- *   at rlc_dnode_t creation which cannot be re-used by other instantiations.
- * - We currently use an rlc_inode_t memory pool per rlc_dnode_t object.
- *   The intent is to make possible using a slave process per dev_t, such that
- *   adding a new file system to monitor (which requires heavy disk I/O) does
- *   not prevent quickly resolving requests for inodes on other file systems.
- *   Alternatively, a thread could be used per file system, but sharing the
- *   pool would still require synchronization (and locality of information
- *   would be less likely for batch lookup requests for a file system).
- *   This remains questionable as path names currently still use malloc/free
- *   but would need a variable allocation dnode specific heap allocator to
- *   achieve data locality.
- * - Ultimately it would be great if the information could be snapshot to
- *   disk in order to speed up re-mounting with inode lookup support.
- *   However, this would also require this system to be started after mounting
- *   a filesystem before any modification events are able to occur, which
- *   would require kernel modifications.  fsck(8) would also need to be aware
- *   of the system.  We don't care about this for now.
- * - We probably could have used a list_t instead of a hashtable_t to store
- *   multiple matching paths for an inode.  Since no two identical paths
- *   should be returned for an inode, it would be safe and slightly faster for
- *   the initial directory scanning.  The hash table may however enhance the
- *   speed of rename events related lookups eventually.
- */
-
-
-
-/*
- * Headers
- */
-
-#include <sys/stat.h>
-#include <sys/syslimits.h>
-#include <sys/types.h>
-
-#include <assert.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <mmlist.h>
-#include <mmpool.h>
-#include <mmhash.h>
-
-#include <rlc.h>
-
-
-
-/*
- * Definitions
- */
-
-/* Tweak for performance testing */
-#define DNODE_MAX      32
-#define DNODE_BUCKETS  8
-#define PNODE_BUCKETS  8
-
-/* Node for a device (dev_t) */
-typedef struct rlc_dnode {
-       hashnode_t      node;
-       dev_t           device;         /* Key */
-       pool_t          inode_pool;
-       hashtable_t     inode_table;
-       char            *mountpoint;
-} rlc_dnode_t;
-
-/* Node for an inode (ino_t) */
-typedef struct rlc_inode {
-       hashnode_t      node;
-       ino_t           inode;          /* Key */
-       nlink_t         links;
-       hashtable_t     pnode_table;
-       list_t          pnode_buckets[PNODE_BUCKETS];
-} rlc_inode_t;
-
-/* Node for a path node (string) */
-typedef struct rlc_pnode {
-       hashnode_t      node;
-       char            path[1];        /* Key */
-} rlc_pnode_t;
-
-struct rlc_pnode_lookup_iterator_udata {
-       const char      *mountpoint;
-       char            **array;
-       int             idx, error;
-};
-
-
-
-/*
- * Static prototypes
- */
-
-static int             rlc_dnode_cmp(const void *, const void *, size_t);
-static u_int32_t       rlc_dnode_hash(const void *, size_t);
-static rlc_dnode_t     *rlc_dnode_alloc(dev_t, const char *);
-static void            rlc_dnode_free(rlc_dnode_t *);
-static bool            rlc_dnode_free_iterator(hashnode_t *, void *);
-static int             rlc_dnode_populate(rlc_dnode_t *, const char *);
-
-static int             rlc_inode_cmp(const void *, const void *, size_t);
-static u_int32_t       rlc_inode_hash(const void *, size_t);
-static rlc_inode_t     *rlc_inode_alloc(rlc_dnode_t *, ino_t, nlink_t);
-static void            rlc_inode_free(rlc_inode_t *);
-static bool            rlc_inode_free_iterator(hashnode_t *, void *);
-
-static rlc_pnode_t     *rlc_pnode_alloc(size_t);
-static void            rlc_pnode_free(rlc_pnode_t *);
-static bool            rlc_pnode_free_iterator(hashnode_t *, void *);
-static bool            rlc_pnode_lookup_iterator(hashnode_t *, void *);
-
-static dev_t           rlc_mp_dev(const char *);
-
-
-
-/*
- * Static globals
- */
-
-static int             rlc_initialized = 0;
-static pool_t          rlc_dnode_pool;
-static hashtable_t     rlc_dnode_table;
-
-
-
-/*
- * Static functions
- */
-
-/* ARGSUSED */
-static int
-rlc_dnode_cmp(const void *from, const void *to, size_t size)
-{
-
-       assert(from != NULL && to != NULL);
-
-       if (*(dev_t *)from == *(dev_t *)to)
-               return 0;
-
-       return -1;
-}
-
-/* ARGSUSED */
-static u_int32_t
-rlc_dnode_hash(const void *key, size_t size)
-{
-
-       assert(key != NULL);
-
-       return (*(dev_t *)key & 0xffffffff);
-}
-
-static rlc_dnode_t *
-rlc_dnode_alloc(dev_t dev, const char *mp)
-{
-       rlc_dnode_t     *dn;
-
-       assert(mp != NULL);
-
-       /* XXX Would need synchronization if shared */
-       if ((dn = (rlc_dnode_t *)pool_alloc(&rlc_dnode_pool, FALSE)) == NULL)
-               goto err;
-       dn->device = dev;
-
-       if (!pool_init(&dn->inode_pool, "inode_pool", malloc, free, NULL,
-           NULL, sizeof(rlc_dnode_t), 65536 / sizeof(rlc_dnode_t), 0, 0))
-               goto err;
-
-       if (!hashtable_init(&dn->inode_table, "inode_table",
-           HT_DEFAULT_CAPACITY, HT_DEFAULT_FACTOR, malloc, free,
-           rlc_inode_cmp, rlc_inode_hash, TRUE))
-               goto err;
-
-       /* XXX Assumes that mountpoint is sanity-checked without trailing / */
-       if ((dn->mountpoint = strdup(mp)) == NULL)
-               goto err;
-
-       return dn;
-
-err:
-       if (dn != NULL) {
-               if (HASHTABLE_VALID(&dn->inode_table))
-                       hashtable_destroy(&dn->inode_table, FALSE);
-               if (POOL_VALID(&dn->inode_pool))
-                       (void) pool_destroy(&dn->inode_pool);
-               if (dn->mountpoint != NULL)
-                       free(dn->mountpoint);
-               (void) pool_free((pnode_t *)dn);
-       }
-
-       return NULL;
-}
-
-static void
-rlc_dnode_free(rlc_dnode_t *dn)
-{
-
-       assert(PNODE_VALID((pnode_t *)dn));
-
-       free(dn->mountpoint);
-       hashtable_iterate(&dn->inode_table, rlc_inode_free_iterator, NULL);
-       hashtable_destroy(&dn->inode_table, FALSE);
-       (void) pool_destroy(&dn->inode_pool);
-
-       (void) pool_free((pnode_t *)dn);
-}
-
-/* ARGSUSED */
-static bool
-rlc_dnode_free_iterator(hashnode_t *nod, void *udata)
-{
-
-       rlc_dnode_free((rlc_dnode_t *)nod);
-
-       return TRUE;
-}
-
-static int
-rlc_dnode_populate(rlc_dnode_t *dn, const char *root)
-{
-       static char             path[PATH_MAX + 1];
-       static rlc_inode_t      *in;
-       static rlc_pnode_t      *pn;
-       static struct dirent    ent, *entp;
-       static struct stat      st;
-
-       char                    *dpath = NULL;
-       DIR                     *dir;
-       int                     i;
-
-       in = NULL;
-       pn = NULL;
-       (void) snprintf(path, PATH_MAX, "%s/%s", dn->mountpoint, root);
-       if ((dir = opendir(path)) == NULL)
-               goto err;
-
-       while ((i = readdir_r(dir, &ent, &entp)) == 0 && entp != NULL) {
-               if ((ent.d_name[0] == '.' && ent.d_name[1] == '\0') ||
-                   (ent.d_name[0] == '.' && ent.d_name[1] == '.' &&
-                    ent.d_name[2] == '\0'))
-                       continue;
-
-               (void) snprintf(path, PATH_MAX, "%s/%s/%s", dn->mountpoint,
-                   root, ent.d_name);
-               if (lstat(path, &st) != 0)
-                       goto err;
-               if (st.st_dev != dn->device || st.st_nlink == 0)
-                       continue;
-
-               if ((in = rlc_inode_alloc(dn, st.st_ino, st.st_nlink)) == NULL)
-                       goto err;
-               if (!hashtable_link(&dn->inode_table, (hashnode_t *)in,
-                   &in->inode, sizeof(ino_t), FALSE))
-                       goto err;
-               i =  snprintf(path, PATH_MAX, "%s/%s", root, ent.d_name);
-               if ((pn = rlc_pnode_alloc(i)) == NULL)
-                       goto err;
-               (void) strncpy(pn->path, path, i);
-               /* Fixed table, will succeed */
-               (void) hashtable_link(&in->pnode_table, (hashnode_t *)pn,
-                   pn->path, i, FALSE);
-               pn = NULL;
-               in = NULL;
-
-               /* Recurse into subdirectories */
-               if ((st.st_mode & S_IFMT) == S_IFDIR) {
-                       if ((dpath = strdup(path)) == NULL)
-                               goto err;
-                       i = rlc_dnode_populate(dn, dpath);
-                       free(dpath);
-                       if (i != 0)
-                               goto err;
-               }
-       }
-       if (i != 0)
-               goto err;
-
-       (void) closedir(dir);
-       return 0;
-
-err:
-       if (pn != NULL)
-               rlc_pnode_free(pn);
-       if (in != NULL)
-               rlc_inode_free(in);
-       if (dir != NULL)
-               (void) closedir(dir);
-       return -1;
-}
-
-/* ARGSUSED */
-static int
-rlc_inode_cmp(const void *from, const void *to, size_t size)
-{
-
-       assert(from != NULL && to != NULL);
-
-       if (*(ino_t *)from == *(ino_t *)to)
-               return 0;
-
-       return -1;
-}
-
-/* ARGSUSED */
-static u_int32_t
-rlc_inode_hash(const void *key, size_t size)
-{
-
-       assert(key != NULL);
-
-       return (*(ino_t *)key & 0xffffffff);
-}
-
-static rlc_inode_t *
-rlc_inode_alloc(rlc_dnode_t *dn, ino_t inode, nlink_t links)
-{
-       rlc_inode_t     *in;
-
-       if ((in = (rlc_inode_t *)pool_alloc(&dn->inode_pool, FALSE)) == NULL)
-               return in;
-
-       in->inode = inode;
-       in->links = links;
-       hashtable_init2(&in->pnode_table, "pnode_table", in->pnode_buckets,
-           PNODE_BUCKETS, rlc_inode_cmp, rlc_inode_hash);
-
-       return in;
-}
-
-static void
-rlc_inode_free(rlc_inode_t *in)
-{
-
-       assert(PNODE_VALID((pnode_t *)in));
-
-       hashtable_iterate(&in->pnode_table, rlc_pnode_free_iterator, NULL);
-       (void) pool_free((pnode_t *)in);
-}
-
-/* ARGSUSED */
-static bool
-rlc_inode_free_iterator(hashnode_t *nod, void *udata)
-{
-
-       rlc_inode_free((rlc_inode_t *)nod);
-
-       return TRUE;
-}
-
-static rlc_pnode_t *
-rlc_pnode_alloc(size_t size)
-{
-
-       return malloc(sizeof(rlc_pnode_t) + size);
-}
-
-static void
-rlc_pnode_free(rlc_pnode_t *pn)
-{
-
-       assert(pn != NULL);
-
-       free(pn);
-}
-
-/* ARGSUSED */
-static bool
-rlc_pnode_free_iterator(hashnode_t *nod, void *udata)
-{
-
-       rlc_pnode_free((rlc_pnode_t *)nod);
-
-       return TRUE;
-}
-
-static bool
-rlc_pnode_lookup_iterator(hashnode_t *nod, void *udata)
-{
-       rlc_pnode_t                             *pn = (rlc_pnode_t *)nod;
-       struct rlc_pnode_lookup_iterator_udata  *ud = udata;
-       /* XXX Uses a lot of stack */
-       char                                    path[PATH_MAX + 1];
-
-       /*
-        * We actually could provide direct pointers to mountpoint and
-        * path component for performance in our current case, but IPC
-        * requests will need to be provided with actual full paths...
-        */
-       path[PATH_MAX] = '\0';
-       (void) snprintf(path, PATH_MAX, "%s/%s", ud->mountpoint, pn->path);
-       if ((ud->array[ud->idx++] = strdup(path)) == NULL) {
-               ud->error = 1;
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-static dev_t
-rlc_mp_dev(const char *mp)
-{
-       struct stat     st;
-
-       if (lstat(mp, &st) == -1 || ((st.st_mode & S_IFMT) & S_IFDIR) != 0)
-               return st.st_dev;
-
-       return -1;
-}
-
-
-
-/*
- * Public functions
- */
-
-int
-rlc_init(void)
-{
-
-       assert(!rlc_initialized);
-
-       /*
-        * XXX Needs to use shared memory allocator if using processes.
-        * Could be dynamically resizeable otherwise, but would then require
-        * synchronization with threads.
-        */
-       if (!pool_init(&rlc_dnode_pool, "dnode_pool", malloc, free, NULL,
-           NULL, sizeof(rlc_dnode_t), DNODE_MAX, 1, 1))
-               goto err;
-       if (!hashtable_init(&rlc_dnode_table, "dnode_table",
-           DNODE_BUCKETS, HT_DEFAULT_FACTOR, malloc, free, rlc_dnode_cmp,
-           rlc_dnode_hash, FALSE))
-               goto err;
-
-       /* XXX */
-
-       rlc_initialized = 1;
-       return 0;
-
-err:
-       if (POOL_VALID(&rlc_dnode_pool))
-               (void) pool_destroy(&rlc_dnode_pool);
-
-       return -1;
-}
-
-void
-rlc_exit(void)
-{
-
-       assert(rlc_initialized);
-
-       hashtable_iterate(&rlc_dnode_table, rlc_dnode_free_iterator, NULL);
-       hashtable_destroy(&rlc_dnode_table, FALSE);
-       (void) pool_destroy(&rlc_dnode_pool);
-}
-
-/*
- * XXX The two following functions may eventually require synchronization.
- * Moreover, since they can be expensive, it might be best to do it with
- * asynchroneous notification in another thread or process.
- */
-
-int
-rlc_device_add(const char *mp)
-{
-       dev_t           dev;
-       rlc_dnode_t     *dn = NULL;
-
-       assert(mp != NULL);
-
-       if ((dev = rlc_mp_dev(mp)) == -1)
-               goto err;
-       if ((dn = (rlc_dnode_t *)hashtable_lookup(&rlc_dnode_table, &dev,
-           sizeof(dev_t))) != NULL)
-               goto err;
-
-       /* XXX Assumes path is sanity checked with no trailing / */
-       if ((dn = rlc_dnode_alloc(dev, mp)) == NULL)
-               goto err;
-       if (rlc_dnode_populate(dn, "/") != 0)
-               goto err;
-       if (!hashtable_link(&rlc_dnode_table, (hashnode_t *)dn, &dn->device,
-           sizeof(dev_t), FALSE))
-               goto err;
-
-       /* XXX */ (void) printf("Added device: %llu (%llu entries)\n",
-           (unsigned long long)dev,
-           (unsigned long long)HASHTABLE_NODES(&dn->inode_table));
-       return 0;
-
-err:
-       if (dn != NULL)
-               rlc_dnode_free(dn);
-
-       return -1;
-}
-
-int
-rlc_device_rem(const char *mp)
-{
-       dev_t           dev;
-       rlc_dnode_t     *dn;
-
-       if ((dev = rlc_mp_dev(mp)) != -1 && (dn = (rlc_dnode_t *)hashtable_lookup(
-           &rlc_dnode_table, &dev, sizeof(dev_t))) != NULL &&
-           strcmp(mp, dn->mountpoint) == 0) {
-               hashtable_unlink(&rlc_dnode_table, (hashnode_t *)dn);
-               rlc_dnode_free(dn);
-
-               return 0;
-       }
-
-       return -1;
-}
-
-rlc_results_t *
-rlc_lookup(dev_t dev, ino_t inode)
-{
-       rlc_results_t                           *r;
-       rlc_dnode_t                             *dn;
-       rlc_inode_t                             *in;
-       int                                     results, i;
-       struct rlc_pnode_lookup_iterator_udata  udata;
-
-       /* First lookup for dnode */
-       /* XXX would need synchronization */
-       if ((dn = (rlc_dnode_t *)hashtable_lookup(&rlc_dnode_table, &dev,
-           sizeof(dev_t))) == NULL)
-               return NULL;
-
-       /* Now lookup for inode within dnode */
-       if ((in = (rlc_inode_t *)hashtable_lookup(&dn->inode_table, &inode,
-           sizeof(ino_t))) == NULL)
-               return NULL;
-       results = (int)HASHTABLE_NODES(&in->pnode_table);
-
-       /* Found, create results object */
-       if ((r = malloc(sizeof(rlc_results_t) + (sizeof(char *) * results))) ==
-           NULL)
-               return NULL;
-       r->results = results;
-       udata.mountpoint = dn->mountpoint;
-       udata.array = r->result;
-       udata.idx = 0;
-       udata.error = 0;
-       for (i = 0; i < r->results; i++)
-               r->result[i] = NULL;
-       hashtable_iterate(&in->pnode_table, rlc_pnode_lookup_iterator,
-           &udata);
-
-       if (udata.error) {
-               for (i = 0; i < r->results; i++) {
-                       if (r->result[i] != NULL)
-                               free(r->result[i]);
-               }
-               free(r);
-               r = NULL;
-       }
-
-       return r;
-}
-
-void
-rlc_free_results(rlc_results_t *r)
-{
-       int     i;
-
-       assert(r != NULL);
-
-       for (i = 0; i < r->results; i++) {
-               assert(r->result[i] != NULL);
-               free(r->result[i]);
-       }
-       free(r);
-}
diff --git a/tests/rlookup/rlc.h b/tests/rlookup/rlc.h
deleted file mode 100644 (file)
index 88bea62..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $Id: rlc.h,v 1.1 2007/03/01 03:51:20 mmondor Exp $ */
-
-/*
- * Copyright (c) 2007, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-typedef struct rlc_results {
-       int             results;
-       char            *result[1];
-} rlc_results_t;
-
-
-
-int                    rlc_init(void);
-void                   rlc_exit(void);
-int                    rlc_device_add(const char *);
-int                    rlc_device_rem(const char *);
-
-/*
- * XXX Public for now, but would be static with a lib using IPC to the daemon
- * instead.
- */
-rlc_results_t          *rlc_lookup(dev_t, ino_t);
-void                   rlc_free_results(rlc_results_t *);
diff --git a/tests/rotate/GNUmakefile b/tests/rotate/GNUmakefile
deleted file mode 100644 (file)
index 41ca002..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# $Id: GNUmakefile,v 1.2 2006/05/06 12:25:02 mmondor Exp $
-
-CC := cc
-RM := rm
-UNAME := uname
-
-CFLAGS += -Wall
-
-# Enable for verbosity/debugging
-#CFLAGS += -v -H -g
-#LDFLAGS += -v -g
-
-# And to disable assertions
-CFLAGS += -DNDEBUG
-
-OBJS := main.o
-BINS := rotate
-CBINS := $(addsuffix .exe,$(BINS))
-
-SDL_CFLAGS := $(shell sdl-config --cflags)
-SDL_LDFLAGS := $(shell sdl-config --libs)
-SDL_LDFLAGS += -lSDL_gfx
-
-# OS dependent settings follow
-OS := $(shell $(UNAME) -s)
-ifneq (,$(findstring CYGWIN,$(OS)))
-       # cygwin-mingw
-       CFLAGS += -mno-cygwin -I/usr/include/mingw
-       LDFLAGS += -mwindows -mno-cygwin -L/usr/lib/mingw -L/usr/local/lib
-#      GL_CFLAGS :=
-#      GL_LDFLAGS := -lopengl32 -lglu32
-else
-       # unix
-       CFLAGS += -I/usr/include -I/usr/pkg/include -I/usr/X11R6/include
-       LDFLAGS += -L/usr/lib -L/usr/pkg/lib -L/usr/X11R6/lib
-#      GL_CFLAGS :=
-#      GL_LDFLAGS := -lGL -lGLU
-endif
-
-#CFLAGS += $(SDL_CFLAGS) $(GL_CFLAGS)
-#LDFLAGS += $(SDL_LDFLAGS) $(GL_LDFLAGS)
-CFLAGS += $(SDL_CFLAGS)
-LDFLAGS += $(SDL_LDFLAGS)
-
-all: $(BINS)
-
-%.o: %.c
-       $(CC) -c $(CFLAGS) -I. -o $@ $<
-
-#$(BINS): $(OBJS)
-#      $(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS)
-
-$(BINS): $(OBJS)
-       $(CC) -o $@ $(OBJS) $(LDFLAGS)
-
-clean:
-       $(RM) -f $(BINS) $(CBINS) $(OBJS) stdout.txt stderr.txt
diff --git a/tests/rotate/main.c b/tests/rotate/main.c
deleted file mode 100644 (file)
index b2ed875..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $Id: main.c,v 1.1 2006/05/06 12:25:02 mmondor Exp $ */
-
-/*
- * Copyright (C) 2006, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <SDL.h>
-#include <SDL_rotozoom.h>
-#include <SDL_gfxPrimitives.h>
-
-
-
-int                    main(int, char **);
-
-
-
-static SDL_Surface     *screen_surface;
-
-
-
-int
-main(int argc, char **argv)
-{
-       SDL_Surface     *s, *save;
-       int             a, ad, at;
-       size_t          fnlen;
-       char            *fnbuf, *file;
-
-       if (argc != 3) {
-               (void) fprintf(stderr, "Usage: rotate \"<file>\" <steps>\n");
-               exit(EXIT_FAILURE);
-       }
-
-       if ((file = strdup(argv[1])) != NULL) {
-               char    *cptr;
-
-               if ((cptr = strrchr(file, '.')) != NULL)
-                       *cptr = '\0';
-       } else {
-               (void) fprintf(stderr, "strdup(%s)\n", argv[1]);
-               exit(EXIT_FAILURE);
-       }
-
-       fnlen = strlen(file) + 16;
-       if ((fnbuf = malloc(fnlen)) == NULL) {
-               (void) fprintf(stderr, "fnbuf = malloc(%d)\n", (int)fnlen + 8);
-               exit(EXIT_FAILURE);
-       }
-
-       at = (double)strtol(argv[2], NULL, 10);
-       ad = (360 / at);
-       if (at * ad != 360) {
-               (void) fprintf(stderr, "<steps> must be a divisor of 360\n");
-               exit(EXIT_FAILURE);
-       }
-
-       if (SDL_Init(SDL_INIT_VIDEO) == -1) {
-               (void) fprintf(stderr, "SDL_Init() - %s\n", SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if ((screen_surface = SDL_SetVideoMode(640, 480, 32, SDL_DOUBLEBUF))
-           == NULL) {
-               (void) fprintf(stderr, "SDL_SetVideoMode() - %s\n",
-                   SDL_GetError());
-               goto err;
-       }
-
-       if ((s = SDL_LoadBMP(argv[1])) == NULL) {
-               (void) fprintf(stderr, "SDL_LoadBMP(%s) - %s",
-                   argv[1], SDL_GetError());
-               goto err;
-       }
-       if ((save = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h, 32,
-           s->format->Rmask, s->format->Gmask, s->format->Bmask,
-           s->format->Amask)) == NULL) {
-               (void) fprintf(stderr, "SDL_CreateRGBSurface() - %s\n",
-                   SDL_GetError());
-               goto err;
-       }
-
-       /*
-        * XXX Assumes 0x000000 is the trasparent color, should probably be
-        * part of the command line parameters.
-        */
-       {
-               Uint32  col;
-
-               col = SDL_MapRGB(s->format, 0x00, 0x00, 0x00);
-               if (SDL_SetColorKey(s, SDL_SRCCOLORKEY, col) == -1) {
-                       (void) fprintf(stderr, "SDL_SetColorKey() - %s\n",
-                           SDL_GetError());
-                       goto err;
-               }
-       }
-
-       for (a = 0; a < 360; a += ad) {
-               SDL_Surface     *t;
-               SDL_Rect        d;
-               int             cx, cy, c;
-
-               cx = s->w / 2;
-               cy = s->h / 2;
-               c = (cx >= cy ? cx : cy);
-
-               /*
-                * XXX Again assumes that 0x000000 color is transparent.
-                * Moreover, in a future version, we also could allow to scale
-                * the bitmap image as wanted...
-                */
-               if (boxRGBA(save, 0, 0, s->w - 1, s->h - 1,
-                   0x00, 0x00, 0x00, 0xff) != 0 ||
-                   boxRGBA(screen_surface, 320 - c, 240 - c, 320 + c, 240 + c,
-                   0x00, 0x00, 0x00, 0xff) != 0) {
-                       (void) fprintf(stderr, "boxRGBA() - %s\n",
-                           SDL_GetError());
-                       goto err;
-               }
-
-               if ((t = rotozoomSurface(s, (double)-a, 1.0, 1)) == NULL) {
-                       (void) fprintf(stderr, "rotozoomSurface() - %s\n",
-                           SDL_GetError());
-                       goto err;
-               }
-               d = (SDL_Rect){320 - (t->w / 2), 240 - (t->h / 2), 0, 0};
-               if (SDL_BlitSurface(t, NULL, screen_surface, &d) != 0) {
-                       (void) fprintf(stderr, "SDL_BlitSurface() - %s\n",
-                           SDL_GetError());
-                       goto err;
-               }
-               SDL_FreeSurface(t);
-
-               d = (SDL_Rect){320 - c, 240 - c, 320 + c, 240 + c};
-               if (SDL_BlitSurface(screen_surface, &d, save, NULL) != 0) {
-                       (void) fprintf(stderr, "SDL_BlitSurface() - %s\n",
-                           SDL_GetError());
-                       goto err;
-               }
-               (void) snprintf(fnbuf, fnlen - 1, "%s-%03d.bmp", file, (int)a);
-               if (SDL_SaveBMP(save, fnbuf) != 0) {
-                       (void) fprintf(stderr, "SDL_SaveBMP(%s) - %s\n",
-                           fnbuf, SDL_GetError());
-                       goto err;
-               }
-
-               if (SDL_Flip(screen_surface) != 0) {
-                       (void) fprintf(stderr, "SDL_Flip() - %s",
-                           SDL_GetError());
-                       goto err;
-               }
-       }
-
-       SDL_Quit();
-       exit(EXIT_SUCCESS);
-
-err:
-       SDL_Quit();
-       exit(EXIT_FAILURE);
-}
diff --git a/tests/sdl-client/GNUmakefile b/tests/sdl-client/GNUmakefile
deleted file mode 100644 (file)
index e316dd3..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-# $Id: GNUmakefile,v 1.31 2006/05/23 01:32:50 mmondor Exp $
-
-CC := cc
-RM := rm
-UNAME := uname
-TOUCH := touch
-OBJDUMP := objdump
-OBJCOPY := objcopy
-GREP := grep
-AWK := awk
-DATE := date
-STRIP := strip
-
-TMPDIR := /tmp
-
-CFLAGS += -Wall
-
-# Enable for verbosity/debugging
-#CFLAGS += -v -H -g
-#LDFLAGS += -v -g
-
-# And to disable assertions
-CFLAGS += -DNDEBUG
-CFLAGS += -g
-
-OBJS := main.o debug.o pool.o thread_msg.o thread_net_recv.o \
-       thread_net_send.o screen.o decode.o
-BINS := client
-CBINS := $(addsuffix .exe,$(BINS))
-RAWOBJS := bmp/RomDD.bmp.enc.o bmp/FedCA.bmp.enc.o wav/nt_cloaked.wav.enc.o \
-       wav/nt_uncloak.wav.enc.o wav/nt_shield_up.wav.enc.o \
-       wav/nt_shield_down.wav.enc.o wav/nt_fire_torp_other.wav.enc.o \
-       wav/nt_plasma_hit.wav.enc.o wav/nt_explosion_other.wav.enc.o \
-       fnt/7x13.fnt.enc.o
-
-SDL_CFLAGS := $(shell sdl-config --cflags)
-SDL_LDFLAGS := $(shell sdl-config --libs)
-SDL_LDFLAGS += -lSDL_image -lSDL_mixer -lSDL_net -lSDL_gfx
-
-# OS dependent settings follow
-OS := $(shell $(UNAME) -s)
-ifneq (,$(findstring CYGWIN,$(OS)))
-       # cygwin-mingw
-       CFLAGS += -mno-cygwin -I/usr/include/mingw -DWIN32
-       LDFLAGS += -mwindows -mno-cygwin -L/usr/lib/mingw -L/usr/local/lib
-#      GL_CFLAGS :=
-#      GL_LDFLAGS := -lopengl32 -lglu32
-else
-       # unix
-       CFLAGS += -I/usr/include -I/usr/pkg/include -I/usr/X11R6/include
-       LDFLAGS += -L/usr/lib -L/usr/pkg/lib -L/usr/X11R6/lib
-#      GL_CFLAGS :=
-#      GL_LDFLAGS := -lGL -lGLU
-endif
-
-# Determine target of compiled objects so that we may convert binaries
-# to compatible objects using objcopy and then link them like other modules.
-OBJTARGET := $(shell $(TOUCH) $(TMPDIR)/obj.c && \
-       $(CC) $(CFLAGS) -c -o $(TMPDIR)/obj.o $(TMPDIR)/obj.c && \
-       $(OBJDUMP) -t $(TMPDIR)/obj.o | \
-       $(GREP) 'file format' | $(AWK) '{print $$4}' \
-       && $(RM) $(TMPDIR)/obj.o $(TMPDIR)/obj.c)
-OBJARCH := $(shell echo $(OBJTARGET) | $(AWK) -F '-' '{print $$2}')
-SEED := $(shell date +%s)
-
-#CFLAGS += $(SDL_CFLAGS) $(GL_CFLAGS)
-#LDFLAGS += $(SDL_LDFLAGS) $(GL_LDFLAGS)
-CFLAGS += $(SDL_CFLAGS)
-LDFLAGS += $(SDL_LDFLAGS)
-
-all: $(BINS)
-
-%.o: %.c
-       $(CC) -c $(CFLAGS) -I. -o $@ $<
-
-encode:
-       $(CC) -o encode encode.c
-
-$(RAWOBJS): encode
-       ./encode $(basename $(basename $@)) $(basename $@) $(SEED)
-       $(OBJCOPY) -I binary -B $(OBJARCH) -O $(OBJTARGET) $(basename $@) $@
-       $(RM) -f $(basename $@)
-
-$(BINS): $(OBJS) $(RAWOBJS)
-       $(CC) -o $@ $(OBJS) $(RAWOBJS) $(LDFLAGS)
-       $(STRIP) -s -w -R .comment -R .ident -R .debug* $@*
-
-clean:
-       $(RM) -f $(BINS) $(CBINS) $(OBJS) $(RAWOBJS) encode encode.exe \
-               stdout.txt stderr.txt
diff --git a/tests/sdl-client/README b/tests/sdl-client/README
deleted file mode 100644 (file)
index 222484f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-$Id: README,v 1.16 2006/05/23 01:32:50 mmondor Exp $
-
-An attempt to develop a portable game client using SDL among unix
-and windows operating systems.  The only officially supported
-compiler should be GCC (and mingw under windows, avoiding the need
-for cygwin libraries).  The compiling/development environment when
-under windows will use cygwin to provide a shell, vim and cvs,
-while compile options will be specified as needed for it to use
-the mingw compiler (which also comes as part of cygwin).
-
-Initial tests will be using SDL, SDL_mixer and SDL_net.
-
-If all works well, it should also be easy to use OpenGL portably.
-I was already able to get portable SDL/OpenGL code working, a while
-ago, but this generated no sound and had no network requirements.
-Hence this test.
-
-Moreover, the test server under kqueue/ needed a client for further
-testing to be possible at its development stage.
-
-Since SDL_net does not provide non-blocking I/O (and it remains
-unclear if windows supports this properly), a decision was made to
-port to SDL an inter-thread messaging library I had done for use
-with POSIX threads, and to use multiple threads.
-
-One thread will be used to send data to the server, another thread
-to receive data form the server, yet another thread to deal with
-all user input events, and a main thread to receive all those events
-in an asynchroneous manner form the utility threads and run the
-main loop.
-
-04:21 <@lucca> one thread to send, one thread to receive, one thread to poll
-           for io events, and one thread to bring them all and in the darkness
-           bind them.
-
-:)
-
-Ogg-vorbis will be used for music, using SDL_mixer.  Ship rotations
-will be performed using SDL_gfx.
-
-It is very important to avoid having to link this client statically
-against GPL or LGPL libraries, because of the viral nature of those
-licenses.  I do not intend to release my code under those licenses.
-If it ever publically is released, it shall be done under a MIT/BSD
-derived license.
-
-I am also thinking about dedicating a thread for the connect state
-to the server, or possibly to have the writer or reader thread also
-perform that task.
-
-It is possible that a thread be ideal for rendering as well.  It
-could be notified when a screen refresh is wanted, when it could
-set a flag.  When it's time for it to draw a frame (honoring FPS),
-it would if the flag is set, or perhaps it simply could when it
-wants.  I wonder if it would be appropriate for the display thread
-to not need a mutex, since it would always be read-only accessing
-the data.
-
-Anticipated design so far:
-       Main thread
-       User events thread
-       Network receive thread
-       Network Send/Connect thread
-       Display thread (the Receive thread will draw for now).
-
-It is possible that states may be desired.  For instance, there
-would be the connection state, the one where the user and client
-have to provide authentication information (this could be part of
-connect phase perhaps), and in-game state.
-
-At first, as a test, the world will all be seen by everyone and
-will fit into their screen.  A world of 1024x768 could be used for
-this :) Then there will probably be addition of a chat system with
-messages window, to continue enhancing the protocol.  Things will
-go on from there...
-
-Hmm for now I want to simply use a joypad.
-- Button 0 fires in direction of the paddle direction.
-- Buttons 1 and 3 could act like button 0, to provide secondary weapon (1)
-  and special weapon (3).
-- Button 2 attempts to correct navigation direction in the direction
-  of the paddle.
-- Button 6 would accelerate.
-- Button 7 would decelerate.
-- Button 4 could toggle shields
-- Button 5 could toggle cloak
-
-Equivalent keyboard layout:
-- uiojlm,. would change angle just like the gamepad directions.
-- w would toggle cloak
-- s would toggle shield
-- z would thrust up
-- a would thrust down
-- d would cause direction change
-- space would torp
-- f would fire second weapon
-- g would fire special weapon
-
-And we're already out of buttons, we can't beam up/down armies or
-bomb.  Unless button 3 was special instead of a special weapon,
-and allowed to perform various commands depending on the paddle
-direction (i.e. up/down to beam up/down, left to bomb).  This also
-means that orbiting/launching would need to be automatic.  Of course
-all this is if we're thinking about a game like netrek.  But we'll
-simply only allow dogfighting at first.
-
-Now it becomes tricky how I'll minimize bandwidth sent from the
-client to the server.  Probably that buttons events will be monitored,
-and then current paddle direction when required.  In the case of
-direction change button, the last paddle direction applied would
-be remembered, and if the same, the event could be dropped.  If
-not, send a direction change packet.  What happens if a button
-remains pressed while a direction change occurs?  We probably should
-ignore it.
-
-
-Threading limitations under win32
-=================================
-
-There seem to be bugs when using SDL with multiple threads under windows
-which I did not observe on unix systems.  The docs specify that the main
-thread should perform the drawing, but it wasn't specified that another
-thread than the initial one would not be able to obtain all user input
-events on windows.  Typed keys would not be received, for instance.
-
-It then appears that most of the processing must be done in the main
-initial thread, while only networking related blocking functions will
-be done in slave threads.
-
-There also seem to be other windows-specific problems using SDL threads,
-such as instability.  I have noticed that when using another thread
-for user events reception, part of the application would often lockup,
-despite my code properly using mutexes as required, and all sound and
-greaphics being performed by the main initial thread nevertheless.
-These problems were also not found to occur on unix systems.
-
-The design was thus changed for now, and threads will be used for SDL_net
-functions only, since they are blocking.  Let's hope that this will work
-stably, however.  It remains to be tested.
-
-
-Storing images and sound samples as part of the executable binary
-=================================================================
-
-I was able to include read-only (.rodata) and read-write (.data) into
-binaries directly from files using objcopy and linking them on NetBSD,
-Linux and cygwin-mingw.  The SDL_image library, which I now successfully
-built for mingw, includes functions that can use RWops, and the SDL
-library allows to easily create RWops from memory buffers.  Moreover, the
-SDL_mixer library also allows to do this to load sound samples.  I should
-thus modify the makefiles and code to very easily use these features.
-
-The SDL_mixer library however does not allow by itself to do this easily
-with music files.  However, thise generally being considerably larger,
-it should not be a problem and they can remain external.
-
-If this works fine, it would be easy to generate a cryptographic block
-cipher key at build time and to include that key within the executable
-as well.  Copies of the binary files to be included could then be
-encrypted using that cipher to a temporary copy which will be linked
-in, and an initialization function could be provided to unencrypt the
-files prior to use.  Of course, since the key is also in the executable,
-there is no real security.  However, it could prevent computer-illiterate
-people from too easily ripping our original content.  RC4 could be used
-for this for instance, or even a much more simple custom encoding
-algorithm :)
-
-
-Using a map
-===========
-
-We probably want to randomize the ship's positions on the map.
-Randomization in this respect could be done on a position in a
-circle of varied radius distance to the location of the actual
-ship.  This would prevent clients from being able to exactly fire
-at the actual ship position using the map (which also would make
-cloaking useful against an unofficial client).
-
-
-PROGRAMMING STYLE
-=================
-
-The style chosen for this project consists of the (Net)BSD KNF style
-(Kernel Normal Form) style borrowed from.  All code should conform to it.
-Additionally, lint(1)-style comments are used to make the code clearer
-for future code auditors.
-
-
-
-Matt
diff --git a/tests/sdl-client/bmp/FedCA.bmp b/tests/sdl-client/bmp/FedCA.bmp
deleted file mode 100644 (file)
index be3a562..0000000
Binary files a/tests/sdl-client/bmp/FedCA.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/README b/tests/sdl-client/bmp/README
deleted file mode 100644 (file)
index 4f0b49d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-For these tests, the winxp ships library were borrowed temporarily.
diff --git a/tests/sdl-client/bmp/RomDD.bmp b/tests/sdl-client/bmp/RomDD.bmp
deleted file mode 100644 (file)
index 50e429a..0000000
Binary files a/tests/sdl-client/bmp/RomDD.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/fedship.bmp b/tests/sdl-client/bmp/fedship.bmp
deleted file mode 100755 (executable)
index 465806f..0000000
Binary files a/tests/sdl-client/bmp/fedship.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/indship.bmp b/tests/sdl-client/bmp/indship.bmp
deleted file mode 100755 (executable)
index 1a7e39b..0000000
Binary files a/tests/sdl-client/bmp/indship.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/kliship.bmp b/tests/sdl-client/bmp/kliship.bmp
deleted file mode 100755 (executable)
index cf52598..0000000
Binary files a/tests/sdl-client/bmp/kliship.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1.bmp b/tests/sdl-client/bmp/misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1.bmp
deleted file mode 100644 (file)
index c55b172..0000000
Binary files a/tests/sdl-client/bmp/misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1.bmp b/tests/sdl-client/bmp/misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1.bmp
deleted file mode 100644 (file)
index 5c2ab05..0000000
Binary files a/tests/sdl-client/bmp/misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1.bmp b/tests/sdl-client/bmp/misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1.bmp
deleted file mode 100644 (file)
index e8ac5d4..0000000
Binary files a/tests/sdl-client/bmp/misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1.bmp b/tests/sdl-client/bmp/misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1.bmp
deleted file mode 100644 (file)
index 9e1d9f2..0000000
Binary files a/tests/sdl-client/bmp/misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/oriship.bmp b/tests/sdl-client/bmp/oriship.bmp
deleted file mode 100755 (executable)
index 166fb1a..0000000
Binary files a/tests/sdl-client/bmp/oriship.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/romship.bmp b/tests/sdl-client/bmp/romship.bmp
deleted file mode 100755 (executable)
index 753d38a..0000000
Binary files a/tests/sdl-client/bmp/romship.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/sbexpl.bmp b/tests/sdl-client/bmp/sbexpl.bmp
deleted file mode 100755 (executable)
index b06ffcf..0000000
Binary files a/tests/sdl-client/bmp/sbexpl.bmp and /dev/null differ
diff --git a/tests/sdl-client/bmp/shexpl.bmp b/tests/sdl-client/bmp/shexpl.bmp
deleted file mode 100755 (executable)
index 72a62c4..0000000
Binary files a/tests/sdl-client/bmp/shexpl.bmp and /dev/null differ
diff --git a/tests/sdl-client/conf.h b/tests/sdl-client/conf.h
deleted file mode 100644 (file)
index e0a91c9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* $Id: conf.h,v 1.6 2006/05/19 11:16:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Various hardcoded configuration parameters.
- */
-
-#define SERVER_HOST    "hal.xisop"
-#define SERVER_PORT    7777
diff --git a/tests/sdl-client/debug.c b/tests/sdl-client/debug.c
deleted file mode 100644 (file)
index 4dd5bae..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id: debug.c,v 1.2 2006/05/19 09:16:14 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-
-#ifndef NDEBUG
-void
-debug(const char *file, const char *func, int line, const char *fmt, ...)
-{
-       va_list lst;
-       char    buf[1024];
-
-       va_start(lst, fmt);
-       vsnprintf(buf, 1023, fmt, lst);
-       va_end(lst);
-       (void) fprintf(stderr, "%s:%s():%d - %s\n", file, func, line, buf);
-}
-
-void
-debug2(const char *file, const char *func, int line, const char *fmt, ...)
-{
-       va_list lst;
-       char    buf[1024];
-
-       va_start(lst, fmt);
-       vsnprintf(buf, 1023, fmt, lst);
-       va_end(lst);
-       (void) fprintf(stderr, "%s:%s():%d - %s\n", file, func, line, buf);
-
-       exit(EXIT_FAILURE);
-}
-#endif
diff --git a/tests/sdl-client/debug.h b/tests/sdl-client/debug.h
deleted file mode 100644 (file)
index 30827c0..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $Id: debug.h,v 1.2 2006/05/19 09:36:57 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-
-
-#ifndef NDEBUG
-
-/*
- * Macro similar to assert(3) but which does not exit the application. Will
- * instead log the condition unless DEBUG_ASSERT_ABORT is set.
- * Moreover, the aborting one actually simply calls exit(2) after logging the
- * error instead of generating a SIGABRT signal.
- */
-#ifdef ASSERT_ABORT
-#define ASSERT(c)              if (!(c))                               \
-   debug2(__FILE__, __func__, __LINE__, "ASSERT(" #c ") == %d", c);
-#else
-#define ASSERT(c)              if (!(c))                               \
-   debug(__FILE__, __func__, __LINE__, "ASSERT(" #c ") == %d", c);
-#endif
-
-#else
-
-#define ASSERT(c)              ;
-
-#endif
-
-
-
-void   debug(const char *, const char *, int, const char *, ...);
-void   debug2(const char *, const char *, int, const char *, ...);
-
-
-
-#endif
diff --git a/tests/sdl-client/decode.c b/tests/sdl-client/decode.c
deleted file mode 100644 (file)
index f0b0bc4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* $Id: decode.c,v 1.2 2006/05/10 01:28:01 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Function to easily decode data processed by the encode command.
- */
-
-
-
-#include <stdio.h>
-#include <stdint.h>
-
-#include <decode.h>
-
-
-
-void
-decode(void **ndata, size_t *nsize, void *data, size_t size)
-{
-       uint8_t *ptr, *tptr, *key;
-
-       ptr = (uint8_t *)data;
-       *ndata = &ptr[4];
-       *nsize = size - 4;
-
-       for (key = ptr, ptr = &ptr[4], tptr = &ptr[*nsize];
-           ptr < tptr; ptr++) {
-               *ptr ^= key[0] ^ key[1] ^ key[2] ^ key[3];
-               key[0]--;
-               key[1]++;
-               key[2] -= 3;
-               key[3] += 3;
-       }
-}
diff --git a/tests/sdl-client/decode.h b/tests/sdl-client/decode.h
deleted file mode 100644 (file)
index ab5f3b6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* $Id: decode.h,v 1.1 2006/05/10 00:48:40 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Function to easily decode data processed by the encode command.
- */
-
-
-
-#ifndef DECODE_H
-#define DECODE_H
-
-
-
-void   decode(void **, size_t *, void *, size_t);
-
-
-
-#endif
diff --git a/tests/sdl-client/dlist.h b/tests/sdl-client/dlist.h
deleted file mode 100644 (file)
index a3bc766..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* $Id: dlist.h,v 1.5 2006/04/27 10:59:19 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2006, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#ifndef DLIST_H
-#define DLIST_H
-
-
-
-typedef struct list    list_t;
-typedef struct node    node_t;
-
-
-
-struct node {
-       node_t          *prev, *next;
-};
-
-struct list {
-       node_t          *top, *bottom;
-       int             nodes;
-};
-
-
-
-/* Some macros to optimize operations on doubly linked lists */
-#define DLIST_INITIALIZER      {NULL, NULL, 0}
-
-#define DLIST_INIT(lst)                do {                                    \
-       (lst)->top = (lst)->bottom = NULL;                              \
-       (lst)->nodes = 0;                                               \
-} while (/* CONSTCOND */0)
-
-#define DLIST_UNLINK(lst, nod) do {                                    \
-       register node_t *prev = (nod)->prev, *next = (nod)->next;       \
-                                                                       \
-       if (prev != NULL)                                               \
-               prev->next = next;                                      \
-       else                                                            \
-               (lst)->top = next;                                      \
-       if (next != NULL)                                               \
-               next->prev = prev;                                      \
-       else                                                            \
-               (lst)->bottom = prev;                                   \
-       (lst)->nodes--;                                                 \
-} while (/* CONSTCOND */0)
-
-#define DLIST_APPEND(lst, nod) do {                                    \
-       register node_t *tmp = (lst)->bottom;                           \
-                                                                       \
-       if (tmp != NULL) {                                              \
-               tmp->next = (nod);                                      \
-               (nod)->prev = tmp;                                      \
-               (nod)->next = NULL;                                     \
-               (lst)->bottom = (nod);                                  \
-       } else {                                                        \
-               (lst)->bottom = (lst)->top = (nod);                     \
-               (nod)->next = (nod)->prev = NULL;                       \
-       }                                                               \
-       (lst)->nodes++;                                                 \
-} while (/* CONSTCOND */0)
-
-#define DLIST_INSERT(lst, nod) do {                                    \
-       register node_t *tmp = (lst)->top;                              \
-                                                                       \
-       if (tmp != NULL) {                                              \
-               tmp->prev = (nod);                                      \
-               (nod)->prev = NULL;                                     \
-               (nod)->next = tmp;                                      \
-               (lst)->top = (nod);                                     \
-       } else {                                                        \
-               (lst)->top = (lst)->bottom = (nod);                     \
-               (nod)->next = (nod)->prev = NULL;                       \
-       }                                                               \
-       (lst)->nodes++;                                                 \
-} while (/* CONSTCOND */0)
-
-#define DLIST_INSERTAT(lst, atnode, nod) do {                          \
-       register node_t *prev = (atnode)->prev, *next = (atnode);       \
-                                                                       \
-       (nod)->next = next;                                             \
-       next->prev = (nod);                                             \
-       if (prev != NULL) {                                             \
-               prev->next = (nod);                                     \
-               (nod)->prev = prev;                                     \
-       } else {                                                        \
-               (lst)->top = (nod);                                     \
-               (nod)->prev = NULL;                                     \
-       }                                                               \
-       (lst)->nodes++;                                                 \
-} while (/* CONSTCOND */0)
-
-#define DLIST_SWAP(dst, src, nod, ins) do {                            \
-       register node_t *prev = (nod)->prev, *next = (nod)->next;       \
-                                                                       \
-       if (prev != NULL)                                               \
-               prev->next = next;                                      \
-       else                                                            \
-               (src)->top = next;                                      \
-       if (next != NULL)                                               \
-               next->prev = prev;                                      \
-       else                                                            \
-               (src)->bottom = prev;                                   \
-       (src)->nodes--;                                                 \
-       if ((ins)) {                                                    \
-               if ((prev = (dst)->top) != NULL) {                      \
-                       prev->prev = (nod);                             \
-                       (nod)->prev = NULL;                             \
-                       (nod)->next = prev;                             \
-                       (dst)->top = (nod);                             \
-               } else {                                                \
-                       (dst)->top = (dst)->bottom = (nod);             \
-                       (nod)->next = (nod)->prev = NULL;               \
-               }                                                       \
-       } else {                                                        \
-               if ((prev = (dst)->bottom) != NULL) {                   \
-                       prev->next = (nod);                             \
-                       (nod)->prev = prev;                             \
-                       (nod)->next = NULL;                             \
-                       (dst)->bottom = (nod);                          \
-               } else {                                                \
-                       (dst)->bottom = (dst)->top = (nod);             \
-                       (nod)->next = (nod)->prev = NULL;               \
-               }                                                       \
-       }                                                               \
-       (dst)->nodes++;                                                 \
-} while (/* CONSTCOND */0)
-
-#define DLIST_TOP(lst)         ((void *)((list_t *)(lst))->top)
-#define DLIST_BOTTOM(lst)      ((void *)((list_t *)(lst))->bottom)
-#define DLIST_NEXT(var)                ((void *)((node_t *)(var))->next)
-#define DLIST_PREV(var)                ((void *)((node_t *)(var))->prev)
-
-#define DLIST_FOREACH(lst, var)                                                \
-    for ((var) = DLIST_TOP((lst)); (var) != NULL; (var) = DLIST_NEXT((var)))
-
-#define DLIST_NODES(lst)       (((list_t *)(lst))->nodes)
-
-
-
-#endif
diff --git a/tests/sdl-client/encode.c b/tests/sdl-client/encode.c
deleted file mode 100644 (file)
index 66701da..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $Id: encode.c,v 1.4 2006/05/19 03:35:43 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHT RESERVED.
- */
-
-/*
- * Very simple encoding algorithm.  Given a 32-bit key,
- * it will encode the supplied file using XOR encoding and changing
- * the integer values.
- * For even more simplicity, the key is randomly generated and stored as
- * part of the output file as the first four bytes :)
- * This really shouldn't be considered encryption, it merely is simple
- * encoding for computer-illiterates to not too easily rip our images
- * and sound samples.
- */
-
-
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-
-#define        BUF_SIZE        65536
-
-
-
-int    main(int, char **);
-void   encode(uint8_t *, size_t, uint8_t *key);
-
-
-
-int
-main(int argc, char **argv)
-{
-       FILE            *ifh, *ofh;
-       uint8_t         key[4], *buf;
-       size_t          s;
-
-       if (argc != 4) {
-               (void) fprintf(stderr,
-                   "Usage: encode <infile> <outfile> <seed>\n");
-               exit(EXIT_FAILURE);
-       }
-
-       if ((buf = malloc(BUF_SIZE)) == NULL) {
-               (void) fprintf(stderr,
-                   "Could not allocate %d bytes\n", BUF_SIZE);
-               exit(EXIT_FAILURE);
-       }
-
-       if ((ifh = fopen(argv[1], "r")) == NULL) {
-               (void) fprintf(stderr,
-                   "Cannot open '%s' for reading\n", argv[1]);
-               exit(EXIT_FAILURE);
-       }
-
-       if ((ofh = fopen(argv[2], "w")) == NULL) {
-               (void) fprintf(stderr,
-                   "Cannot open '%s' for writing\n", argv[2]);
-               exit(EXIT_FAILURE);
-       }
-
-       /* Generate random key and write it to output file */
-       srand((unsigned int)strtoul(argv[3], NULL, 10));
-       key[0] = rand() & 0xff;
-       key[1] = rand() & 0xff;
-       key[2] = rand() & 0xff;
-       key[3] = rand() & 0xff;
-       if (fwrite(key, 1, 4, ofh) != 4) {
-               (void) fprintf(stderr,
-                   "Error writing key to '%s'\n", argv[2]);
-               exit(EXIT_FAILURE);
-       }
-
-       while ((s = fread(buf, 1, BUF_SIZE, ifh)) > 0) {
-               encode(buf, s, key);
-               if (fwrite(buf, 1, s, ofh) != s) {
-                       (void) fprintf(stderr,
-                           "Error writing to '%s'\n", argv[2]);
-                       exit(EXIT_FAILURE);
-               }
-       }
-
-       (void) fclose(ofh);
-       (void) fclose(ifh);
-       free(buf);
-
-       exit(EXIT_SUCCESS);
-}
-
-void
-encode(uint8_t *data, size_t size, uint8_t *key)
-{
-       uint8_t *tdata;
-
-       for (tdata = data + size; data < tdata; data++) {
-               *data ^= key[0] ^ key[1] ^ key[2] ^ key[3];
-               key[0]--;
-               key[1]++;
-               key[2] -= 3;
-               key[3] += 3;
-       }
-}
diff --git a/tests/sdl-client/fnt/10x20.fnt b/tests/sdl-client/fnt/10x20.fnt
deleted file mode 100644 (file)
index 99b3486..0000000
Binary files a/tests/sdl-client/fnt/10x20.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/5x7.fnt b/tests/sdl-client/fnt/5x7.fnt
deleted file mode 100644 (file)
index 3612165..0000000
Binary files a/tests/sdl-client/fnt/5x7.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/5x8.fnt b/tests/sdl-client/fnt/5x8.fnt
deleted file mode 100644 (file)
index 01add72..0000000
Binary files a/tests/sdl-client/fnt/5x8.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x10.fnt b/tests/sdl-client/fnt/6x10.fnt
deleted file mode 100644 (file)
index 3c49f20..0000000
Binary files a/tests/sdl-client/fnt/6x10.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x12.fnt b/tests/sdl-client/fnt/6x12.fnt
deleted file mode 100644 (file)
index 156865b..0000000
Binary files a/tests/sdl-client/fnt/6x12.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x13.fnt b/tests/sdl-client/fnt/6x13.fnt
deleted file mode 100644 (file)
index e259f1a..0000000
Binary files a/tests/sdl-client/fnt/6x13.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x13B.fnt b/tests/sdl-client/fnt/6x13B.fnt
deleted file mode 100644 (file)
index 503b773..0000000
Binary files a/tests/sdl-client/fnt/6x13B.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x13O.fnt b/tests/sdl-client/fnt/6x13O.fnt
deleted file mode 100644 (file)
index cb5a27f..0000000
Binary files a/tests/sdl-client/fnt/6x13O.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/6x9.fnt b/tests/sdl-client/fnt/6x9.fnt
deleted file mode 100644 (file)
index cca4689..0000000
Binary files a/tests/sdl-client/fnt/6x9.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/7x13.fnt b/tests/sdl-client/fnt/7x13.fnt
deleted file mode 100644 (file)
index d20852e..0000000
Binary files a/tests/sdl-client/fnt/7x13.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/7x13B.fnt b/tests/sdl-client/fnt/7x13B.fnt
deleted file mode 100644 (file)
index 9f3fbed..0000000
Binary files a/tests/sdl-client/fnt/7x13B.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/7x13O.fnt b/tests/sdl-client/fnt/7x13O.fnt
deleted file mode 100644 (file)
index e5b7732..0000000
Binary files a/tests/sdl-client/fnt/7x13O.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/7x14.fnt b/tests/sdl-client/fnt/7x14.fnt
deleted file mode 100644 (file)
index fdcd752..0000000
Binary files a/tests/sdl-client/fnt/7x14.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/7x14B.fnt b/tests/sdl-client/fnt/7x14B.fnt
deleted file mode 100644 (file)
index 939aa63..0000000
Binary files a/tests/sdl-client/fnt/7x14B.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/8x13.fnt b/tests/sdl-client/fnt/8x13.fnt
deleted file mode 100644 (file)
index 9de72b4..0000000
Binary files a/tests/sdl-client/fnt/8x13.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/8x13B.fnt b/tests/sdl-client/fnt/8x13B.fnt
deleted file mode 100644 (file)
index 96179a0..0000000
Binary files a/tests/sdl-client/fnt/8x13B.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/8x13O.fnt b/tests/sdl-client/fnt/8x13O.fnt
deleted file mode 100644 (file)
index a38a371..0000000
Binary files a/tests/sdl-client/fnt/8x13O.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/9x15.fnt b/tests/sdl-client/fnt/9x15.fnt
deleted file mode 100644 (file)
index 349e5bd..0000000
Binary files a/tests/sdl-client/fnt/9x15.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/9x15B.fnt b/tests/sdl-client/fnt/9x15B.fnt
deleted file mode 100644 (file)
index 23bc97e..0000000
Binary files a/tests/sdl-client/fnt/9x15B.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/9x18.fnt b/tests/sdl-client/fnt/9x18.fnt
deleted file mode 100644 (file)
index 0651c97..0000000
Binary files a/tests/sdl-client/fnt/9x18.fnt and /dev/null differ
diff --git a/tests/sdl-client/fnt/9x18B.fnt b/tests/sdl-client/fnt/9x18B.fnt
deleted file mode 100644 (file)
index d93d09d..0000000
Binary files a/tests/sdl-client/fnt/9x18B.fnt and /dev/null differ
diff --git a/tests/sdl-client/main.c b/tests/sdl-client/main.c
deleted file mode 100644 (file)
index 100de1c..0000000
+++ /dev/null
@@ -1,872 +0,0 @@
-/* $Id: main.c,v 1.73 2006/05/23 01:32:50 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-/* STANDARD HEADERS */
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* THIRD PARTY LIBRARY HEADERS */
-#include <SDL.h>
-#include <SDL_image.h>
-#include <SDL_thread.h>
-#include <SDL_rotozoom.h>
-#include <SDL_gfxPrimitives.h>
-#include <SDL_framerate.h>
-#include <SDL_mixer.h>
-#include <SDL_net.h>
-
-/* APPLICATION HEADERS */
-#include <main.h>
-#include <debug.h>
-#include <screen.h>
-#include <packets.h>
-#include <thread_msg.h>
-#include <thread_net_recv.h>
-#include <thread_net_send.h>
-#include <rawobjs.h>
-#include <decode.h>
-
-
-
-/* DEFINITIONS */
-
-enum userevents {
-       UE_FPS
-};
-
-struct font {
-       int     w, h;
-       void    *data;
-       size_t  size;
-};
-
-#define        VECTOR_X(x, a, r)       ((int)(x) + (cos_table[(a)] * (r)))
-#define        VECTOR_Y(y, a, r)       ((int)(y) + (sin_table[(a)] * (r)))
-
-
-
-/* PRIVATE PROTOTYPES */
-
-int                    main(int, char **);
-
-static void            axis_angle_update(void);
-static void            handle_uevent(SDL_Event *);
-static void            handle_recvmsg(thread_amsg_t *);
-static void            objects_update(void);
-static void            frame_clear(void);
-static void            frame_draw(void);
-
-static int             surface_blit_angle(SDL_Surface *, int, int, double,
-                           int);
-static SDL_Surface     *bmp_load_key(void *, size_t);
-
-static Mix_Chunk       *sample_load(void *, size_t);
-
-static struct font     *font_load(void *, size_t, int, int);
-static void            font_blit_string(struct font *, int, int,
-                           const char *, uint8_t, uint8_t, uint8_t, uint8_t);
-
-static Uint32          fpscnt_callback(Uint32, void *);
-
-static void            trig_init(void);
-
-
-
-/* PUBLIC GLOBALS */
-
-thread_port_t          main_port;
-
-
-
-/* PRIVATE GLOBALS */
-
-static int             joy_angle = 0;
-
-static int             shields = 0, cloaked = 0, nav_thrust = 0,
-                       cur_nav_thrust = 0, nav_angle = 0,
-                       cur_nav_angle = 0, nav_pos_x = 512, nav_pos_y = 384,
-                       max_thrust = 12;
-static SDL_Surface     *rship, *fship;
-
-static Mix_Chunk       *snd_cloak, *snd_uncloak, *snd_shield, *snd_unshield,
-                       *snd_torp, *snd_hit, *snd_explode;
-
-static FPSmanager      fpsh;
-static SDL_TimerID     fpst;
-static char            fpsstr[8];
-static int             fpscnt;
-
-static struct font     *font;
-
-static double          cos_table[360], sin_table[360];
-static int             fired = 0;
-
-
-
-/* PRIVATE FUNCTIONS */
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-       thread_ring_t   main_ring;
-       SDL_Thread      *recv_threadid, *send_threadid;
-       Mix_Music       *mus;
-
-       /* Initialization */
-       screen_init();
-       trig_init();
-       (void) SDL_ShowCursor(0);
-       (void) SDL_EnableKeyRepeat(0, 0);
-
-       /*
-        * Ignore a few events with potentially high frequency but which
-        * we don't need
-        */
-       (void) SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
-       (void) SDL_EventState(SDL_JOYAXISMOTION, SDL_IGNORE);
-       (void) SDL_EventState(SDL_JOYBALLMOTION, SDL_IGNORE);
-       (void) SDL_EventState(SDL_JOYHATMOTION, SDL_IGNORE);
-       (void) SDL_EventState(SDL_KEYUP, SDL_IGNORE);
-
-       /*
-        * Network
-        */
-       if (SDLNet_Init() != 0) {
-               (void) fprintf(stderr, "main() - SDLNet_Init() - %s\n",
-                   SDLNet_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * Audio
-        */
-       if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) != 0) {
-               (void) fprintf(stderr, "main() - Mix_OpenAudio() - %s\n",
-                   Mix_GetError());
-               exit(EXIT_FAILURE);
-       }
-       snd_cloak = sample_load((void *)&_binary_wav_nt_cloaked_wav_enc_start,
-           (size_t)&_binary_wav_nt_cloaked_wav_enc_size);
-       snd_uncloak = sample_load(
-           (void *)&_binary_wav_nt_uncloak_wav_enc_start,
-           (size_t)&_binary_wav_nt_uncloak_wav_enc_size);
-       snd_shield = sample_load(
-           (void *)&_binary_wav_nt_shield_up_wav_enc_start,
-           (size_t)&_binary_wav_nt_shield_up_wav_enc_size);
-       snd_unshield = sample_load(
-           (void *)&_binary_wav_nt_shield_down_wav_enc_start,
-           (size_t)&_binary_wav_nt_shield_down_wav_enc_size);
-       snd_torp = sample_load(
-           (void *)&_binary_wav_nt_fire_torp_other_wav_enc_start,
-           (size_t)&_binary_wav_nt_fire_torp_other_wav_enc_size);
-       snd_hit = sample_load((void *)&_binary_wav_nt_plasma_hit_wav_enc_start,
-           (size_t)&_binary_wav_nt_plasma_hit_wav_enc_size);
-       snd_explode = sample_load(
-           (void *)&_binary_wav_nt_explosion_other_wav_enc_start,
-           (size_t)&_binary_wav_nt_explosion_other_wav_enc_size);
-       (void) Mix_AllocateChannels(16);
-       (void) Mix_ReserveChannels(2);
-       if ((mus = Mix_LoadMUS("ogg/1.ogg")) == NULL) {
-               (void) fprintf(stderr, "main() - Mix_LoadMUS() - %s\n",
-                   Mix_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if (Mix_PlayMusic(mus, -1) != 0) {
-               (void) fprintf(stderr, "main() - Mix_PlayMusic() - %s\n",
-                   Mix_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * Bitmap graphics
-        */
-       rship = bmp_load_key((void *)&_binary_bmp_RomDD_bmp_enc_start,
-           (size_t)&_binary_bmp_RomDD_bmp_enc_size);
-       fship = bmp_load_key((void *)&_binary_bmp_FedCA_bmp_enc_start,
-           (size_t)&_binary_bmp_FedCA_bmp_enc_size);
-
-       /*
-        * Bitmap fonts
-        */
-       font = font_load((void *)&_binary_fnt_7x13_fnt_enc_start,
-           (size_t)&_binary_fnt_7x13_fnt_enc_size, 7, 13);
-
-       /*
-        * We're already the main thread.
-        * Initialize our message port and notification ring.
-        */
-       if (thread_ring_init(&main_ring) == -1) {
-               (void) fprintf(stderr,
-                   "main() - thread_ring_init(main_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if (thread_port_init(&main_port) == -1) {
-               (void) fprintf(stderr,
-                   "main() - thread_port_init(main_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       thread_port_set_ring(&main_port, &main_ring);
-
-       /* XXX We should obtain user login information */
-
-       if (thread_amsg_pool_init() != 0) {
-               (void) fprintf(stderr, "main() - thread_amsg_init()\n");
-               exit(EXIT_FAILURE);
-       }
-
-       /* Launch network utility threads */
-       if ((recv_threadid = SDL_CreateThread(thread_net_recv, NULL))
-           == NULL) {
-               (void) fprintf(stderr,
-                   "main() - SDL_CreateThread(thread_net_recv) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if ((send_threadid = SDL_CreateThread(thread_net_send, NULL))
-           == NULL) {
-               (void) fprintf(stderr,
-                   "main() - SDL_CreateThread(thread_net_send) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * XXX Wait until we receive the server's connection status.
-        * We should display a "connecting to server" or such message to the
-        * user during this time.
-        */
-       {
-               struct msg_connect      *cmsg;
-
-               while ((cmsg = (struct msg_connect *)thread_msg_get(
-                   &main_port)) == NULL)
-                       (void) thread_ring_wait(&main_ring, -1);
-
-               if (cmsg->status == -1) {
-                       (void) fprintf(stderr, "%s\n", cmsg->error);
-                       exit(EXIT_FAILURE);
-               }
-
-               (void) thread_msg_reply(&cmsg->msg);
-       }
-
-       /* FPS counter initialization */
-       (void) strcpy(fpsstr, "000 fps");
-       fpscnt = 0;
-       fpst = SDL_AddTimer(5000, fpscnt_callback, NULL);
-
-       /* FPS management initialization */
-       SDL_initFramerate(&fpsh);
-       SDL_setFramerate(&fpsh, 10);
-
-       /*
-        * Main loop.
-        * Listen for messages and events and process them, while drawing
-        * frames.
-        *
-        * XXX There remain design choices to make here.
-        * We could only draw a frame once we received all data for a frame
-        * from the server, thus waiting for the EndOfFrame message to draw,
-        * in which case we only need to bother drawing the current new
-        * received data.  If we did this, we potentially could reduce the
-        * incomming asynchroneous messages rate so that a single one is sent
-        * once every messages for a frame were obtained.  This method would
-        * probably be the most efficient, while allowing the client to update
-        * its display as fast as it is able to obtain the server information
-        * for a frame.  However, this also means that for a very large world,
-        * if a map exists or such, there could be more data needing to be
-        * sent per frame, unless there also were in a frame the information
-        * to update the existing world information, which would be similar to
-        * the second method.  Hmm since we need to send a difference packet
-        * for every object on the map, or to possibly resend their position,
-        * what could be done is having the server sending updates less
-        * frequently for that data.  Although, we would need to make sure to
-        * avoid causing lag to the normal 10fps display when
-        * sending/processing large map packets.  We possibly could
-        * intermingle some map information data per normal frame, having the
-        * server round-robin the map information among the clients in a
-        * distributed way?  Say we have 50 connected clients, and that we
-        * want a map update rate of approximately 1 second interval, we could
-        * send the data among them at 50 / 10, meaning that we send each
-        * client update of 5 clients.  With round robin this means that every
-        * client, 10 times per second are receiving enough update information
-        * so that within a second the whole map be updated.  Of course, we
-        * would need not to break this when clients connect/disconnect.
-        *
-        * Or, we could instead maintain our own known world and display
-        * states and only update them via the messages received from the
-        * server, allowing us to maintain a steady frame rate (although this
-        * would also mean that no change could be made between certain
-        * frames).
-        */
-       for (;;) {
-               thread_amsg_t   *amsg;
-               SDL_Event       ev;
-
-               /* Process incomming server messages. */
-               while ((amsg = (thread_amsg_t *)thread_msg_get(&main_port))
-                   != NULL) {
-                       handle_recvmsg(amsg);
-                       thread_amsg_destroy(amsg);
-               }
-
-               /* Update gamepad current angle. */
-               if (gamepad != NULL)
-                       axis_angle_update();
-
-               /*
-                * Process incomming user events, sending corresponding
-                * messages to the server when appropriate.
-                */
-               while (SDL_PollEvent(&ev))
-                       handle_uevent(&ev);
-
-               /*
-                * XXX Probably to be done on the server, but such a step
-                * might still be necessary perhaps.
-                * Update objects position in preparation to draw the current
-                * frame.
-                */
-               objects_update();
-
-               /*
-                * Draw current frame and wait until it's time to draw another
-                * frame.
-                */
-               frame_draw();
-               SDL_framerateDelay(&fpsh);
-       }
-       /* NOTREACHED */
-
-       thread_port_set_ring(&main_port, NULL);
-       thread_port_destroy(&main_port);
-       thread_ring_destroy(&main_ring);
-
-       exit(EXIT_SUCCESS);
-}
-
-static void
-axis_angle_update(void)
-{
-       int     angle, x, y;
-
-       angle = joy_angle;
-
-       /* On win32 -1 is reported for dead state instead of 0! */
-       if ((x = SDL_JoystickGetAxis(gamepad, 0)) > 127)
-               x = 1;
-       else if (x < -128)
-               x = -1;
-       else
-               x = 0;
-
-       if ((y = SDL_JoystickGetAxis(gamepad, 1)) > 127)
-               y = 1;
-       else if (y < -128)
-               y = -1;
-       else
-               y = 0;
-
-       if (x == 0 && y == 0)
-               return;
-       if (x == 0 && y == -1)
-               angle = 0;
-       else if (x == 1 && y == -1)
-               angle = 45;
-       else if (x == 1 && y == 0)
-               angle = 90;
-       else if (x == 1 && y == 1)
-               angle = 135;
-       else if (x == 0 && y == 1)
-               angle = 180;
-       else if (x == -1 && y == 1)
-               angle = 225;
-       else if (x == -1 && y == 0)
-               angle = 270;
-       else if (x == -1 && y == -1)
-               angle = 315;
-
-       if (joy_angle != angle)
-               joy_angle = angle;
-
-       return;
-}
-
-static void
-handle_uevent(SDL_Event *ev)
-{
-
-       if (ev->type == SDL_MOUSEMOTION)
-           return;
-
-       /*
-        * Quit commands events.
-        */
-       if ((ev->type == SDL_KEYDOWN && ev->key.keysym.sym == SDLK_ESCAPE) ||
-           ev->type == SDL_QUIT)
-               exit(EXIT_FAILURE);
-
-       /*
-        * Button events.  joy_angle affects several of them.
-        * We currently ignore release events.
-        */
-       if (ev->type == SDL_JOYBUTTONDOWN) {
-               int     ch;
-
-               if (ev->jbutton.state != 1)
-                       return;
-
-               switch (ev->jbutton.button) {
-               case 0:
-                       /* Torp */
-                       if ((ch = Mix_PlayChannel(-1, snd_torp, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       fired = 1;
-                       break;
-               case 1:
-                       /* Secondary weapon */
-                       if ((ch = Mix_PlayChannel(-1, snd_hit, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       break;
-               case 2:
-                       /* Navigation direction change */
-                       if (nav_angle != joy_angle)
-                               nav_angle = joy_angle;
-                       break;
-               case 3:
-                       /* Special weapon */
-                       if ((ch = Mix_PlayChannel(-1, snd_explode, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       break;
-               case 4:
-                       /* Toggle shields */
-                       shields = (shields == 0 ? 1 : 0);
-                       Mix_PlayChannel(1,
-                           (shields == 1 ? snd_shield : snd_unshield), 0);
-                       break;
-               case 5:
-                       /* Toggle cloak */
-                       cloaked = (cloaked == 0 ? 1 : 0);
-                       Mix_PlayChannel(2,
-                           (cloaked == 1 ? snd_cloak : snd_uncloak), 0);
-                       break;
-               case 6:
-                       /* Thrust accelerate */
-                       if (nav_thrust < max_thrust)
-                               nav_thrust++;
-                       break;
-               case 7:
-                       /* Thrust decelerate */
-                       if (nav_thrust > 0)
-                               nav_thrust--;
-                       break;
-               }
-
-               return;
-       }
-
-       /*
-        * Keyboard events
-        */
-       if (ev->type == SDL_KEYDOWN) {
-               int     angle = joy_angle, ch;
-
-               switch (ev->key.keysym.sym) {
-               /* Angle changes */
-               case SDLK_i:
-                       angle = 0;
-                       break;
-               case SDLK_o:
-                       angle = 45;
-                       break;
-               case SDLK_l:
-                       angle = 90;
-                       break;
-               case SDLK_PERIOD:
-                       angle = 135;
-                       break;
-               case SDLK_COMMA:
-                       angle = 180;
-                       break;
-               case SDLK_m:
-                       angle = 225;
-                       break;
-               case SDLK_j:
-                       angle = 270;
-                       break;
-               case SDLK_u:
-                       angle = 315;
-                       break;
-               /* Navigation change */
-               case SDLK_d:
-                       /* Direction */
-                       if (nav_angle != joy_angle)
-                               nav_angle = joy_angle;
-                       break;
-               case SDLK_z:
-                       /* Thrust up */
-                       if (nav_thrust < max_thrust)
-                               nav_thrust++;
-                       break;
-               case SDLK_a:
-                       /* Thrust down */
-                       if (nav_thrust > 0)
-                               nav_thrust--;
-                       break;
-               /* Weapons */
-               case SDLK_SPACE:
-                       /* Torp */
-                       if ((ch = Mix_PlayChannel(-1, snd_torp, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       fired = 1;
-                       break;
-               case SDLK_f:
-                       /* Secondary weapon */
-                       if ((ch = Mix_PlayChannel(-1, snd_hit, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       break;
-               case SDLK_g:
-                       /* Special weapon */
-                       if ((ch = Mix_PlayChannel(-1, snd_explode, 0)) != -1)
-                               Mix_SetPosition(ch, joy_angle, 50);
-                       break;
-               /* Toggles */
-               case SDLK_s:
-                       /* Shield */
-                       shields = (shields == 0 ? 1 : 0);
-                       Mix_PlayChannel(1,
-                           (shields == 1 ? snd_shield : snd_unshield), 0);
-                       break;
-               case SDLK_w:
-                       /* Cloak */
-                       cloaked = (cloaked == 0 ? 1 : 0);
-                       Mix_PlayChannel(2,
-                           (cloaked == 1 ? snd_cloak : snd_uncloak), 0);
-                       break;
-               default:
-                       break;
-               }
-
-               if (joy_angle != angle)
-                       joy_angle = angle;
-               return;
-       }
-
-}
-
-static void
-handle_recvmsg(thread_amsg_t *amsg)
-{
-
-       /* XXX */
-       if (amsg->size != -1)
-               (void) fwrite(amsg->data, amsg->size, 1, stdout);
-       else {
-               (void) fprintf(stderr, "Error reading from server socket\n");
-               exit(EXIT_FAILURE);
-       }
-}
-
-/*
- * These will normally occur on the server.
- * However, it's nice for temporary testing.
- */
-static void
-objects_update(void)
-{
-
-       /*
-        * XXX
-        * Adjust current thrust according to ship's acceleration/deceleration
-        * speeds in order to eventually reach nav_thrust.  It seems that
-        * we need floating point variables to perform this.
-        */
-       if (cur_nav_thrust != nav_thrust) {
-               if (cur_nav_thrust < nav_thrust)
-                       cur_nav_thrust++;
-               else
-                       cur_nav_thrust--;
-       }
-
-       /*
-        * XXX
-        * For now we also should use cos/sin and allow the ship to move
-        * around in its current direction at its current thrust.
-        * We should also bounce when reaching the borders for now,
-        * by reversing its angle.
-        */
-       if (cur_nav_thrust != 0) {
-               nav_pos_x = VECTOR_X(nav_pos_x, cur_nav_angle,
-                   cur_nav_thrust + 1);
-               nav_pos_y = VECTOR_Y(nav_pos_y, cur_nav_angle,
-                   cur_nav_thrust + 1);
-       }
-
-       /*
-        * XXX
-        * We need to rotate cur_nav_angle in the shortest direction to
-        * nav_angle, while making sure to always have angles in the range
-        * 0 - 359 only.  Moreover, if the degrees stepped are too large
-        * to exactly reach nav_angle, we want to just reach it at the last
-        * step.  To properly test the later condition, we step relatively
-        * to the current thrust.
-        */
-       if (cur_nav_angle != nav_angle) {
-               if (cur_nav_angle < nav_angle) {
-                       if ((cur_nav_angle += (max_thrust + 10) -
-                           cur_nav_thrust) > nav_angle)
-                               cur_nav_angle = nav_angle;
-               } else {
-                       if ((cur_nav_angle -= (max_thrust + 10) -
-                           cur_nav_thrust) < nav_angle)
-                               cur_nav_angle = nav_angle;
-               }
-       }
-}
-
-static void
-frame_clear(void)
-{
-       uint32_t        *ptr, *tptr;
-
-       /*
-       for (ptr = screen_surface->pixels,
-           tptr = &ptr[screen_width * screen_height];
-           ptr < tptr; ) {
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-               *ptr++ = 0x00000000;
-       }
-       */
-
-       for (ptr = screen_surface->pixels,
-           tptr = &ptr[screen_width * screen_height];
-           ptr < tptr; ptr = &ptr[8]) {
-               ptr[0] = 0x00000000;
-               ptr[1] = 0x00000000;
-               ptr[2] = 0x00000000;
-               ptr[3] = 0x00000000;
-               ptr[4] = 0x00000000;
-               ptr[5] = 0x00000000;
-               ptr[6] = 0x00000000;
-               ptr[7] = 0x00000000;
-       }
-}
-
-static void
-frame_draw(void)
-{
-
-       frame_clear();
-       /* SDL_FillRect(screen_surface, NULL, 0); */
-
-       surface_blit_angle(rship, nav_pos_x, nav_pos_y, cur_nav_angle, 0);
-       if (cloaked)
-               filledCircleRGBA(screen_surface, nav_pos_x, nav_pos_y, 25,
-                   0x00, 0x00, 0x00, 0x80);
-       if (shields) {
-               aacircleRGBA(screen_surface, nav_pos_x, nav_pos_y, 25,
-                   0xe0, 0xe0, 0x20, 0x60);
-               filledCircleRGBA(screen_surface, nav_pos_x, nav_pos_y, 25,
-                   0xf0, 0xf0, 0x30, 0x40);
-       }
-       aalineRGBA(screen_surface,
-           VECTOR_X(nav_pos_x, cur_nav_angle, 40),
-           VECTOR_Y(nav_pos_y, cur_nav_angle, 40),
-           VECTOR_X(nav_pos_x, cur_nav_angle, 60),
-           VECTOR_Y(nav_pos_y, cur_nav_angle, 60),
-           0xff, 0xff, 0xff, 0x80);
-
-       if (fired) {
-               int     i;
-
-               fired = 0;
-               for (i = 0; i < 255; i++) {
-                       pixelRGBA(screen_surface,
-                           VECTOR_X(nav_pos_x, joy_angle, i),
-                           VECTOR_Y(nav_pos_y, joy_angle, i),
-                           0xff, 0xff, 0x00, 0xff - i);
-               }
-       }
-
-       {
-               char    str[256];
-
-               (void) snprintf(str, 255,
-                   "Thrust: %02d/%02d (%02d), "
-                   "Angle: %03d (%03d), "
-                   "Position: (%03d,%03d), "
-                   "Shields: %3s, "
-                   "Cloak: %3s",
-                   cur_nav_thrust, max_thrust, nav_thrust,
-                   cur_nav_angle, nav_angle,
-                   nav_pos_x, nav_pos_y,
-                   (shields == 1 ? "On" : "Off"),
-                   (cloaked == 1 ? "On" : "Off"));
-               font_blit_string(font, 17, 17, str,
-                   0x00, 0x00, 0x00, 0xff);
-               font_blit_string(font, 16, 16, str,
-                   0xff, 0xff, 0xff, 0xff);
-       }
-
-       font_blit_string(font, 17, 741, fpsstr, 0x00, 0x00, 0x00, 0xff);
-       font_blit_string(font, 16, 740, fpsstr, 0xff, 0xff, 0xff, 0xff);
-
-       (void) SDL_Flip(screen_surface);
-       fpscnt++;
-}
-
-static SDL_Surface *
-bmp_load_key(void *data, size_t size)
-{
-       SDL_RWops       *rwo;
-       SDL_Surface     *s;
-       Uint32          c;
-       void            *ndata;
-       size_t          nsize;
-
-       decode(&ndata, &nsize, data, size);
-
-       if ((rwo = SDL_RWFromMem(ndata, nsize)) == NULL)
-               goto err;
-       if ((s = IMG_LoadBMP_RW(rwo)) == NULL)
-               goto err;
-       SDL_FreeRW(rwo);
-
-       c = SDL_MapRGB(s->format, 0, 0, 0);
-       if (SDL_SetColorKey(s, SDL_SRCCOLORKEY | SDL_RLEACCEL, c) == -1)
-               goto err;
-
-       return s;
-
-err:
-       (void) fprintf(stderr, "bmp_load_key() - %s\n", SDL_GetError());
-       exit(EXIT_FAILURE);
-}
-
-static int
-surface_blit_angle(SDL_Surface *s, int x, int y, double a, int clean)
-{
-       SDL_Surface     *t;
-       SDL_Rect        d;
-       int             r;
-
-       ASSERT(a > -1 && a < 360);
-
-       if (clean) {
-               int     cx, cy, c;
-
-               cx = s->w / 2 + 2;
-               cy = s->h / 2 + 2;
-               c = (cx >= cy ? cx : cy);
-               (void) boxRGBA(screen_surface, x - c, y - c,
-                   x + c, y + c, 0x00, 0x00, 0x00, 0xff);
-       }
-
-       if ((t = rotozoomSurface(s, -a, 1.0, 1)) != NULL) {
-               d = (SDL_Rect){x - (t->w / 2), y - (t->h / 2), 0, 0};
-               r = SDL_BlitSurface(t, NULL, screen_surface, &d);
-               SDL_FreeSurface(t);
-       } else
-               r = -1;
-
-       return r;
-}
-
-static Mix_Chunk *
-sample_load(void *data, size_t size)
-{
-       SDL_RWops       *rwo;
-       Mix_Chunk       *c;
-       void            *ndata;
-       size_t          nsize;
-
-       decode(&ndata, &nsize, data, size);
-
-       if ((rwo = SDL_RWFromMem(ndata, nsize)) == NULL)
-               goto err;
-
-       if ((c = Mix_LoadWAV_RW(rwo, 0)) == NULL)
-               goto err;
-
-       SDL_FreeRW(rwo);
-       return c;
-
-err:
-       (void) fprintf(stderr, "sample_load() - %s\n", SDL_GetError());
-       exit(EXIT_FAILURE);
-}
-
-static struct font *
-font_load(void *data, size_t size, int width, int height)
-{
-       struct font     *font;
-       void            *ndata;
-       size_t          nsize;
-
-       decode(&ndata, &nsize, data, size);
-
-       if ((font = malloc(sizeof(struct font))) == NULL)
-               goto err;
-
-       font->data = ndata;
-       font->w = width;
-       font->h = height;
-       font->size = nsize;
-       return font;
-
-err:
-       (void) fprintf(stderr, "font_load()\n");
-       exit(EXIT_FAILURE);
-}
-
-static void
-font_blit_string(struct font *font, int x, int y, const char *str,
-    uint8_t r, uint8_t g, uint8_t b, uint8_t a)
-{
-
-       (void) gfxPrimitivesSetFont(font->data, font->w, font->h);
-       (void) stringRGBA(screen_surface, x, y, str, r, g, b, a);
-}
-
-/* ARGSUSED */
-static Uint32
-fpscnt_callback(Uint32 interval, void *args)
-{
-
-       (void) sprintf(fpsstr, "%03d fps", fpscnt / 5);
-       fpscnt = 0;
-
-       return interval;
-}
-
-/* Initialize trigonometric tables */
-static void
-trig_init(void)
-{
-       int     i;
-       double  f;
-
-       for (i = 0; i < 360; i++) {
-               f = ((2 * M_PI) / 360) * (i - 90);
-               sin_table[i] = sin(f);
-               cos_table[i] = cos(f);
-       }
-}
diff --git a/tests/sdl-client/main.h b/tests/sdl-client/main.h
deleted file mode 100644 (file)
index 12b8cb2..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $Id: main.h,v 1.3 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Exported resources by the main program, mainly for thread modules.
- */
-
-
-
-#ifndef MAIN_H
-#define MAIN_H
-
-
-
-#include <SDL.h>
-
-#include <thread_msg.h>
-
-
-
-extern thread_port_t   main_port;
-
-
-
-#endif
diff --git a/tests/sdl-client/ogg/README b/tests/sdl-client/ogg/README
deleted file mode 100644 (file)
index 90d493c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-For how, place any ogg track that you like as 1.ogg under this directory.
-Eventually there shall be some of my own composed music, when I have time
-and care enough to add it.
-
-Matt
diff --git a/tests/sdl-client/packets.c b/tests/sdl-client/packets.c
deleted file mode 100644 (file)
index 0a46921..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/* $Id: packets.c,v 1.1 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * To validate a received packet, we'll make sure that it's larger than
- * sizeof(int), and that the first integer consists of a valid expected packet
- * type ID within range.  If so, we verify if packet length really corresponds
- * to the packet type, and then can interpret the packet information.
- * An actual network packet may contain a number of these packets.
- * We thus must be able to efficiently determine each packet's length.
- * Since we're using TCP, it should be enough.  However, on the server side
- * especially, proper sanity checking on input must be done to avoid crashing
- * the server because of unexpected data processing.
- */
-
-
-
-#include <stdlib.h>
-
-#include <mmstring.h>
-#include <mmarch.h>
-
-#include "packets.h"
-#include "client.h"
-#include "sendq.h"
-#include "conf.h"
-
-
-
-static int     cpacket_auth_handler(client_t *, uint16_t *);
-static int     cpacket_ping_handler(client_t *, uint16_t *);
-static int     cpacket_pong_handler(client_t *, uint16_t *);
-static int     cpacket_direction_handler(client_t *, uint16_t *);
-static int     cpacket_thrust_handler(client_t *, uint16_t *);
-static int     cpacket_torp_handler(client_t *, uint16_t *);
-static int     cpacket_quit_handler(client_t *, uint16_t *);
-
-
-
-static struct packet_index     cpacket_index[CPACKET_MAX] = {
-       {sizeof(struct cpacket_auth), cpacket_auth_handler},
-       {sizeof(struct cpacket_ping), cpacket_ping_handler},
-       {sizeof(struct cpacket_pong), cpacket_pong_handler},
-       {sizeof(struct cpacket_direction), cpacket_direction_handler},
-       {sizeof(struct cpacket_thrust), cpacket_thrust_handler},
-       {sizeof(struct cpacket_torp), cpacket_torp_handler},
-       {sizeof(struct cpacket_quit), cpacket_quit_handler}
-};
-
-
-
-void
-update(void)
-{
-       node_t          *nod, *next;
-       client_t        *c;
-       uint8_t         *data;
-       size_t          size, off;
-
-       for (nod = DLIST_TOP(&clients_list); nod != NULL; nod = next) {
-               next = DLIST_NEXT(nod);
-               c = (client_t *)nod;
-
-               if (c->todestroy || c->toclose)
-                       continue;
-
-               /* Reset ping request throttling flag */
-               c->askedping = 0;
-
-               /* First process incomming packets */
-               recvq_content(&c->recvq, &data, &size);
-               for (off = 0; off < size; ) {
-                       int16_t *id;
-
-                       /*
-                        * Verify packet type ID. It already has been
-                        * converted to host endian byte order, unlike other
-                        * packet fields.
-                        */
-                       id = (int16_t *)&data[off];
-                       *id = BYTEORDER_HOST16(*id);
-                       if (*id < 0 || *id > CPACKET_MAX) {
-                               client_destroy_mark(c);
-                               break;
-                       }
-
-                       /* There must be enough data for packet size */
-                       if (size - off < cpacket_index[*id].size) {
-                               /*
-                                * Kill authentucated client if other packets
-                                * than CPACKET_AUTH
-                                */
-                               if (!c->authenticated && *id != CPACKET_AUTH)
-                                       goto k;
-
-                               /*
-                                * XXX We'll need to also do special
-                                * processing for chat packets, since they'll
-                                * have arbitrary length.  They'll still need
-                                * to be 16-bit aligned, too.
-                                */
-
-                               /* Kill client on packet processing error */
-                               if (cpacket_index[*id].handler(c,
-                                   (uint16_t *)off) == -1)
-                                       goto k;
-                       } else
-                               goto k;
-
-                       /* Process next packet if any */
-                       off += cpacket_index[*id].size;
-                       continue;
-
-k:
-                       client_destroy_mark(c);
-                       break;
-               }
-
-               /*
-                * XXX I don't like having to run the clients list all over,
-                * to then run through all objects (including clients) to
-                * update them, and then yet again through all objects to send
-                * updates to all clients.
-                */
-
-               /* Run game frame on all objects */
-               DLIST_FOREACH(&clients_list, nod) {
-                       client_t        *c = (client_t *)nod;
-
-                       /*
-                       if (!c->authenticated)
-                               continue;
-                        */
-
-                       /*
-                        * First update direction and thrust.
-                        * XXX I could do a small function or macro to deal
-                        * with similar situations, i.e.
-                        * change_update(int goal, int *current, int steps);
-                        */
-                       if (c->object.direction < c->object.i_direction)
-                               c->object.direction++;
-                       else if (c->object.direction > c->object.i_direction)
-                               c->object.direction--;
-                       if (c->object.thrust < c->object.i_thrust)
-                               c->object.thrust++;
-                       else if (c->object.thrust > c->object.i_thrust)
-                               c->object.thrust--;
-
-                       /*
-                        * Translate object x/y position according to
-                        * trust/direction.  When reaching borders we simply
-                        * bounce for now.
-                        * (I need to review my trigonometry a bit again :)
-                        */
-                       /* XXX */
-                       c->object.x += 1 - (random() & 2);
-                       if (c->object.x < 0)
-                               c->object.x = 0;
-                       else if (c->object.x > WORLD_X_MAX - 1)
-                               c->object.x = WORLD_X_MAX - 1;
-                       c->object.y += 1 - (random() & 2);
-                       if (c->object.y < 0)
-                               c->object.y = 0;
-                       else if (c->object.y > WORLD_Y_MAX - 1)
-                               c->object.y = WORLD_Y_MAX - 1;
-               }
-
-               /* Send update frame information packets */
-               DLIST_FOREACH(&clients_list, nod) {
-                       client_t        *c = (client_t *)nod;
-                       node_t          *nod2;
-
-                       /*
-                       if (!c->authenticated)
-                               continue;
-                        */
-
-                       DLIST_FOREACH(&clients_list, nod2) {
-                               if (spacket_position_send(c,
-                                   &((client_t *)nod2)->object) == -1)
-                                       break;
-                       }
-                       (void) sendq_flush(&c->sendq, -1);
-               }
-       }
-}
-
-
-int
-spacket_auth_send(client_t *c)
-{
-       struct spacket_auth     p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_AUTH);
-       mm_memclr(p.string, 32);
-       mm_strncpy(p.string, SERVER_STRING, 31);
-       p.protocol_version = BYTEORDER_NETWORK16(SERVER_VERSION);
-       /* XXX */
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 0);
-}
-
-int
-spacket_pong_send(client_t *c)
-{
-       struct spacket_pong     p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_PONG);
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 0);
-}
-
-int
-spacket_position_send(client_t *c, object_t *o)
-{
-       struct spacket_position p;
-
-       p.packet_type = BYTEORDER_NETWORK16(SPACKET_POSITION);
-       p.object_id = p.object_type = BYTEORDER_NETWORK16(0);   /* XXX */
-       p.x = BYTEORDER_NETWORK16(o->x);
-       p.y = BYTEORDER_NETWORK16(o->y);
-       p.direction - BYTEORDER_NETWORK16(o->direction);
-
-       return client_write(c, (uint8_t *)&p, sizeof(p), 1);
-}
-
-
-/* Note that only the packet_type field is endian converted yet. */
-
-static int
-cpacket_auth_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_auth     *p = (struct cpacket_auth *)ptr;
-
-       p->protocol_version = BYTEORDER_HOST16(p->protocol_version);
-
-       if (c->authenticated || p->protocol_version < SERVER_VERSION)
-               return -1;
-
-       /*
-        * XXX For now.  Eventually also check user/password
-        * We could use APOP-like authentication where server sends random
-        * data as part of the authentication greeting/request, and expect
-        * client to append password to random data and send hashed result.
-        * We also should do user concurrency checking here.
-        */
-       c->authenticated = 1;
-
-       return 0;
-}
-
-/*
- * Note: Following function is never used, since pings are handled in the
- * kqueue main loop code.
- */
-/* ARGSUSED */
-static int
-cpacket_ping_handler(client_t *c, uint16_t *ptr)
-{
-       /* NOOP */
-
-       return 0;
-}
-
-static int
-cpacket_pong_handler(client_t *c, uint16_t *ptr)
-{
-/*     struct cpacket_pong     *p = (struct cpacket_pong *)ptr;*/
-
-       /* XXX */
-
-       return 0;
-}
-
-static int
-cpacket_direction_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_direction        *p = (struct cpacket_direction *)ptr;
-
-       p->direction = BYTEORDER_HOST16(p->direction);
-
-       /* Radians */
-       if (p->direction < 0 || p->direction > 1000)
-               return -1;
-
-       c->object.i_direction = p->direction;
-
-       return 0;
-}
-
-static int
-cpacket_thrust_handler(client_t *c, uint16_t *ptr)
-{
-       struct cpacket_thrust   *p = (struct cpacket_thrust *)ptr;
-
-       p->thrust = BYTEORDER_HOST16(p->thrust);
-
-       if (p->thrust < 0 || p->thrust > 20)
-               return -1;
-
-       c->object.i_thrust = p->thrust;
-
-       return 0;
-}
-
-static int
-cpacket_torp_handler(client_t *c, uint16_t *ptr)
-{
-/*     struct cpacket_torp     *p = (struct cpacket_torp *)ptr;*/
-
-       /* XXX */
-
-       return 0;
-}
-
-/* ARGSUSED */
-static int
-cpacket_quit_handler(client_t *c, uint16_t *ptr)
-{
-
-       return -1;
-}
diff --git a/tests/sdl-client/packets.h b/tests/sdl-client/packets.h
deleted file mode 100644 (file)
index 4db2425..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* $Id: packets.h,v 1.1 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * All packets must begin with an int16_t packet_type.  All fields of a packet
- * must either be [u]int8_t, [u]int16_t, [u]int32+t or [u]int64_t.  Moreover,
- * all fields will be passed in network/big endian byte order when sent over
- * the network.  We could have used a union, but this would have resulted in
- * larger, fixed sized packets wasting bandwidth.  Since a server to client
- * update will generally involve sending more than one such packet in a row,
- * it is important to minimize their size.
- * Note: If using 32-bit fields within a packet, make sure that they are
- * 32-bit aligned.
- */
-
-
-
-#ifndef _PACKETS_H_
-#define _PACKETS_H_
-
-
-
-#include <stdint.h>
-
-
-
-/*
- * For every server packet type we support, an index array will be used
- * with this structure to call the associated handler function, which will
- * perform sanity checking and process the packet, returning 0 on success or
- * -1 on error.  The size field will allow to perform sanity checking on
- * data size prior to calling the handler function, as well as to increase the
- * buffer pointer.
- */
-struct packet_index {
-       size_t  size;
-       int     (*handler)(uint16_t *);
-};
-
-
-
-/*
- * Server to client packets
- */
-
-enum spacket_types {
-       SPACKET_AUTH = 0,
-       SPACKET_PING,
-       SPACKET_PONG,
-       SPACKET_POSITION,
-       SPACKET_COLLISION,
-       SPACKET_MAX
-};
-
-/* Used to request client authentication and respond success/failure */
-struct spacket_auth {
-       int16_t packet_type;
-       int16_t protocol_version;
-       char    string[32];
-       /* XXX */
-} __attribute__((__packed__));
-
-/* And for server to test idle connections */
-struct spacket_ping {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* And clients to test latency */
-struct spacket_pong {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* Object position/direction update to client */
-struct spacket_position {
-       int16_t packet_type;
-       int16_t object_id, object_type;
-       int16_t x, y, direction;
-} __attribute__((__packed__));
-
-/* Collision/detonation update to client */
-struct spacket_collision {
-       int16_t packet_type;
-       int16_t collision_type;
-       int16_t object1_id, object2_id;
-} __attribute__((__packed__));
-
-
-
-/*
- * Client to server packets
- */
-
-enum cpacket_tyoes {
-       CPACKET_AUTH = 0,
-       CPACKET_PING,
-       CPACKET_PONG,
-       CPACKET_DIRECTION,
-       CPACKET_THRUST,
-       CPACKET_TORP,
-       CPACKET_QUIT,
-       CPACKET_MAX
-};
-
-/* Used to respond to server authentication request */
-struct cpacket_auth {
-       int16_t packet_type;
-       int16_t protocol_version;
-       char    string[32];
-       /* XXX */
-} __attribute__((__packed__));
-
-/* To ping server for latency mesurement */
-struct cpacket_ping {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* To respond to server ping requests */
-struct cpacket_pong {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-/* Angle/direction change request */
-struct cpacket_direction {
-       int16_t packet_type;
-       int16_t direction;
-} __attribute__((__packed__));
-
-/* Speed change request */
-struct cpacket_thrust {
-       int16_t packet_type;
-       int16_t thrust;
-} __attribute__((__packed__));
-
-/* Torpedo fire request */
-struct cpacket_torp {
-       int16_t packet_type;
-       int16_t direction;
-} __attribute__((__packed__));
-
-/* Game quit request */
-struct cpacket_quit {
-       int16_t packet_type;
-} __attribute__((__packed__));
-
-
-
-#endif
diff --git a/tests/sdl-client/pool.c b/tests/sdl-client/pool.c
deleted file mode 100644 (file)
index 23d7d25..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/* $Id: pool.c,v 1.3 2006/05/19 09:36:57 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2006, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <dlist.h>
-#include <pool.h>
-#include <debug.h>
-
-
-
-/* DEFINITIONS */
-
-#define BPAGE_SIZE     ((size_t)OALIGN_CEIL(sizeof(bpage_t), long))
-
-
-
-/* STATIC FUNCTION PROTOTYPES */
-
-static bpage_t *       pool_page_create(const char *, pool_t *);
-static bpage_t *       pool_page_destroy(bpage_t *);
-
-
-
-/* STATIC FUNCTIONS */
-
-/*
- * Creates a new page of objects, and calls the constructor function for each
- * object of the new page if needed.  Returns NULL on failure, or the new
- * bpage_t pointer on success.
- */
-static bpage_t *
-pool_page_create(const char *func, pool_t *pool)
-{
-       register size_t         nodesize = pool->nodesize;
-       register uint8_t        *ptr, *toptr;
-       register bpage_t        *page;
-       register list_t         *list;
-
-       if ((page = pool->malloc(pool->pagesize)) == NULL)
-               return NULL;
-
-       /* Initialize bpage_t */
-       page->magic = MAGIC_PAGE;
-       page->pool = pool;
-       DLIST_INIT(&page->objects);
-
-       /*
-        * Create all objects of that bpage_t, inserting them into it's list_t.
-        * If any object creation fails (it's optional construtor function can
-        * fail), destroy the page and return NULL.
-        */
-       if (pool->create != NULL) {
-               for (ptr = toptr = (uint8_t *)page, ptr += BPAGE_SIZE,
-                    toptr += pool->pagesize, list = &page->objects;
-                    ptr + nodesize < toptr; ptr += nodesize) {
-                       ((pnode_t *)ptr)->magic = 0;
-                       ((pnode_t *)ptr)->page = page;
-                       if (pool->create((pnode_t *)ptr) != 0)
-                               return pool_page_destroy(page);
-                       DLIST_APPEND(list, (node_t *)ptr);
-               }
-       } else {
-               for (ptr = toptr = (uint8_t *)page, ptr += BPAGE_SIZE,
-                    toptr += pool->pagesize, list = &page->objects;
-                    ptr + nodesize < toptr; ptr += nodesize) {
-                       ((pnode_t *)ptr)->magic = 0;
-                       ((pnode_t *)ptr)->page = page;
-                       DLIST_APPEND(list, (node_t *)ptr);
-               }
-       }
-
-       return page;
-}
-
-/*
- * Destroys a page previously created using pool_page_create(), calling the
- * destructor function for each object of the page if necessary.
- * Returns NULL.
- */
-static bpage_t *
-pool_page_destroy(bpage_t *page)
-{
-       register pnode_t        *pnode;
-       register void           (*destroy)(pnode_t *);
-
-       if ((destroy = (page->pool->destroy)) != NULL) {
-               /* We need to destroy all objects */
-               DLIST_FOREACH(&page->objects, pnode)
-                  destroy(pnode);
-       }
-
-       page->pool->free(page);
-
-       return NULL;
-}
-
-
-
-/* PUBLIC FUNCTIONS */
-
-/*
- * Initializes a memory pool for efficient management of fixed sized nodes.
- * Returns 0 on success or -1 on failure.
- */
-int
-pool_init(pool_t *pool, const char *label, void *(*mallocfunc)(size_t),
-    void (*freefunc)(void *), int (*create)(pnode_t *),
-    void (*destroy)(pnode_t *), size_t nodesize, uint32_t nodesperpage,
-    uint32_t minpages, uint32_t maxpages)
-{
-       int             ok = -1;
-       register size_t ns, ps;
-
-       ASSERT(!POOL_VALID(pool));
-       ASSERT(pool != NULL && mallocfunc != NULL && freefunc != NULL &&
-           ((create != NULL && destroy != NULL) ||
-            (void *)create == (void *)destroy) &&
-           nodesize != 0 && nodesperpage > 0);
-
-       ns = (size_t)OALIGN_CEIL(nodesize, long);
-       ps = (BPAGE_SIZE + ((nodesperpage + 1) * ns));
-
-       pool->magic = 0;
-       pool->label = label;
-       pool->malloc = mallocfunc;
-       pool->free = freefunc;
-       pool->create = create;
-       pool->destroy = destroy;
-       pool->nodesize = ns;
-       pool->minpages = minpages;
-       pool->maxpages = maxpages;
-       pool->nodesperpage = nodesperpage;
-       pool->pagesize = ps;
-       pool->avgtotal = pool->avgcnt = minpages;
-       DLIST_INIT(&pool->pages);
-       DLIST_INIT(&pool->fpages);
-       DLIST_INIT(&pool->epages);
-
-       /*
-        * Allocate minimum number of pages, if needed. We insert them into
-        * the empty pages list, but minpages will be honored as such to
-        * never free pages below it.
-        */
-       for (; minpages > 0; minpages--) {
-               register bpage_t        *p;
-
-               if ((p = pool_page_create("pool_init", pool)) == NULL)
-                       break;
-               DLIST_APPEND(&pool->epages, (node_t *)p);
-       }
-
-       /* Validate this pool */
-       pool->magic = MAGIC_POOL;
-
-       /*
-        * Have we failed to allocate any needed pages? If so, destroy pool
-        * and return -1.
-        */
-       if (minpages == 0)
-               ok = 0;
-       else if (minpages < pool->minpages)
-               (void) pool_destroy(pool);
-
-       return ok;
-}
-
-
-/*
- * Destroys a pool which previously has been created by pool_init(), and frees
- * any resources it uses (all the nodes it created become invalid).
- */
-void
-pool_destroy(pool_t *pool)
-{
-       register bpage_t        *p, *t;
-
-       ASSERT(POOL_VALID(pool));
-
-       /* Destroy all pages of all lists */
-       for (p = DLIST_TOP(&pool->pages); p != NULL; p = t) {
-               t = DLIST_NEXT(p);
-               (void) pool_page_destroy(p);
-       }
-       for (p = DLIST_TOP(&pool->fpages); p != NULL; p = t) {
-               t = DLIST_NEXT(p);
-               (void) pool_page_destroy(p);
-       }
-       for (p = DLIST_TOP(&pool->epages); p != NULL; p = t) {
-               t = DLIST_NEXT(p);
-               (void) pool_page_destroy(p);
-       }
-
-       /* Invalidate pool_t */
-       pool->magic = 0;
-}
-
-
-/*
- * Allows to very efficiently allocate a single node from the specified pool,
- * optionally initializing it's memory to zeros. Returns the newly allocated
- * node pointer on success, or NULL on error.
- */
-pnode_t *
-pool_alloc(pool_t *pool, int zero)
-{
-       pnode_t                 *pnode = NULL;
-       register bpage_t        *page;
-
-       ASSERT(POOL_VALID(pool));
-       ASSERT(!zero || pool->create == NULL);
-
-       /* Are there any partially used pages? */
-       if ((page = DLIST_TOP(&pool->pages)) == NULL) {
-               /*
-                * No, we thus attempt to move a page from our empty pages
-                * cache back into our usable pages list. The order of the
-                * usable page list becomes irrelevant at DLIST_SWAP() since
-                * it will be the only node.
-                */
-               if ((page = DLIST_TOP(&pool->epages)) == NULL) {
-                       /*
-                        * No more free pages in our cache neither.
-                        * If maxpages is set and not yet reached, we need
-                        * to create a new page.  If we can't, return NULL
-                        * for error.
-                        */
-                       if (pool->maxpages == 0 ||
-                           DLIST_NODES(&pool->fpages) < pool->maxpages) {
-                               if ((page = pool_page_create("pool_alloc",
-                                   pool)) == NULL)
-                                       return NULL;
-                               DLIST_APPEND(&pool->pages, (node_t *)page);
-                       } else
-                              return NULL;
-               } else
-                       DLIST_SWAP(&pool->pages, &pool->epages, (node_t *)page,
-                           0);
-       }
-
-       /*
-        * <page> now points to a page we know we can at least get a free
-        * object node from. Obtain one and unlink it.
-        */
-       pnode = DLIST_TOP(&page->objects);
-       DLIST_UNLINK(&page->objects, (node_t *)pnode);
-
-       /*
-        * Have we obtained the last available object from this page?
-        * If so, move the page to the full pages list. The order of the
-        * full pages list nodes is irrelevant, since we don't know which
-        * of those pages are more likely to be swapped to the usable
-        * pages list first, and we won't run through that list, except at
-        * pool_destroy().
-        */
-       if (DLIST_NODES(&page->objects) == 0)
-               DLIST_SWAP(&pool->fpages, &pool->pages, (node_t *)page, 0);
-
-       /*
-        * If requested, zero object. This is stupid if a constructor and
-        * destructor are used, but can be useful otherwise.
-        */
-       if (zero) {
-               page = pnode->page;
-               (void) memset(pnode, 0, pool->nodesize);
-               pnode->page = page;
-       }
-
-       /* Mark this node as a valid allocated object */
-       pnode->magic = MAGIC_PNODE;
-
-       return pnode;
-}
-
-
-/*
- * Efficiently frees the specified node back to the pool it was allocated from.
- * Returns NULL.  Uses heuristics keeping statistics to determine when to
- * actually shrink the memory blocks internally used by the pool, so that
- * frequently growing and shrinking pools will remain large for scalability.
- * This also makes a big difference when constructors and destructors are used
- * and need to execute a significant amount of code.
- */
-pnode_t *
-pool_free(pnode_t *pnode)
-{
-       register bpage_t        *page = pnode->page;
-       register pool_t         *pool = page->pool;
-       register uint32_t       count;
-
-       ASSERT(PNODE_VALID(pnode));
-
-       /* Invalidate object */
-       pnode->magic = 0;
-
-       /*
-        * Record how many nodes there currently are in our page's object
-        * list, to be used later on
-        */
-       count = DLIST_NODES(&page->objects);
-
-       /*
-        * Add node back to it's page's object list.  Insert it so that we
-        * favor reuse of recently used objects soon.
-        */
-       DLIST_INSERT(&page->objects, (node_t *)pnode);
-
-       /*
-        * Was this page full before we inserted our node?  If so, page is in
-        * full pages list.  Move it to the usable pages list.  Insert it to
-        * favor reuse of recently used pages soon (this page will soon return
-        * back to the full pages list).
-        */
-       if (count == 0)
-               DLIST_SWAP(&pool->pages, &pool->fpages, (node_t *)page, 1);
-       else {
-               /*
-                * Did we cause our node insertion to totally free back the
-                * page?  If so, the page is on the usable free list, but move
-                * it back to the empty pages list.  Insert it to favor reuse
-                * of recently used pages soon (this page will be the first to
-                * get used again when the usable pages list needs pages).
-                */
-               if (++count == pool->nodesperpage) {
-                       DLIST_SWAP(&pool->epages, &pool->pages, (node_t *)page,
-                           1);
-               }
-       }
-
-       if ((pool->minpages < pool->maxpages) ||
-           (pool->minpages == 0 && pool->maxpages == 0)) {
-               register int    exceeding;
-
-               /*
-                * This pool_t is allowed to shrink.  Maintain average pages
-                * usage to prevent destroying our pages in the empty pages
-                * list unless we should.
-                */
-               count = DLIST_NODES(&pool->pages) + DLIST_NODES(&pool->fpages);
-               pool->avgtotal += count;
-               pool->avgcnt++;
-
-               /*
-                * Using * 8 here means that pool_free() needs to at least be
-                * called to release as much objects as can fit into eight full
-                * pages in order to execute the following block.  But of
-                * course, this does not mean that eight pages will recently
-                * have been freed, since allocations probably also occured
-                * meanwhile.
-                */
-               if (pool->avgcnt > pool->nodesperpage * 8) {
-                       /*
-                        * Do statistics suggest that we should shrink the
-                        * pool?  If so, free pages from our empty pages
-                        * cache back to the system, destroying their objects
-                        * if necessary.  We'll make sure to at least leave a
-                        * one page hysterisis for better performance.
-                        */
-                       if ((exceeding = (count + DLIST_NODES(&pool->epages)
-                           - 1) - (pool->avgtotal / pool->avgcnt)) > 0) {
-                               register list_t *epages = &pool->epages;
-
-                               /*
-                                * Preferably free pages which haven't been
-                                * used recently.
-                                */
-                               for (; exceeding > 0 &&
-                                    (page = DLIST_BOTTOM(epages)) != NULL;
-                                    exceeding--) {
-                                       DLIST_UNLINK(epages, (node_t *)page);
-                                       (void) pool_page_destroy(page);
-                               }
-                       }
-                       /* Reset statistics */
-                       pool->avgcnt = 1;
-                       pool->avgtotal = count;
-               }
-       }
-
-       return NULL;
-}
diff --git a/tests/sdl-client/pool.h b/tests/sdl-client/pool.h
deleted file mode 100644 (file)
index f132c3c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* $Id: pool.h,v 1.1 2006/04/27 10:59:19 mmondor Exp $ */
-
-/*
- * Copyright (C) 2001-2006, Matthew Mondor
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Matthew Mondor.
- * 4. The name of Matthew Mondor may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- * 5. Redistribution of source code may not be released under the terms of
- *    any GNU Public License derivate.
- *
- * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-
-
-#ifndef MPOOL_H
-#define MPOOL_H
-
-
-
-#include <stdint.h>
-
-#include <dlist.h>
-
-
-
-/* Useful to o-align a value relative to v (sizes and pointers) */
-#define OALIGN_CEIL(v, o) \
-    ((((size_t)(v)) + (sizeof(o)) - 1) / (sizeof(o)) * (sizeof(o)))
-#define OALIGN_FLOOR(v, o)     ((size_t)(v) - (((size_t)(v) % sizeof(o))))
-
-/* Useful to byte align a value with supplied size */
-#define BALIGN_CEIL(v, s)      ((((size_t)(v)) + (s) - 1) / (s) * (s))
-#define BALIGN_FLOOR(v, s)     ((size_t)(v) - (((size_t)(v) % (s))))
-
-
-
-typedef struct pnode   pnode_t;
-typedef struct bpage   bpage_t;
-typedef struct pool    pool_t;
-
-
-
-#define MAGIC_POOL     0x504f4f4c      /* POOL */
-#define MAGIC_PAGE     0x50414745      /* PAGE */
-#define MAGIC_PNODE    0x504e4f44      /* PNOD */
-
-#define POOL_VALID(p)  ((p) != NULL && (p)->magic == MAGIC_POOL)
-#define PNODE_VALID(p) ((p) != NULL && (p)->magic == MAGIC_PNODE && \
-       (p)->page != NULL && (p)->page->magic == MAGIC_PAGE && \
-       (p)->page->pool != NULL && (p)->page->pool->magic == MAGIC_POOL)
-
-
-
-/* Header structure of internally allocated/prepared page/blocks */
-struct bpage {
-    node_t             node;
-    uint32_t           magic;
-    pool_t             *pool;
-    list_t             objects;
-};
-
-/* Header structure of individual pool objects */
-struct pnode {
-    node_t             node;
-    uint32_t           magic;
-    bpage_t            *page;
-};
-
-/* Pool control structure */
-struct pool {
-    pnode_t            node;   /* Hey, we never know, a pool_t of pool_t */
-    uint32_t           magic;
-    const char         *label;
-    void               *(*malloc)(size_t);
-    void               (*free)(void *);
-    int                        (*create)(pnode_t *);
-    void               (*destroy)(pnode_t *);
-    size_t             nodesize, pagesize;
-    uint32_t           minpages, maxpages, nodesperpage;
-    uint32_t           avgtotal, avgcnt;
-    /* Usable pages, totally full/busy pages, totally empty/free pages */
-    list_t             pages, fpages, epages;
-};
-
-
-
-/* Public API prototypes */
-extern int             pool_init(pool_t *, const char *, void *(*)(size_t),
-                           void (*)(void *), int (*)(pnode_t *),
-                           void (*)(pnode_t *), size_t,
-                           uint32_t, uint32_t, uint32_t);
-extern void            pool_destroy(pool_t *);
-extern pnode_t *       pool_alloc(pool_t *, int);
-extern pnode_t *       pool_free(pnode_t *);
-
-
-
-#endif
diff --git a/tests/sdl-client/rawobjs.h b/tests/sdl-client/rawobjs.h
deleted file mode 100644 (file)
index 89d59bc..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $Id: rawobjs.h,v 1.4 2006/05/10 00:48:40 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/* XXX This file should probably be auto-generated */
-
-
-
-#ifndef RAWOBJS_H
-#define RAWOBJS_H
-
-
-
-/*
- * On win32, binary objects must be referenced without the underscore prefix.
- * Let's then define a few aliases.
- */
-#ifdef WIN32
-
-#define _binary_bmp_FedCA_bmp_enc_size binary_bmp_FedCA_bmp_enc_size
-#define _binary_bmp_FedCA_bmp_enc_start        binary_bmp_FedCA_bmp_enc_start
-#define _binary_bmp_RomDD_bmp_enc_size binary_bmp_RomDD_bmp_enc_size
-#define _binary_bmp_RomDD_bmp_enc_start        binary_bmp_RomDD_bmp_enc_start
-
-#define _binary_wav_nt_cloaked_wav_enc_size binary_wav_nt_cloaked_wav_enc_size  
-#define _binary_wav_nt_cloaked_wav_enc_start binary_wav_nt_cloaked_wav_enc_start
-#define _binary_wav_nt_explosion_other_wav_enc_size binary_wav_nt_explosion_other_wav_enc_size
-#define _binary_wav_nt_explosion_other_wav_enc_start binary_wav_nt_explosion_other_wav_enc_start
-#define _binary_wav_nt_fire_torp_other_wav_enc_size binary_wav_nt_fire_torp_other_wav_enc_size
-#define _binary_wav_nt_fire_torp_other_wav_enc_start binary_wav_nt_fire_torp_other_wav_enc_start
-#define _binary_wav_nt_plasma_hit_wav_enc_size binary_wav_nt_plasma_hit_wav_enc_size
-#define _binary_wav_nt_plasma_hit_wav_enc_start binary_wav_nt_plasma_hit_wav_enc_start
-#define _binary_wav_nt_shield_down_wav_enc_size binary_wav_nt_shield_down_wav_enc_size
-#define _binary_wav_nt_shield_down_wav_enc_start binary_wav_nt_shield_down_wav_enc_start
-#define _binary_wav_nt_shield_up_wav_enc_size binary_wav_nt_shield_up_wav_enc_size
-#define _binary_wav_nt_shield_up_wav_enc_start binary_wav_nt_shield_up_wav_enc_start
-#define _binary_wav_nt_uncloak_wav_enc_size binary_wav_nt_uncloak_wav_enc_size
-#define _binary_wav_nt_uncloak_wav_enc_start binary_wav_nt_uncloak_wav_enc_start
-
-#define _binary_fnt_7x13_fnt_enc_start binary_fnt_7x13_fnt_enc_start
-#define _binary_fnt_7x13_fnt_enc_size  binary_fnt_7x13_fnt_enc_size
-
-#endif
-
-
-
-/*
- * And export symbols to other modules
- */
-
-extern void    *_binary_bmp_FedCA_bmp_enc_size;
-extern void    *_binary_bmp_FedCA_bmp_enc_start;
-extern void    *_binary_bmp_RomDD_bmp_enc_size;
-extern void    *_binary_bmp_RomDD_bmp_enc_start;
-
-extern void    *_binary_wav_nt_cloaked_wav_enc_size;
-extern void    *_binary_wav_nt_cloaked_wav_enc_start;
-extern void    *_binary_wav_nt_explosion_other_wav_enc_size;
-extern void    *_binary_wav_nt_explosion_other_wav_enc_start;
-extern void    *_binary_wav_nt_fire_torp_other_wav_enc_size;
-extern void    *_binary_wav_nt_fire_torp_other_wav_enc_start;
-extern void    *_binary_wav_nt_plasma_hit_wav_enc_size;
-extern void    *_binary_wav_nt_plasma_hit_wav_enc_start;
-extern void    *_binary_wav_nt_shield_down_wav_enc_size;
-extern void    *_binary_wav_nt_shield_down_wav_enc_start;
-extern void    *_binary_wav_nt_shield_up_wav_enc_size;
-extern void    *_binary_wav_nt_shield_up_wav_enc_start;
-extern void    *_binary_wav_nt_uncloak_wav_enc_size;
-extern void    *_binary_wav_nt_uncloak_wav_enc_start;
-
-extern void    *_binary_fnt_7x13_fnt_enc_start;
-extern void    *_binary_fnt_7x13_fnt_enc_size;
-
-
-
-#endif
diff --git a/tests/sdl-client/screen.c b/tests/sdl-client/screen.c
deleted file mode 100644 (file)
index 4cf25f2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $Id: screen.c,v 1.11 2006/05/08 21:05:17 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Display related initialization.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <SDL.h>
-
-#include <conf.h>
-#include <screen.h>
-
-
-
-#define                SCREEN_WIDTH    1024
-#define                SCREEN_HEIGHT   768
-
-
-
-SDL_Surface    *screen_surface;
-int            screen_width, screen_height;
-SDL_Joystick   *gamepad;
-
-
-
-void
-screen_init(void)
-{
-
-       if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
-               (void) fprintf(stderr, "main() - SDL_Init() - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if ((screen_surface = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32,
-           SDL_DOUBLEBUF | SDL_FULLSCREEN)) == NULL) {
-               (void) fprintf(stderr, "main() - SDL_SetVideoMode() - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       if (SDL_NumJoysticks > 0)
-               gamepad = SDL_JoystickOpen(0);
-
-       screen_width = SCREEN_WIDTH;
-       screen_height = SCREEN_HEIGHT;
-
-       (void) atexit(screen_destroy);
-}
-
-void
-screen_destroy(void)
-{
-
-       SDL_Quit();
-}
diff --git a/tests/sdl-client/screen.h b/tests/sdl-client/screen.h
deleted file mode 100644 (file)
index d98322f..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* $Id: screen.h,v 1.3 2006/05/08 08:17:00 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Screen related initialization.
- */
-
-
-
-#ifndef SCREEN_H
-#define SCREEN_H
-
-
-
-#include <SDL.h>
-
-
-
-extern SDL_Surface     *screen_surface;
-extern int             screen_width, screen_height;
-extern SDL_Joystick    *gamepad;
-
-
-
-void                   screen_init(void);
-void                   screen_destroy(void);
-
-
-
-#endif
diff --git a/tests/sdl-client/tests/draw.c b/tests/sdl-client/tests/draw.c
deleted file mode 100644 (file)
index da2c393..0000000
+++ /dev/null
@@ -1,948 +0,0 @@
-/* $Id: draw.c,v 1.1 2006/05/03 14:20:47 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * XXX TODO XXX
- * - Fix most all code using multiplication to locate x,y pixel positions into
- *   the display to use the screen_lines array for optimization.
- *   This however could cause a problem for SDL surfaces other than the screen
- *   which are involved. A possibility to fix this would be to wrap the
- *   SDL_Surface into a custom structure, which could also hold the optimized
- *   line position array for each...
- * - Implement a diff function, to fill a surface with the difference between
- *   two other surfaces... This might be good for some type of effects and
- *   animations. Hmm there possibly would be a problem with the 0 transparent
- *   color though... Consider following situation:
- *   - Diff detects new 0 color pixels in second image, how would we effect
- *     transformation of first image to second one, since we can't blit zero
- *     color images? If we did blit zero color, how would we detect what
- *     pixels consist in the difference? Perhaps that we would need a special
- *     diff format rather than just blitting differences into a zero color
- *     surface. Diff format could be very similar to runlength-style encoding
- *     format, if not the same, perhaps. I would only need to add section
- *     support, other than just compression... I.E. section starting at x,y,
- *     of total length l, followed by runlength compressed section...
- *   Such diffs might also be nice to send over the network when images change
- *   or such...
- * - Implement simple runlength compression and decompression support, with
- *   possibly load/save image support.
- * - Maybe implement simple animation format based on above diff and runlength
- *   support. It would be enough to implement small animated sets with limited
- *   motion.
- * - Implement ellipse and ellipse arc support
- * - Splines support would be great but I would need to read about it.
- *   If really required, SDL_gfx might be worth using.
- * - Once all required primitives have been implemented, allow support for
- *   parallel postscript commands output, so that it would be possible to
- *   print results. This would allow to have consistent on-screen and printer
- *   results (this is not game related, it could be used for applications).
- * * Postscript has all of the above. It actually would be nice if I could
- *   have my application draw postscript in real time while internally keeping
- *   the necessary information in memory of the screen state to be able to
- *   also print to a postscript printer. It seems that ghostscript has a
- *   graphics library. Can it be used by a third party application easily?
- *   Also, if I used postscript, how would I allow bitmap images to be
- *   supported? Especially as the relative scaling of everything would have
- *   to be respected?
- *   - It also would be possible to simply use X11R6. However, this would
- *     limit client applications to run on unix systems in most cases.
- *     Moreover, I probably would still require some kind of hack to
- *     internally keep track of postscript equivalents for printing, or the
- *     contrary, to process using postscript and draw using X11, etc...
- *     I of course still would need to provide my own toolkit.
- *   - The main problem I would have with both above techniques is dealing
- *     with fonts. Obviously, fonts would need to be vectorial, and in a way
- *     which is useful for postscript output. I would need to have an onscreen
- *     WYSIWYG renderer for the same type of fonts. X11 can supposedly output
- *     GS fonts to screen, using the X Font Server (XFS)... But this requires
- *     clients to have a special configuration, once more.
- *     NOTE: This is fixed, SDL_ttf can be used.
- *   - It would be possible to use bitmap fonts, as long as they are of the
- *     right size to be equivalent to the postscript output, and that the
- *     screen has proper visual to represent the page... If we support
- *     proportional fonts, some new code would need to be added. Moreover, we
- *     probably would not want the proportional fonts to be used where the
- *     user types text, to ease the editor's tasks... We would need to at
- *     least support fixed/courrier, times and helvetica. We would need a font
- *     format which can specify the size of each character of proportional
- *     fonts. Maybe an aditionnal data file along with the bitmap file...
- */
-
-
-
-/* HEADERFILES */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <SDL.h>
-
-#include <draw.h>
-#include <conf.h>
-#include <screen.h>
-
-
-
-/* DEFINITIONS */
-
-#ifdef ANTIALIASING    /* conf.h */
-#define DRAW_PIXEL     draw_pixel_antialias
-#else
-#define DRAW_PIXEL     draw_pixel
-#endif
-
-
-
-/* STATIC FUNCTIONS PROTOTYPES */
-
-
-
-/* GLOBALS */
-
-static draw_point_t    *stack_start, *stack_pos, pen;
-static double          sin_table[1000], cos_table[1000];
-static uint32_t                **screen_lines;
-
-
-
-/* PRIVATE FUNCTIONS */
-
-
-
-/* PUBLIC FUNCTIONS */
-
-int
-draw_init(void)
-{
-
-       /* Allocate memory for draw_fill_*() stack */
-       if ((stack_start = malloc(sizeof(draw_point_t) *
-           (screen_width * screen_height) * 4)) == NULL)
-               return -1;
-
-       /*
-        * Allocate and initialize fast screen display line index lookup table,
-        * which can be used by pixel drawing routines without the need for
-        * multiplications.
-        */
-       {
-               uint32_t        *lptr;
-               int             i;
-
-               if ((screen_lines = malloc(sizeof(uint32_t *) *
-                   screen_height)) == NULL)
-                       return -1;
-
-               for (lptr = (uint32_t *)(screen_surface->pixels), i = 0;
-                    i < screen_height; i++, lptr += screen_width)
-                       screen_lines[i] = lptr;
-       }
-
-       /*
-        * Initialize our sin/cos trigonometric functions arrays for
-        * performance when mesuring rotations in radians.
-        * XXX We should add pixel ratio modifyer too here.
-        */
-       {
-               int     i;
-               double  f;
-
-               for (i = 0; i < 1000; i++) {
-                       f = ((2 * M_PI) / 1000) * (i - 250);
-                       sin_table[i] = sin(f);
-                       cos_table[i] = cos(f);
-               }
-       }
-
-       return 0;
-}
-
-/* The following functions require that screen_surface be locked. */
-
-/* Draws a vertical line at specified position and of specified height */
-inline void
-draw_vline(draw_point_t *p, int height, uint32_t col)
-{
-       register uint32_t       *ptr;
-       register int            i;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x >= screen_width ||
-           p->y < 0 || p->y + height > screen_height));
-
-       /* XXX Should use lines array */
-       for (ptr = &((uint32_t *)screen_surface->pixels)[
-           (p->y * screen_width) + p->x], i = height; i > 0;
-           i--, ptr = &ptr[screen_width])
-               *ptr = col;
-}
-
-/* Draws an horizontal line at specified position and of specified width */
-inline void
-draw_hline(draw_point_t *p, int width, uint32_t col)
-{
-       register uint32_t       *ptr, *tptr;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x + width > screen_width ||
-           p->y < 0 || p->y >= screen_height));
-
-       /* XXX Should use lines array */
-       for (ptr = &((uint32_t *)screen_surface->pixels)[
-           (p->y * screen_width + p->x)], tptr = &ptr[width]; ptr < tptr; )
-               *ptr++ = col;
-}
-
-/*
- * Draws a rectangle of specified colors. Two colors can be specified for a
- * special 3d-like effect (although both can be the same if wanted).
- */
-inline void
-draw_rect(draw_rect_t *r, uint32_t hicol, uint32_t locol)
-{
-       draw_point_t    p;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       p.x = r->x;
-       p.y = r->y;
-       draw_hline(&p, r->w, hicol);
-       p.y++;
-       draw_vline(&p, r->h - 1, hicol);
-       p.x = r->x + r->w - 1;
-       p.y--;
-       draw_vline(&p, r->h, locol);
-       p.x = r->x + 1;
-       p.y = r->y + r->h - 1;
-       draw_hline(&p, r->w - 1, locol);
-}
-
-/*
- * Draws rectangular box at (x,y) to (x+w-1,y+h-1), using lcol for the 3d
- * border light color, dcol for 3d border dark color, filled with fcol (or 0
- * for transparent interior) and of specified 3d depth.
- */
-void
-draw_rect_3d(draw_rect_t *r, uint32_t hicol, uint32_t locol, uint32_t fillcol,
-    int depth)
-{
-       draw_rect_t     rect;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       if (fillcol != 0) {
-               rect.x = r->x + 1;
-               rect.y = r->y + 1;
-               rect.w = r->w - 2;
-               rect.h = r->h - 2;
-               draw_rect_fill(&rect, fillcol);
-       }
-       rect = *r;
-       for (; depth > 0; depth--, rect.x += 1, rect.y += 1,
-            rect.w -= 2, rect.h -= 2)
-               draw_rect(&rect, hicol, locol);
-}
-
-/* Allows to fill specified rectangle with specified color */
-inline void
-draw_rect_fill(draw_rect_t *r, uint32_t col)
-{
-       register uint32_t       *ptr, *tptr = NULL, *lptr;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       if (r->w == screen_width) {
-               /*
-                * Even better optimization, setting an entire single block of
-                * multiple lines together.
-                * XXX Should use lines array
-                */
-               for (ptr = &((uint32_t *)screen_surface->pixels)[
-                   (r->y * screen_width) + r->x],
-                   tptr = &ptr[screen_width * r->h];
-                   ptr < tptr; )
-                       *ptr++ = col;
-       } else {
-               /* Use line-based optimizations */
-               /* XXX Should use lines array */
-               for (ptr = &((uint32_t *)screen_surface->pixels)[
-                   (r->y * screen_width) + r->x],
-                   tptr = &((uint32_t *)screen_surface->pixels)[
-                   ((r->y + r->h - 1) * screen_width) + (r->x + r->w)];
-                   ptr < tptr; ptr = &ptr[screen_width - r->w]) {
-                       for (lptr = &ptr[r->w]; ptr < lptr; )
-                               *ptr++ = col;
-               }
-       }
-}
-
-/*
- * Similar to draw_rect_fill(), but causes pixels to be XORed against m,
- * to toggle their bits. This is reversable by another call to this function
- * on the same area again. This can be useful for the implementation of a
- * block cursor. However, because of the disposition of the current 256 color
- * palette, the effect might not be what is expected (some colors will render
- * too bright or too dark to be considered an inversing effect).
- */
-void
-draw_rect_fill_xor(draw_rect_t *r, uint32_t mask)
-{
-       register uint32_t       *ptr, *toptr, *lptr;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       /* XXX Should use lines array */
-       for (ptr = &((uint32_t *)screen_surface->pixels)[
-           (r->y * screen_width) + r->x],
-           toptr = &((uint32_t *)screen_surface->pixels)[
-           ((r->y + r->h - 1) * screen_width) + (r->x + r->w)];
-           ptr < toptr; ptr = &ptr[screen_width - r->w]) {
-               for (lptr = &ptr[r->w]; ptr < lptr; )
-                       *ptr++ ^= mask;
-       }
-}
-
-/*
- * Similar to draw_rect_fill(), but causes pixels which are not of the bgcol
- * to be reversed to the bgcol. Other pixels, which already were of bgcol are
- * set to col. This function is useful for the implementation of a block
- * cursor.
- */
-void
-draw_rect_fill_inverse(draw_rect_t *r, uint32_t col, uint32_t bgcol)
-{
-       register uint32_t       *ptr, *toptr, *lptr;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       /* XXX Should use lines array */
-       for (ptr = &((uint32_t *)screen_surface->pixels)[
-           (r->y * screen_width) + r->x],
-           toptr = &((uint32_t *)screen_surface->pixels)[
-           ((r->y + r->h - 1) * screen_width) + (r->x + r->w)];
-           ptr < toptr; ptr = &ptr[screen_width - r->w]) {
-               for (lptr = &ptr[r->w]; ptr < lptr; ptr++)
-                       *ptr = (*ptr == bgcol ? col : bgcol);
-       }
-}
-
-/*
- * Very similar to draw_rect_fill(), but causes empty/transparent pixels to be
- * left at 50%. Can be used to simulate transparency without the need for
- * alpha values. Especially useful with restricted palettes, or simply to
- * create an effect.
- */
-void
-draw_rect_fill_transparent(draw_rect_t *r, uint32_t col)
-{
-       register uint32_t       *ptr, *toptr, *lptr;
-       int                     even;
-
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > screen_width ||
-           r->y < 0 || r->y + r->h > screen_height));
-
-       /* XXX Should use lines array */
-       for (ptr = &((uint32_t *)screen_surface->pixels)[
-           (r->y * screen_width) + r->x],
-           toptr = &((uint32_t *)screen_surface->pixels)[
-           ((r->y + r->h - 1) * screen_width) + (r->x + r->w)], even = 0;
-           ptr < toptr;
-           ptr = &ptr[screen_width - r->w], even = (even == 0 ? 1 : 0)) {
-               ptr += even;
-               for (lptr = &ptr[r->w]; ptr < lptr; ptr += 2)
-                       *ptr = col;
-               ptr -= even;
-       }
-}
-
-/*
- * Similar to SDL_BlitSurface(), but less efficient, it allows to blit the
- * specified image in one color. All non-zero pixels are copied, while others
- * are output as fg. In the case where bg is non-zero, zero pixels output bg.
- * The screen surface should be locked when calling this function.
- */
-void
-draw_surface_color(SDL_Surface *surface, draw_rect_t *r, draw_point_t *p,
-    uint32_t fg, uint32_t bg)
-{
-       register uint32_t       *dstptr, *tdstptr, *srcptr, *tptr;
-
-       assert(surface != NULL);
-       assert(r != NULL);
-       assert(p != NULL);
-       assert(!(r->x < 0 || r->x + r->w > surface->w ||
-           r->y < 0 || r->y + r->h > surface->h));
-       assert(!(p->x < 0 || p->x + r->w > surface->w));
-
-       /*
-        * For performance we want to avoid having to include the bg color
-        * check every loop iteration. We prefer to have two loops instead.
-        * Moreover, we optimize the loop as such to avoid multiplications
-        * and divisions, using a line-based algorithm with additions only.
-        */
-       if (bg == 0) {
-               /* XXX Should use lines array */
-               for (dstptr = &((uint32_t *)screen_surface->pixels)[
-                   (p->y * screen_width) + p->x],
-                   tdstptr = &((uint32_t *)screen_surface->pixels)[
-                   ((p->y + r->h - 1) * screen_width) + (p->x + r->w)],
-                   srcptr = &((uint32_t *)surface->pixels)[
-                   (r->y * surface->w) + r->x];
-                   dstptr < tdstptr;
-                   dstptr = &dstptr[screen_width - r->w],
-                   srcptr = &srcptr[surface->w - r->w]) {
-                       for (tptr = &dstptr[r->w]; dstptr < tptr;
-                           dstptr++, srcptr++) {
-                               if ((*srcptr & 0xff000000) != 0)
-                                       *dstptr = fg;
-                       }
-               }
-       } else {
-               /* XXX Should use lines array */
-               for (dstptr = &((uint32_t *)screen_surface->pixels)[
-                   (p->y * screen_width) + p->x],
-                   tdstptr = &((uint32_t *)screen_surface->pixels)[
-                   ((p->y + r->h - 1) * screen_width) + (p->x + r->w)],
-                   srcptr = &((uint32_t *)surface->pixels)[
-                   (r->y * surface->w) + r->x];
-                   dstptr < tdstptr;
-                   dstptr = &dstptr[screen_width - r->w],
-                   srcptr = &srcptr[surface->w - r->w]) {
-                       for (tptr = &dstptr[r->w]; dstptr < tptr; )
-                               *dstptr++ = ((*srcptr++ & 0xff000000) == 0 ?
-                                   bg : fg);
-               }
-       }
-}
-
-void
-draw_surface_color_antialias(SDL_Surface *surface, draw_rect_t *r,
-    draw_point_t *p, uint32_t fg, uint32_t bg)
-{
-       register uint32_t       *srcptr, *tsrcptr, *tptr;
-       register int            x, y;
-
-       assert(surface != NULL);
-       assert(r != NULL);
-       assert(p != NULL);
-       assert(!(r->x < 0 || r->x + r->w > surface->w ||
-           r->y < 0 || r->y + r->h > surface->h));
-       assert(!(p->x < 0 || p->x + r->w > screen_width ||
-           p->y < 0 || p->y + r->h > screen_height));
-
-       /* XXX Should use lines array */
-       for (tsrcptr = &((uint32_t *)surface->pixels)[
-           ((r->y + r->h - 1) * surface->w) + (r->x + r->w)],
-           srcptr = &((uint32_t *)surface->pixels)[
-           (r->y * surface->w) + r->x],
-           y = p->y;
-           srcptr < tsrcptr;
-           srcptr = &srcptr[surface->w - r->w], y++) {
-               for (x = p->x, tptr = &srcptr[r->w]; srcptr < tptr;
-                   srcptr++, x++) {
-                       if (bg == 0) {
-                               if ((*srcptr & 0xff000000) != 0)
-                                       draw_pixel_antialias(x, y, fg);
-                       } else
-                               draw_pixel_antialias(x, y,
-                                   ((*srcptr & 0xff000000) == 0 ? bg : fg));
-               }
-       }
-}
-
-/*
- * Similar to SDL_BlitSurface(), but less efficient, it allows to blit a
- * perfect copy of a surface area to another surface area. This is most useful
- * when colors have been setup as transparent and that an opaque identical
- * copy is wanted.
- */
-void
-draw_surface_copy(SDL_Surface *dstsurface, draw_point_t *p,
-    SDL_Surface *srcsurface, draw_rect_t *r)
-{
-       uint32_t        *dstptr, *tdstptr, *srcptr, *tptr;
-
-       assert(dstsurface != NULL);
-       assert(p != NULL);
-       assert(srcsurface != NULL);
-       assert(r != NULL);
-       assert(!(r->x < 0 || r->x + r->w > srcsurface->w ||
-           r->y < 0 || r->y + r->h > srcsurface->h));
-       assert(!(p->x < 0 || p->x + r->w > dstsurface->w ||
-           p->y < 0 || p->y + r->h > dstsurface->h));
-
-       /* XXX Should use lines array */
-       for (dstptr = &((uint32_t *)dstsurface->pixels)[
-           (p->y * dstsurface->w) + p->x],
-           tdstptr = &((uint32_t *)dstsurface->pixels)[
-           ((p->y + r->h - 1) * dstsurface->w) + (p->x + r->w)],
-           srcptr = &((uint32_t *)srcsurface->pixels)[
-           (r->y * srcsurface->w) + r->x];
-           dstptr < tdstptr;
-           dstptr = &dstptr[dstsurface->w - r->w],
-           srcptr = &srcptr[srcsurface->w - r->w]) {
-               for (tptr = &dstptr[r->w]; dstptr < tptr; )
-                       *dstptr++ = *srcptr++;
-       }
-}
-
-/*
- * Blits a single pixel of specified color to screen at specified position.
- * Note that this function does not consider color 0 to be transparent.
- * This function, by exception, does not require the use of a draw_point_t.
- * This allows to use register based optimizations in functions calling us
- * (They do not need to keep counters in a memory structure when looping).
- */
-inline void
-draw_pixel(int x, int y, uint32_t col)
-{
-
-       /*
-        * Instead of using this alternative, which requires multiplication:
-        * ((uint32_t *)screen_surface->pixels)[(y * screen_width) + x] = col;
-        * Use the advantage of our screen_lines array for indexing
-        * optimization.
-        */
-       screen_lines[y][x] = col;
-}
-
-inline void
-draw_pixel_transparent(int x, int y, uint32_t col, int alpha)
-{
-       uint32_t        ccol;
-
-       /* This condition can happen because we are called for antialiasing */
-       if (x >= screen_width || x < 0 || y >= screen_height || y < 0)
-               return;
-
-       alpha &= 0xff;
-
-       /* First optimize possible cases */
-       if (alpha == 0x00)
-               return;
-       if (alpha == 0xff) {
-               draw_pixel(x, y, col);
-               return;
-       }
-
-       /* Transparently blit pixel if necessary */
-       if ((ccol = draw_getpixel2(x, y)) != col) {
-               int     r, g, b, nr, ng, nb;
-
-               /*
-                * Decompose into r, g, b levels, first current screen pixel
-                * color
-                */
-               r = ((ccol & 0x00ff0000) >> 16);
-               g = ((ccol & 0x0000ff00) >> 8);
-               b = (ccol & 0x000000ff);
-               /* Then supplied color */
-               nr = ((col & 0x00ff0000) >> 16);
-               ng = ((col & 0x0000ff00) >> 8);
-               nb = (col & 0x000000ff);
-
-               /*
-                * Apply opacity modification on supplied color according to
-                * alpha
-                */
-               nr = nr * alpha / 0xff;
-               ng = ng * alpha / 0xff;
-               nb = nb * alpha / 0xff;
-
-               /*
-                * XXX bug here! Works fine when blitting lighter colors on
-                * darker ones, but not for dark colors over brighter
-                * background.  I probably need something as simple as reverse
-                * proportional function or such...
-                */
-               /* Mix supplied color with pixel color */
-               if ((r = (r + nr) / 2) > 0xff)
-                       r = 0xff;
-               if ((g = (g + ng) / 2) > 0xff)
-                       g = 0xff;
-               if ((b = (b + nb) / 2) > 0xff)
-                       b = 0xff;
-
-               /* Recompose into a 32-bit color */
-               ccol = (((r << 16) & 0x00ff0000) | ((g << 8) & 0x0000ff00) |
-                   (b & 0x000000ff));
-
-               /* Finally blit resulting pixel back to screen */
-               draw_pixel(x, y, ccol);
-       }
-}
-
-/*
- * XXX Test.
- */
-inline void
-draw_pixel_antialias(int x, int y, uint32_t col)
-{
-#define AA_T   0xd0    /*0x60*/
-
-       assert(!(x >= screen_width || x < 0 || y >= screen_height || y < 0));
-
-       draw_pixel(x, y, col);
-       draw_pixel_transparent(x, y - 1, col, AA_T);
-       draw_pixel_transparent(x + 1, y, col, AA_T);
-       draw_pixel_transparent(x, y + 1, col, AA_T);
-       draw_pixel_transparent(x - 1, y, col, AA_T);
-
-#undef AA_T
-}
-
-/* Returns the color of pixel at specified location on screen. */
-inline uint32_t
-draw_getpixel(draw_point_t *p)
-{
-
-       assert(p != NULL);
-
-       return screen_lines[p->y][p->x];
-}
-
-inline uint32_t
-draw_getpixel2(int x, int y)
-{
-
-       return screen_lines[y][x];
-}
-
-/*
- * Blits a line on screen of specified color (x,y)->(x2,y2). Note that color 0
- * is not considered transparent. Probably does not use the best algorithm,
- * but SDL doesn't provide hardware line blitting support, and I at least
- * needed such a function... This seems to be fast enough, using this
- * home-rolled algorithm for now.
- */
-/* XXX Modify so that it performs a gradient using draw_pixel_transparent()
- * with various alpha values when lines are nor vertical, horizontal or
- * diagonal. I.E.
- * --++--
- *       --++--
- * This is apparently a known antialiasing algorithm for lines and would
- * probably be faster than using my current method.
- */
-void
-draw_line(draw_point_t *p1, draw_point_t *p2, uint32_t col)
-{
-       int             ix, iy;
-       register int    x, y, tx, ty;
-       double          f, fa;
-
-       assert(p1 != NULL);
-       assert(p2 != NULL);
-       assert(!(p1->x < 0 || p1->x >= screen_width ||
-           p1->y < 0 || p1->y >= screen_height));
-       assert(!(p2->x < 0 || p2->x >= screen_width ||
-           p2->y < 0 || p2->y >= screen_height));
-
-       /*
-        * Convert quadrant 1 to 3, and quadrant 2 to 4. This ensures that we
-        * only need to blit the line from top to bottom.
-        */
-       if (p1->y > p2->y) {
-               draw_point_t    *p;
-
-               p = p1;
-               p1 = p2;
-               p2 = p;
-       }
-
-       /* Test for cases which can easily be optimized */
-       if (p1->x == p2->x) {
-               if (p1->y == p2->y) {
-                       /* Only a single pixel to blit */
-                       draw_pixel(p1->x, p1->y, col);
-                       return;
-               }
-               /* We can use draw_vline() */
-               draw_vline(p1, (p2->y - p1->y), col);
-               return;
-       }
-       if (p1->y == p2->y) {
-               /* We can use draw_hline() */
-               if (p1->x < p2->x)
-                       draw_hline(p1, (p2->x - p1->x), col);
-               else
-                       draw_hline(p2, (p1->x - p2->x), col);
-               return;
-       }
-
-       if (p1->x < p2->x) {
-               /* Left to right blitting, quadrant 4 */
-
-               /* Obtain width/height ratio */
-               ix = p2->x - p1->x;
-               iy = p2->y - p1->y;
-               if (ix == iy) {
-                       /*
-                        * Equal ratio, no need to use floating point
-                        * arithmetic
-                        */
-                       for (x = p1->x, y = p1->y, tx = p2->x, ty = p2->y;
-                           x <= tx && y <= ty; x++, y++)
-                               DRAW_PIXEL(x, y, col);
-               } else if (ix > iy) {
-                       /*
-                        * XXX Use tf double instead of converting f to int
-                        * in comparision and test if speed is gained
-                        */
-                       /* X ratio larger, use floating point for Y count */
-                       for (fa = (double)iy / (double)ix,
-                           f = (double)p1->y, x = p1->x, tx = p2->x;
-                           (int)f <= p2->y && x <= tx; x++, f += fa)
-                               DRAW_PIXEL(x, (int)f, col);
-               } else {
-                       /* Y ratio larger, use floating point for X count */
-                       for (fa = (double)ix / (double)iy,
-                           f = (double)p1->x, y = p1->y, ty = p2->y;
-                           (int)f <= p2->x && y <= ty; y++, f += fa)
-                               DRAW_PIXEL((int)f, y, col);
-               }
-       } else {
-               /* Right to left blitting, quadrant 3 */
-
-               /* Obtain width/height ratio */
-               ix = p1->x - p2->x;
-               iy = p2->y - p1->y;
-               if (ix == iy) {
-                       /*
-                        * Equal ratio, no need to use floating point
-                        * arithmetic
-                        */
-                       for (x = p1->x, y = p1->y, tx = p2->x, ty = p2->y;
-                           x >= tx && y <= ty; x--, y++)
-                               DRAW_PIXEL(x, y, col);
-               } else if (ix > iy) {
-                       /* X ratio larger, use floating point for Y count */
-                       for (fa = (double)iy / (double)ix,
-                           f = (double)p1->y, x = p1->x, tx = p2->x;
-                           (int)f <= p2->y && x >= tx; x--, f += fa)
-                               DRAW_PIXEL(x, (int)f, col);
-               } else {
-                       /* Y ratio larger, use floating point for X count */
-                       for (fa = (double)ix / (double)iy,
-                           f = (double)p1->x, y = p1->y, ty = p2->y;
-                           (int)f >= p2->x && y <= ty; y++, f -= fa)
-                               DRAW_PIXEL((int)f, y, col);
-               }
-       }
-}
-
-inline void
-draw_moveto(draw_point_t *p)
-{
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x >= screen_width ||
-           p->y < 0 || p->y >= screen_height));
-
-       pen = *p;
-}
-
-inline void
-draw_lineto(draw_point_t *p, uint32_t col)
-{
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x >= screen_width ||
-           p->y < 0 || p->y >= screen_height));
-
-       draw_line(&pen, p, col);
-       pen = *p;
-}
-
-/*
- * Fills the specified region, as long as pixels are bgcol, in all directions.
- * This implementation uses a custom stack with iteration to avoid overflowing
- * the stack. SDL can internally be compiled against various threading
- * libraries, several of which have a fixed stack size (I.E. Pth). Thus,
- * filling rather large areas crashes using the previous implementation.
- * With this one, we don't need to worry about stack room, since we are using
- * the process heap instead. It however may be slower on some architectures
- * than implementations using the actual stack.
- */
-void
-draw_fill_bg(draw_point_t *p, uint32_t col, uint32_t bgcol)
-{
-       draw_point_t    node;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x >= screen_width ||
-           p->y < 0 || p->y >= screen_height));
-
-       stack_pos = stack_start;
-       *stack_pos++ = *p;
-
-       while (stack_pos > stack_start) {
-               node = *--stack_pos;
-               if (!(node.x < 0 || node.y > screen_width - 1 ||
-                   node.y < 0 || node.y > screen_height - 1)) {
-                       if (draw_getpixel(&node) == bgcol) {
-                               draw_pixel(node.x, node.y, col);
-                               *stack_pos++ =
-                                   (draw_point_t){node.x + 1, node.y};
-                               *stack_pos++ =
-                                   (draw_point_t){node.x, node.y + 1};
-                               *stack_pos++ =
-                                   (draw_point_t){node.x - 1, node.y};
-                               *stack_pos++ =
-                                   (draw_point_t){node.x, node.y - 1};
-                       }
-               }
-       }
-}
-
-/*
- * This implementation varies in that all pixels which are not of specified
- * colors are filled. This is only useful if you know the borders of your
- * surface to fill has the same color. It then allows to perform opaque
- * filling over a variety of colors, contrary to the last function.
- */
-void
-draw_fill_fg(draw_point_t *p, uint32_t col)
-{
-       draw_point_t    node;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x >= screen_width ||
-           p->y < 0 || p->y >= screen_height));
-
-       stack_pos = stack_start;
-       *stack_pos++ = *p;
-
-       while (stack_pos > stack_start) {
-               node = *--stack_pos;
-               if (!(node.x < 0 || node.y > screen_width - 1 ||
-                   node.y < 0 || node.y > screen_height - 1)) {
-                       if (draw_getpixel(&node) != col) {
-                               draw_pixel(node.x, node.y, col);
-                               *stack_pos++ =
-                                   (draw_point_t){node.x + 1, node.y};
-                               *stack_pos++ =
-                                   (draw_point_t){node.x, node.y + 1};
-                               *stack_pos++ =
-                                  (draw_point_t){node.x - 1, node.y};
-                               *stack_pos++ =
-                                  (draw_point_t){node.x, node.y - 1};
-                       }
-               }
-       }
-}
-
-/*
- * Draws a perfect circle pixel-wise, radius <radius>, expressed in pixels.
- * What it does is draw in four sections, adding pixels at both sides of each
- * section until the sections close the circle.
- */
-void
-draw_circle(draw_point_t *p, int radius, uint32_t col)
-{
-       int     x = 0, y = radius, u = 1, v = 2 * radius - 1, e = 0;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x + radius > screen_width ||
-               p->y < 0 || p->y + radius > screen_height ||
-               p->x - radius < 0 || p->y - radius < 0));
-
-       while (x < y) {
-               DRAW_PIXEL(p->x + x, p->y + y, col);
-               DRAW_PIXEL(p->x + y, p->y - x, col);
-               DRAW_PIXEL(p->x - x, p->y - y, col);
-               DRAW_PIXEL(p->x - y, p->y + x, col);
-               x++;
-               e += u;
-               u += 2;
-               if (v < (2 * e)) {
-                       y--;
-                       e -= v;
-                       v -= 2;
-               }
-               if (x > y)
-                       break;
-               DRAW_PIXEL(p->x + y, p->y + x, col);
-               DRAW_PIXEL(p->x + x, p->y - y, col);
-               DRAW_PIXEL(p->x - y, p->y - x, col);
-               DRAW_PIXEL(p->x - x, p->y + y, col);
-       }
-}
-
-/*
- * Returns x/y position in (xp,yp), for point at (x,y) of radius <radius> at
- * angle <angle> (in radians). Uses an array suitable for onscreen resolution
- * for efficiency instead of having to always call sin()/cos() functions.
- */
-inline void
-draw_get_vector(draw_point_t *tp, draw_point_t *p, draw_vect_t *v)
-{
-       int     angle;
-
-       assert(tp != NULL);
-       assert(p != NULL);
-       assert(v != NULL);
-       assert(!(p->x < 0 || p->x + v->r > screen_width ||
-           p->y < 0 || p->y + v->r > screen_height ||
-           p->x - v->r < 0 || p->y - v->r < 0));
-
-       if ((angle = v->a) < 0)
-               angle = 1000 - (-angle);
-       else if (angle > 999)
-               angle %= 1000;
-
-       tp->x = (int)(p->x + (cos_table[angle] * v->r));
-       tp->y = (int)(p->y + (sin_table[angle] * v->r));
-}
-
-/*
- * Slower implementation of draw_circle() using floating point, but which
- * can draw arcs.
- */
-void draw_circle_arc(draw_point_t *p, int radius, int a1, int a2, int step,
-    uint32_t col)
-{
-       register int    i;
-       draw_point_t    tp;
-       draw_vect_t     v;
-
-       assert(p != NULL);
-       assert(!(p->x < 0 || p->x + radius > screen_width ||
-           p->y < 0 || p->y + radius > screen_height ||
-           p->x - radius < 0 || p->y - radius < 0));
-
-       if (a2 < a1) {
-               i = a1;
-               a1 = a2;
-               a2 = i;
-       }
-       v.r = radius;
-       v.a = a1;
-       draw_get_vector(&tp, p, &v);
-       draw_moveto(&tp);
-       for (i = a1; i <= a2; i += step) {
-               v.a = i;
-               draw_get_vector(&tp, p, &v);
-               draw_lineto(&tp, col);
-       }
-       if (i > a2) {
-               v.a = a2;
-               draw_get_vector(&tp, p, &v);
-               draw_lineto(&tp, col);
-       }
-}
diff --git a/tests/sdl-client/tests/draw.h b/tests/sdl-client/tests/draw.h
deleted file mode 100644 (file)
index 2cb3647..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $Id: draw.h,v 1.1 2006/05/03 14:22:06 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-#ifndef DRAW_H
-#define DRAW_H
-
-
-
-#include <stdint.h>
-
-
-
-#define        SCREEN_LOCK()   if (SDL_LockSurface(screen_surface) != 0) \
-                               abort();
-#define SCREEN_UNLOCK()        SDL_UnlockSurface(screen_surface)
-
-
-
-typedef struct draw_point {
-       int     x, y;
-} draw_point_t;
-
-typedef struct draw_vect {
-       int     a, r;
-} draw_vect_t;
-
-typedef struct draw_rect {
-       int     x, y;
-       int     w, h;
-} draw_rect_t;
-
-
-
-extern int             draw_init(void);
-extern inline void     draw_vline(draw_point_t *, int, uint32_t);
-extern inline void     draw_hline(draw_point_t *, int, uint32_t);
-extern inline void     draw_rect(draw_rect_t *, uint32_t, uint32_t);
-extern void            draw_rect_3d(draw_rect_t *, uint32_t, uint32_t,
-                           uint32_t, int);
-extern inline void     draw_rect_fill(draw_rect_t *, uint32_t);
-extern void            draw_rect_fill_xor(draw_rect_t *, uint32_t);
-extern void            draw_rect_fill_inverse(draw_rect_t *, uint32_t,
-                           uint32_t);
-extern void            draw_rect_fill_transparent(draw_rect_t *, uint32_t);
-extern void            draw_surface_color(SDL_Surface *, draw_rect_t *,
-                           draw_point_t *, uint32_t, uint32_t);
-extern void            draw_surface_color_antialias(SDL_Surface *,
-                           draw_rect_t *, draw_point_t *, uint32_t,
-                           uint32_t);
-extern void            draw_surface_copy(SDL_Surface *, draw_point_t *,
-                           SDL_Surface *, draw_rect_t *);
-extern inline void     draw_pixel(int, int, uint32_t);
-extern inline void     draw_pixel_transparent(int, int, uint32_t, int);
-extern inline void     draw_pixel_antialias(int, int, uint32_t);
-extern inline uint32_t draw_getpixel(draw_point_t *);
-extern inline uint32_t draw_getpixel2(int, int);
-extern void            draw_line(draw_point_t *, draw_point_t *, uint32_t);
-extern void            draw_moveto(draw_point_t *);
-extern void            draw_lineto(draw_point_t *, uint32_t);
-extern void            draw_fill_bg(draw_point_t *, uint32_t, uint32_t);
-extern void            draw_fill_fg(draw_point_t *, uint32_t);
-extern void            draw_circle(draw_point_t *, int, uint32_t);
-extern inline void     draw_get_vector(draw_point_t *, draw_point_t *,
-                           draw_vect_t *);
-extern void            draw_circle_arc(draw_point_t *, int, int, int, int,
-                           uint32_t);
-
-
-
-#endif
diff --git a/tests/sdl-client/tests/fonts.c b/tests/sdl-client/tests/fonts.c
deleted file mode 100644 (file)
index fc6b96f..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-/* $Id: fonts.c,v 1.1 2006/05/03 14:20:47 mmondor Exp $ */
-
-/*
- * Copyright (c) 2004-2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-/* HEADERFILES */
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <SDL.h>
-
-#include <fonts.h>
-#include <screen.h>
-#include <draw.h>
-#include <conf.h>
-
-
-
-/* DEFINITIONS */
-
-#ifdef ANTIALIASING            /* conf,h */
-#define DRAW_SURFACE_COLOR     draw_surface_color_antialias
-#else
-#define DRAW_SURFACE_COLOR     draw_surface_color
-#endif
-
-
-
-/* STATIC FUNCTIONS PROTOTYPES */
-
-inline static void     font_rectangle(font_t *, draw_rect_t *, int);
-
-
-
-/* GLOBALS */
-
-font_t                 *font_small, *font_small_bold,
-                       *font_large, *font_large_bold;
-
-
-
-/* PRIVATE FUNCTIONS */
-
-/*
- * Fills the rectangle coordinates for the specified character of specified
- * font within the font's surface
- */
-inline static void
-font_rectangle(font_t *font, draw_rect_t *rect, int c)
-{
-       assert(font != NULL);
-       assert(rect != NULL);
-
-       /* Make sure that c is within 0-255 */
-       c &= 0xff;
-
-       /* Map c (0-255) to 0-15 x/y coordinates */
-       rect->x = font->x * (c & 0x0f);
-       rect->y = font->y * (c / 16);
-       rect->w = font->x;
-       rect->h = font->y;
-}
-
-
-
-/* PUBLIC FUNCTIONS */
-
-/* Load fonts */
-int
-font_init(void)
-{
-
-       font_small = font_load(
-           "bmp/misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1.bmp");
-       font_small_bold = font_load(
-           "bmp/misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1.bmp");
-       font_large = font_load(
-         "bmp/misc-fixed-medium-r-normal--15-120-100-100-c-90-iso8859-1.bmp");
-       font_large_bold = font_load(
-           "bmp/misc-fixed-bold-r-normal--15-120-100-100-c-90-iso8859-1.bmp");
-
-       /*
-        * On error, we don't free any successfully loaded fonts, and expect
-        * the application to exit.
-        */
-       if (font_small == NULL || font_small_bold == NULL ||
-           font_large == NULL || font_large_bold == NULL)
-               return -1;
-
-       return 0;
-}
-
-/*
- * Allows to load a 256 characters (16x16 tiled) font map from an image.
- * This image usually is in 1 bit depth, but it internally gets converted to
- * 32-bit depth, and we then create a per-pixel alpha blending enabled surface
- * for it.
- */
-font_t *
-font_load(const char *file)
-{
-       font_t          *font;
-       SDL_Surface     *surface1 = NULL, *surface2 = NULL, *surface3 = NULL;
-       int             ok;
-
-       assert(file != NULL);
-
-       /* Load 1 bit depth bitmap */
-       if ((surface1 = SDL_LoadBMP(file)) == NULL)
-               goto err;
-
-       /*
-        * Convert loaded surface to screen_surface's depth, into new surface.
-        * bits 0 become 0x00000000 and 1 0x00ffffff. Remember that surface2
-        * is the one we'll copy to the final destination one.
-        */
-       if ((surface2 = SDL_ConvertSurface(surface1, screen_surface->format,
-           SDL_SWSURFACE)) == NULL)
-               goto err;
-       SDL_FreeSurface(surface1);
-       surface1 = NULL;
-
-       /*
-        * Create new surface suitable for source alpha blending blitting.
-        * I previously attempted to use the converted surface and create an
-        * alpha blending enabled copy, but this seemed to fail. I thus must
-        * explicitely create a new surface myself (which proved to work in a
-        * test program).
-        */
-       if ((surface1 = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA,
-           surface2->w, surface2->h, 32, 0, 0, 0, 0)) == NULL)
-               goto err;
-
-       /*
-        * Convert newly created surface to support per-pixel alpha blending
-        * with hardware support. Resulting surface3 is the one we'll copy
-        * surface2 to.
-        */
-       (void) SDL_SetAlpha(surface1, SDL_SRCALPHA | SDL_RLEACCEL, 128);
-       if ((surface3 = SDL_DisplayFormatAlpha(surface1)) == NULL)
-               goto err;
-       SDL_FreeSurface(surface1);
-       surface1 = NULL;
-
-       /*
-        * We now have both our 32-bit depth font surface (surface2) and our
-        * destination alpha surface (surface3). Copy surface2 data to
-        * surface3, making sure to set the alpha color to 0x00 for pixels
-        * which originally were 0 bits, that is, now 0x00000000, and to 0xff
-        * for pixels which were 1 bits, now being 0x00ffffff.
-        */
-       ok = -1;
-       if (SDL_LockSurface(surface2) == 0) {
-               if (SDL_LockSurface(surface3) == 0) {
-                       uint32_t        *sptr, *dptr, *dtptr;
-
-                       for (sptr = (uint32_t *)surface2->pixels,
-                           dptr = (uint32_t *)surface3->pixels,
-                           dtptr = &dptr[surface3->w * surface3->h];
-                           dptr < dtptr;
-                           sptr++, dptr++)
-                               *dptr = (*sptr == 0 ? 0x00000000 : 0xffffffff);
-                       ok = 0;
-                       SDL_UnlockSurface(surface3);
-               }
-               SDL_UnlockSurface(surface2);
-       }
-       SDL_FreeSurface(surface2);
-       surface2 = NULL;
-       if (ok == -1)
-               goto err;
-
-       /* Allocate font structure */
-       if ((font = malloc(sizeof(font_t))) == NULL)
-               goto err;
-
-       /* Everything successful, fill font structure and return it. */
-       font->x = surface3->w / 16;
-       font->y = surface3->h / 16;
-       font->surface = surface3;
-
-       return font;
-
-err:
-       if (surface1 != NULL)
-               SDL_FreeSurface(surface1);
-       if (surface2 != NULL)
-               SDL_FreeSurface(surface2);
-       if (surface3 != NULL)
-               SDL_FreeSurface(surface3);
-
-       return NULL;
-}
-
-/* Frees previously loaded font using font_load() */
-void
-font_free(font_t *font)
-{
-
-       assert(font != NULL);
-       assert(font->surface != NULL);
-
-       SDL_FreeSurface(font->surface);
-       free(font);
-}
-
-/*
- * Efficiently draws a character to screen at specified position. The output
- * color however can only be white using this function.
- */
-void
-font_draw_char(font_t *font, draw_point_t *p, int c)
-{
-       SDL_Rect        screen_rect, font_rect;
-       draw_rect_t     r;
-
-       assert(font != NULL);
-       assert(p != NULL);
-
-       screen_rect.x = p->x;
-       screen_rect.y = p->y;
-       font_rectangle(font, &r, c);
-       font_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
-       (void) SDL_BlitSurface(font->surface, &font_rect,
-           screen_surface, &screen_rect);
-}
-
-/*
- * Efficiently draws a character string to screen at specified position.
- * The output color however can only be white using this function.
- */
-void
-font_draw_string(font_t *font, draw_point_t *p, const char *string)
-{
-       register const char     *ptr;
-       SDL_Rect                screen_rect, font_rect;
-       draw_rect_t             r;
-
-       assert(font != NULL);
-       assert(p != NULL);
-       assert(string != NULL);
-
-       screen_rect.x = p->x;
-       screen_rect.y = p->y;
-       for (ptr = string; *ptr != '\0'; ptr++, screen_rect.x += font->x) {
-               font_rectangle(font, &r, *ptr);
-               font_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
-               (void) SDL_BlitSurface(font->surface, &font_rect,
-                   screen_surface, &screen_rect);
-       }
-}
-
-/*
- * Returns the necessary number of horizontal pixels required to blit the
- * specified string.
- */
-int
-font_string_width(font_t *font, const char *string)
-{
-
-       assert(font != NULL);
-       assert(string != NULL);
-
-       return (strlen(string) * font->x);
-}
-
-
-/* The following functions require that the screen surface be locked. */
-
-/*
- * font_draw_char() variant which is a slightly less efficient but allows to
- * blit a character on screen at specified position with specified color.
- * If bg color is 0, font is drawn in overlay mode. Otherwise, it is drawn
- * overstrike with specified color. Note that if calling this function, the
- * screen_surface SDL_Surface should be locked using SDL_LockSurface().
- */
-void
-font_draw_char_color(font_t *font, uint32_t fg, uint32_t bg, draw_point_t *p,
-    int c)
-{
-       draw_rect_t     rect;
-
-       assert(font != NULL);
-       assert(p != NULL);
-
-       font_rectangle(font, &rect, c);
-       DRAW_SURFACE_COLOR(font->surface, &rect, p, fg, bg);
-}
-
-/*
- * font_draw_string() variant which is a little less efficient but allows to
- * blit a character string on screen at specified position with specified
- * color. If bg is 0, string is drawn in overlay mode. Otherwise, it is drawn
- * in overstrike mode with specified background color.
- */
-void
-font_draw_string_color(font_t *font, uint32_t fg, uint32_t bg, draw_point_t *p,
-    const char *string)
-{
-       register const char     *ptr;
-       draw_rect_t             rect;
-
-       assert(font != NULL);
-       assert(p != NULL);
-       assert(string != NULL);
-
-       for (ptr = string; *ptr != '\0'; ptr++, p->x += font->x) {
-               font_rectangle(font, &rect, *ptr);
-               DRAW_SURFACE_COLOR(font->surface, &rect, p, fg, bg);
-       }
-}
diff --git a/tests/sdl-client/tests/fonts.h b/tests/sdl-client/tests/fonts.h
deleted file mode 100644 (file)
index 2edbccd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $id$ */
-
-/*
- * Copyright (c) 2004-2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#ifndef FONTS_H
-#define FONTS_H
-
-
-
-#include <SDL.h>
-
-#include <draw.h>
-
-
-
-typedef struct font {
-       int             x, y;
-       SDL_Surface     *surface;
-} font_t;
-
-
-
-extern int             font_init(void);
-extern font_t          *font_load(const char *);
-extern void            font_free(font_t *);
-extern void            font_draw_char(font_t *, draw_point_t *, int);
-extern void            font_draw_string(font_t *, draw_point_t *,
-                           const char *);
-extern int             font_string_width(font_t *, const char *);
-extern void            font_draw_char_color(font_t *, uint32_t, uint32_t,
-                           draw_point_t *, int);
-extern void            font_draw_string_color(font_t *, uint32_t, uint32_t,
-                           draw_point_t *, const char *);
-
-
-extern font_t          *font_small, *font_small_bold,
-                               *font_large, *font_large_bold;
-
-
-
-#endif
diff --git a/tests/sdl-client/tests/msg.c b/tests/sdl-client/tests/msg.c
deleted file mode 100644 (file)
index dc4a14a..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* $Id: msg.c,v 1.1 2006/04/27 13:26:51 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <SDL.h>
-#include <SDL_thread.h>
-
-#include <thread_msg.h>
-
-
-
-#define        CLIENTS 16
-#define ROUNDS 32
-
-
-
-struct client {
-       SDL_Thread      *thread;
-       int             id;
-};
-
-struct client_msg {
-       thread_msg_t    msg;
-       struct client   *c;
-       int             rounds;
-};
-
-
-
-int            main(int, char **);
-
-static void    done(int);
-static int     thread_client(void *);
-
-
-
-thread_port_t  server_port;
-
-
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-       struct client   clients[CLIENTS];
-       int             i;
-       thread_ring_t   server_ring;
-
-       if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
-               (void) fprintf(stderr, "main() - SDL_Init() - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       /*
-        * We're already the server thread.
-        * Initialize our message port and notification ring.
-        */
-       if (thread_ring_init(&server_ring) == -1) {
-               (void) fprintf(stderr,
-                   "main() - thread_ring_init(server_port) - %s\n",
-                   SDL_GetError());
-               done(EXIT_FAILURE);
-       }
-       if (thread_port_init(&server_port) == -1) {
-               (void) fprintf(stderr,
-                   "main() - thread_port_init(server_port) - %s\n",
-                   SDL_GetError());
-               done(EXIT_FAILURE);
-       }
-       thread_port_set_ring(&server_port, &server_ring);
-
-       /* Launch client threads */
-       for (i = 0; i < CLIENTS; i++) {
-               clients[i].id = i;
-               if ((clients[i].thread = SDL_CreateThread(thread_client,
-                   &clients[i])) == NULL) {
-                       (void) fprintf(stderr,
-                           "main() - SDL_CreateThread(%d) - %s\n",
-                           i, SDL_GetError());
-                       done(EXIT_FAILURE);
-               }
-       }
-
-       /*
-        * Listen for messages from our client threads with a one second
-        * timeout delay and display them.
-        */
-       for (;;) {
-               struct client_msg       *msg;
-
-               while ((msg = (struct client_msg *)thread_msg_get(
-                   &server_port)) != NULL) {
-                       (void) printf("Message from client %d: %d\n",
-                           msg->c->id, msg->rounds);
-                       if (thread_msg_reply(&msg->msg) != 0) {
-                               (void) fprintf(stderr,
-                                   "main() - thread_msg_reply() - %s\n",
-                                   SDL_GetError());
-                               break;
-                       }
-               }
-               (void) printf("Server polling\n");
-               if (thread_ring_wait(&server_ring, 1000) != 0) {
-                       (void) fprintf(stderr,
-                           "main() - thread_ring_wait() - %s\n",
-                           SDL_GetError());
-                       break;
-               }
-       }
-
-       thread_port_set_ring(&server_port, NULL);
-       thread_port_destroy(&server_port);
-       thread_ring_destroy(&server_ring);
-
-       exit(EXIT_SUCCESS);
-}
-
-static void
-done(code)
-{
-
-       SDL_Quit();
-       exit(code);
-}
-
-static int
-thread_client(void *data)
-{
-       struct client           *c = (struct client *)data;
-       struct client_msg       msg, *rmsg;
-       thread_ring_t           client_ring;
-       thread_port_t           client_port;
-       int                     i;
-
-       /* Initialize reply port and ring */
-       if (thread_ring_init(&client_ring) == -1) {
-               (void) fprintf(stderr,
-                   "thread_client(%d) - thread_ring_init(server_port) - %s\n",
-                   c->id, SDL_GetError());
-               done(EXIT_FAILURE);
-       }
-       if (thread_port_init(&client_port) == -1) {
-               (void) fprintf(stderr,
-                   "thread_client(%d) - thread_port_init(server_port) - %s\n",
-                   c->id, SDL_GetError());
-               done(EXIT_FAILURE);
-       }
-       thread_port_set_ring(&client_port, &client_ring);
-
-       /* Initialize message with our reply port */
-       thread_msg_init(&msg.msg, &client_port);
-       msg.c = c;
-
-       for (i = 0; i < ROUNDS; i++) {
-               msg.rounds = i;
-               if (thread_msg_put(&server_port, &msg.msg) == -1) {
-                       (void) fprintf(stderr,
-                           "thread_client(%d) - thread_msg_put(%d) - %s\n",
-                           c->id, i, SDL_GetError());
-                       break;
-               }
-               while ((rmsg = (struct client_msg *)thread_msg_get(
-                   &client_port)) == NULL) {
-                       (void) printf("Client polling\n");
-                       if (thread_ring_wait(&client_ring, 1000) != 0) {
-                               (void) fprintf(stderr,
-                                   "thread_client(%d) - thread_ring_wait(%d)"
-                                   "- %s\n", c->id, i, SDL_GetError());
-                               break;
-                       }
-               }
-               if (rmsg != NULL)
-                       (void) printf("Received reply for %d: %d\n",
-                           rmsg->c->id, rmsg->rounds);
-               else
-                       break;
-       }
-
-       return 0;
-}
diff --git a/tests/sdl-client/tests/netrek-like.c b/tests/sdl-client/tests/netrek-like.c
deleted file mode 100644 (file)
index dbf9e11..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $Id: netrek-like.c,v 1.1 2006/05/03 08:58:01 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <SDL.h>
-#include <SDL_rotozoom.h>
-#include <SDL_gfxPrimitives.h>
-
-#include <screen.h>
-#include <fonts.h>
-
-
-
-int                    main(int, char **);
-
-static int             surface_blit_angle(SDL_Surface *, int, int,
-                           double, int);
-static SDL_Surface     *bmp_load_key(const char *);
-
-
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-       int             i;
-       SDL_Surface     *rship, *fship;
-
-       screen_init();
-       draw_init();
-       if (font_init() != 0) {
-               (void) fprintf(stderr, "Could not load font bitmaps\n");
-               screen_destroy();
-       }
-
-       rship = bmp_load_key("bmp/RomDD.bmp");
-       fship = bmp_load_key("bmp/FedCA.bmp");
-
-       (void) rectangleRGBA(screen_surface, 0, 0, 750, 750,
-           0xff, 0xff, 0xff, 0xff);
-       (void) rectangleRGBA(screen_surface, 750, 0, 1023, 274,
-           0xff, 0xff, 0xff, 0xff);
-       (void) rectangleRGBA(screen_surface, 750, 274, 1023, 506,
-           0xff, 0xff, 0xff, 0xff);
-       (void) rectangleRGBA(screen_surface, 750, 274, 1023, 767,
-           0xff, 0xff, 0xff, 0xff);
-       (void) rectangleRGBA(screen_surface, 0, 750, 1023, 767,
-           0xff, 0xff, 0xff, 0xff);
-
-       for (i = 0; i < 1440; i += 2) {
-               if (surface_blit_angle(rship, 100, 100, (double)i, 1) == -1 ||
-                   surface_blit_angle(fship, 200, 100, (double)i, 1) == -1)
-                       (void) fprintf(stderr, "surface_blit_angle()\n");
-               SDL_Flip(screen_surface);
-               SDL_Delay(10);
-       }
-
-       SDL_Delay(1000);
-
-       /* Attempt to connect to server */
-
-       screen_destroy();
-       /* NOTREACHED */
-
-       exit(EXIT_SUCCESS);
-}
-
-static SDL_Surface *
-bmp_load_key(const char *file)
-{
-       SDL_Surface     *s;
-       Uint32          c;
-
-       if ((s = SDL_LoadBMP(file)) == NULL)
-               goto err;
-
-       c = SDL_MapRGB(s->format, 0, 0, 0);
-       if (SDL_SetColorKey(s, SDL_SRCCOLORKEY | SDL_RLEACCEL, c) == -1)
-               goto err;
-
-       return s;
-
-err:
-       (void) fprintf(stderr, "bmp_load_key(%s) - %s\n", file, SDL_GetError());
-       screen_destroy();
-       /* NOTREACHED */
-       return NULL;
-}
-
-static int
-surface_blit_angle(SDL_Surface *s, int x, int y, double a, int clean)
-{
-       SDL_Surface     *t;
-       SDL_Rect        d;
-       int             r;
-
-       if (clean) {
-               int     cx, cy, c;
-
-               cx = s->w / 2 + 2;
-               cy = s->h / 2 + 2;
-               c = (cx >= cy ? cx : cy);
-               (void) boxRGBA(screen_surface, x - c, y - c,
-                   x + c, y + c, 0x00, 0x00, 0x00, 0xff);
-       }
-
-       if ((t = rotozoomSurface(s, a, 0.75, 1)) == NULL)
-               return -1;
-
-       d = (SDL_Rect){x - (t->w / 2), y - (t->h / 2), 0, 0};
-       r = SDL_BlitSurface(t, NULL, screen_surface, &d);
-       SDL_FreeSurface(t);
-
-       return r;
-}
diff --git a/tests/sdl-client/tests/rot.c b/tests/sdl-client/tests/rot.c
deleted file mode 100644 (file)
index 18448e8..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* $Id: rot.c,v 1.3 2006/05/03 08:09:37 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <SDL.h>
-#include <SDL_rotozoom.h>
-#include <SDL_gfxPrimitives.h>
-
-#include <screen.h>
-#include <fonts.h>
-
-
-
-typedef struct angle_cache {
-       SDL_Surface     *source;
-       SDL_Surface     *angles[360];
-} angle_cache_t;
-
-
-
-int                    main(int, char **);
-
-static angle_cache_t   *angle_cache_init(SDL_Surface *);
-static void            angle_cache_destroy(angle_cache_t *);
-static int             surface_blit_angle(struct angle_cache *, int, int,
-                           double, int);
-static SDL_Surface     *bmp_load_key(const char *);
-
-
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-       int             i, i2;
-       SDL_Surface     *rship, *fship;
-       angle_cache_t   *rshipc, *fshipc;
-
-       screen_init();
-       draw_init();
-       if (font_init() != 0) {
-               (void) fprintf(stderr, "Could not load font bitmaps\n");
-               screen_destroy();
-       }
-
-       rship = bmp_load_key("bmp/RomDD.bmp");
-       fship = bmp_load_key("bmp/FedCA.bmp");
-       if ((rshipc = angle_cache_init(rship)) == NULL ||
-           (fshipc = angle_cache_init(fship)) == NULL) {
-               (void) fprintf(stderr, "Could not initialize angle caches\n");
-               screen_destroy();
-       }
-
-       for (i2 = 0; i2 < 2; i2++) {
-               for (i = 0; i < 360; i += 5) {
-                       if (surface_blit_angle(rshipc, 100, 100, (double)i, 1)
-                           == -1 || surface_blit_angle(fshipc, 200, 100,
-                           (double)i, 1) == -1)
-                               (void) fprintf(stderr,
-                                   "surface_blit_angle()\n");
-                       SDL_Flip(screen_surface);
-                       SDL_Delay(33);
-               }
-       }
-
-       SDL_Delay(1000);
-
-       /* Attempt to connect to server */
-
-       screen_destroy();
-       /* NOTREACHED */
-
-       exit(EXIT_SUCCESS);
-}
-
-static SDL_Surface *
-bmp_load_key(const char *file)
-{
-       SDL_Surface     *s;
-       Uint32          c;
-
-       if ((s = SDL_LoadBMP(file)) == NULL)
-               goto err;
-
-       c = SDL_MapRGB(s->format, 0, 0, 0);
-       if (SDL_SetColorKey(s, SDL_SRCCOLORKEY | SDL_RLEACCEL, c) == -1)
-               goto err;
-
-       return s;
-
-err:
-       (void) fprintf(stderr, "bmp_load_key(%s) - %s\n", file, SDL_GetError());
-       screen_destroy();
-       /* NOTREACHED */
-       return NULL;
-}
-
-static angle_cache_t *
-angle_cache_init(SDL_Surface *s)
-{
-       angle_cache_t   *ac;
-       int             i;
-
-       assert(s != NULL);
-
-       if ((ac = malloc(sizeof(angle_cache_t))) != NULL) {
-               ac->source = s;
-               for (i = 0; i < 360; i++)
-                       ac->angles[i] = NULL;
-
-               return ac;
-       }
-
-       return NULL;
-}
-
-static void
-angle_cache_destroy(angle_cache_t *ac)
-{
-       int     i;
-
-       assert(ac != NULL);
-
-       for (i = 0; i < 360; i++) {
-               if (ac->angles[i] != NULL)
-                       SDL_FreeSurface(ac->angles[i]);
-       }
-
-       free(ac);
-}
-
-static int
-surface_blit_angle(angle_cache_t *ac, int x, int y, double a, int clean)
-{
-       SDL_Surface     *t, *s = ac->source;
-       SDL_Rect        d;
-       int             r, i;
-
-       assert(a > -1 && a < 360);
-       assert(((int)a) == a);
-
-       if (clean) {
-               int     cx, cy, c;
-
-               cx = s->w / 2 + 2;
-               cy = s->h / 2 + 2;
-               c = (cx >= cy ? cx : cy);
-               (void) boxRGBA(screen_surface, x - c, y - c,
-                   x + c, y + c, 0x00, 0x00, 0x00, 0xff);
-       }
-
-       if ((t = ac->angles[(int)a]) == NULL) {
-               for (r = 0; r < 2; r++) {
-                       if ((t = rotozoomSurface(s, a, 1.0, 1)) != NULL) {
-                               ac->angles[(int)a] = t;
-                               break;
-                       }
-                       /* Free some room and retry */
-                       for (i = 0; i < 360; i++) {
-                               if (ac->angles[i] != NULL) {
-                                       SDL_FreeSurface(ac->angles[i]);
-                                       ac->angles[i] = NULL;
-                               }
-                       }
-               }
-               if (t == NULL)
-                       return -1;
-       }
-
-       d = (SDL_Rect){x - (t->w / 2), y - (t->h / 2), 0, 0};
-       return SDL_BlitSurface(t, NULL, screen_surface, &d);
-}
diff --git a/tests/sdl-client/tests/snd.c b/tests/sdl-client/tests/snd.c
deleted file mode 100644 (file)
index eceaa3c..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $Id: snd.c,v 1.1 2006/05/01 03:52:45 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <SDL.h>
-#include <SDL_mixer.h>
-
-
-
-int                    main(int, char **);
-
-static void            done(int);
-static Mix_Chunk       *sample_load(const char *);
-
-
-
-static SDL_Surface     *surface_screen = NULL;
-static Mix_Chunk       *cloak, *uncloak, *shield, *unshield, *torp, *hit,
-                       *explode;
-
-static int             iscloaked, isshielded;
-
-
-
-/* ARGSUSED */
-int
-main(int argc, char **argv)
-{
-       Mix_Music       *mus;
-       SDL_Event       ev;
-
-       if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
-               (void) fprintf(stderr, "main() - SDL_Init() - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if ((surface_screen = SDL_SetVideoMode(640, 480, 32,
-           SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF/* | SDL_FULLSCREEN*/))
-           == NULL) {
-               (void) fprintf(stderr, "main() - SDL_SetVideoMode() - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-
-       if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) != 0) {
-               (void) fprintf(stderr, "main() - Mix_OpenAudio() - %s\n",
-                   Mix_GetError());
-               done(EXIT_FAILURE);
-       }
-
-       cloak = sample_load("wav/nt_cloaked.wav");
-       uncloak = sample_load("wav/nt_uncloak.wav");
-       shield = sample_load("wav/nt_shield_up.wav");
-       unshield = sample_load("wav/nt_shield_down.wav");
-       torp = sample_load("wav/nt_fire_torp_other.wav");
-       hit = sample_load("wav/nt_plasma_hit.wav");
-       explode = sample_load("wav/nt_explosion_other.wav");
-
-       (void) Mix_AllocateChannels(16);
-       (void) Mix_ReserveChannels(2);
-
-       if ((mus = Mix_LoadMUS("ogg/1.ogg")) == NULL) {
-               (void) fprintf(stderr, "main() - Mix_LoadMUS() - %s\n",
-                   Mix_GetError());
-               done(EXIT_FAILURE);
-       }
-
-       if (Mix_PlayMusic(mus, -1) != 0) {
-               (void) fprintf(stderr, "main() - Mix_PlayMusic() - %s\n",
-                   Mix_GetError());
-               done(EXIT_FAILURE);
-       }
-
-       for (iscloaked = isshielded = 0; SDL_WaitEvent(&ev) != 0; ) {
-               int     ch;
-
-               if (ev.type == SDL_KEYUP && ev.key.keysym.sym == SDLK_ESCAPE)
-                       break;
-               if (ev.type == SDL_KEYDOWN) {
-                       switch (ev.key.keysym.sym) {
-                       case SDLK_SPACE:
-                               /* Torp */
-                               if ((ch = Mix_PlayChannel(-1, torp, 0)) == -1)
-                                       (void) fprintf(stderr, "main() - "
-                                           "Mix_PlayChannel(torp) - %s\n",
-                                           SDL_GetError());
-                               else
-                                       Mix_SetPosition(ch, rand() % 359,
-                                           255 - (200 + (rand() % 54)));
-                               break;
-                       case SDLK_w:
-                               /* Cloak toggle */
-                               iscloaked = (iscloaked == 0 ? 1 : 0);
-                               if (Mix_PlayChannel(0,
-                                   (iscloaked == 1 ? cloak : uncloak), 0)
-                                   == -1)
-                                       (void) fprintf(stderr, "main() - "
-                                           "Mix_PlayChannel(cloack) - %s\n",
-                                           SDL_GetError());
-                               break;
-                       case SDLK_s:
-                               /* Shield toggle */
-                               isshielded = (isshielded == 0 ? 1 : 0);
-                               if (Mix_PlayChannel(1,
-                                   (isshielded == 1 ? shield : unshield), 0)
-                                   == -1)
-                                       (void) fprintf(stderr, "main() - "
-                                           "Mix_PlayChannel(shield) - %s\n",
-                                           SDL_GetError());
-                               break;
-                       default:
-                               break;
-                       }
-               }
-       }
-
-       if (Mix_FadeOutMusic(2000))
-               SDL_Delay(2000);
-
-       Mix_HaltMusic();
-       Mix_CloseAudio();
-
-       done(EXIT_SUCCESS);
-       /* NOTREACHED */
-       exit(EXIT_SUCCESS);
-}
-
-static void
-done(code)
-{
-
-       SDL_Quit();
-       exit(code);
-}
-
-static Mix_Chunk *
-sample_load(const char *file)
-{
-       Mix_Chunk       *c;
-
-       if ((c = Mix_LoadWAV(file)) == NULL) {
-               (void) fprintf(stderr,
-                   "sample_load() - Mix_LoadWAV(%s) - %s\n",
-                   file, SDL_GetError());
-               done(EXIT_FAILURE);
-       }
-
-       return c;
-}
diff --git a/tests/sdl-client/thread_msg.c b/tests/sdl-client/thread_msg.c
deleted file mode 100644 (file)
index 3652617..0000000
+++ /dev/null
@@ -1,432 +0,0 @@
-/* $Id: thread_msg.c,v 1.12 2006/05/19 10:14:35 mmondor Exp $ */
-
-/*
- * Copyright (C) 2006, Matthew Mondor
- * All rights reserved.
- *
- * Adapted from older code intended for use with POSIX threads,
- * for use within SDL.
- */
-
-
-
-#include <stdlib.h>
-
-#include <debug.h>
-#include <thread_msg.h>
-#include <pool.h>
-
-
-
-static int             amsg_create(pnode_t *);
-static void            amsg_destroy(pnode_t *);
-
-
-
-static pool_t          amsg_pool;
-static SDL_mutex       *amsg_mutex;
-static int             amsg_initialized = 0;
-
-
-
-/*
- * Allows to initialize a polling notification handle.  When attached to a
- * port, a message arriving on an empty port causes the associated ring to
- * wake the thread from thread_ring_wait().
- */
-int
-thread_ring_init(thread_ring_t *ring)
-{
-
-       ASSERT(ring != NULL && ring->magic != PRING_MAGIC);
-
-       if ((ring->cond = SDL_CreateCond()) != NULL) {
-               if ((ring->mutex = SDL_CreateMutex()) != NULL) {
-                       ring->event = 0;
-                       ring->magic = PRING_MAGIC;
-
-                       return 0;
-               }
-               SDL_DestroyCond(ring->cond);
-       }
-
-       return -1;
-}
-
-/*
- * Returns TRUE if the supplied ring is a valid/usable one, or FALSE
- * otherwise.  Useful to conditionally destroy it.
- */
-int
-thread_ring_valid(thread_ring_t *ring)
-{
-
-       ASSERT(ring != NULL);
-
-       return (ring != NULL && ring->magic == PRING_MAGIC);
-}
-
-/*
- * Destroys a ring.  Note that all message ports attached to this ring should
- * first be detached or destroyed.
- */
-void
-thread_ring_destroy(thread_ring_t *ring)
-{
-
-       ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       SDL_DestroyMutex(ring->mutex);
-       SDL_DestroyCond(ring->cond);
-       ring->magic = 0;
-}
-
-/*
- * Causes the current thread to sleep until a message arrives on an empty port
- * associated with this ring.  In normal operation, a thread only goes in wait
- * mode after it processed all queued messages on all interesting ports.
- * The ring is only notified when the port is empty and that a message is
- * queued into it.
- */
-int
-thread_ring_wait(thread_ring_t *ring, Uint32 ms)
-{
-       int     error = 0;
-
-       ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       /* We must hold the condition variable's mutex */
-       if (SDL_LockMutex(ring->mutex) != 0) {
-               error = -1;
-               goto err;
-       }
-
-       /* As long as we don't have confirmation that we must stop waiting */
-       for (ring->event = 0; !ring->event && error == 0; ) {
-               /*
-                * Wait on conditional variable, which will automatically
-                * and atomically release the mutex and return with the mutex
-                * locked again, as soon as the conditional variable gets
-                * signaled.
-                */
-               if (ms != 0)
-                       error = SDL_CondWaitTimeout(ring->cond, ring->mutex,
-                           ms);
-               else
-                       error = SDL_CondWait(ring->cond, ring->mutex);
-       }
-
-       /*
-        * And we know that conditional waiting functions returned with mutex
-        * locked, so now release it back.
-        */
-       (void) SDL_UnlockMutex(ring->mutex);
-
-err:
-       return error;
-}
-
-/*
- * Allows to wake up waiter(s) on the specified ring, which are sleeping
- * threads within thread_ring_wait().  This can be used to simulate the
- * arrival of a message on an empty port.  Also useful to use rings as a
- * notification system only when no message passing is needed.
- */
-int
-thread_ring_notify(thread_ring_t *ring)
-{
-
-       ASSERT(ring != NULL && ring->magic == PRING_MAGIC);
-
-       if (SDL_LockMutex(ring->mutex) != 0)
-               return -1;
-
-       ring->event = 1;
-       (void) SDL_CondSignal(ring->cond);
-
-       (void) SDL_UnlockMutex(ring->mutex);
-
-       return 0; 
-}
-
-/*
- * Allows to initialize/create a message port.
- */
-int
-thread_port_init(thread_port_t *port)
-{
-
-       ASSERT(port != NULL && port->magic != PPORT_MAGIC);
-
-       if ((port->lock = SDL_CreateMutex()) == NULL)
-               return -1;
-
-       port->magic = PPORT_MAGIC;
-       port->ring = NULL;
-       DLIST_INIT(&port->messages);
-
-       return 0;
-}
-
-/*
- * Returns TRUE if the supplied port is valid/usable, or FALSE otherwise.
- * Useful to conditionally destroy a port, for instance.
- */
-int
-thread_port_valid(thread_port_t *port)
-{
-
-       return (port != NULL && port->magic == PPORT_MAGIC);
-}
-
-/*
- * Destroys the specified port, previously created using thread_port_init().
- */
-void
-thread_port_destroy(thread_port_t *port)
-{
-
-       ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       port->magic = 0;
-       SDL_DestroyMutex(port->lock);
-}
-
-/*
- * Attaches a port to a ring.  Multiple ports may be attached to a ring.  A
- * message arriving on an empty port will cause the attached ring to be
- * notified, if any, and as such to cause a thread waiting on the ring to
- * be awakened.
- */
-void
-thread_port_set_ring(thread_port_t *port, thread_ring_t *ring)
-{
-
-       ASSERT(port != NULL && port->magic == PPORT_MAGIC &&
-           (ring == NULL || ring->magic == PRING_MAGIC));
-
-       port->ring = ring;
-}
-
-/*
- * Allows to initialize a message before it can be sent over a port.  The
- * message only needs to be initialized once in general, even if it will be
- * used for bidirectional transmission for synchronous operation.  If the
- * reply port needs to be changed, however, this function should be used again
- * to set the new reply port.
- */
-void
-thread_msg_init(thread_msg_t *msg, thread_port_t *rport)
-{
-
-       ASSERT(msg != NULL && msg->magic != PMESG_MAGIC &&
-           (rport == NULL || rport->magic == PPORT_MAGIC));
-
-       msg->magic = PMESG_MAGIC;
-       msg->reply = rport;
-}
-
-/*
- * Returns TRUE if supplied message is valid/usable or FALSE otherwise.
- */
-int
-thread_msg_valid(thread_msg_t *msg)
-{
-
-       return (msg != NULL && msg->magic == PMESG_MAGIC);
-}
-
-/*
- * Invalidates a message, so that it can no longer be sent over ports.
- */
-void
-thread_msg_destroy(thread_msg_t *msg)
-{
-
-       ASSERT(msg != NULL && msg->magic == PMESG_MAGIC);
-
-       msg->magic = 0;
-}
-
-/*
- * If any message exists in the queue of the specified port, unqueues it and
- * returns it.  Otherwise, NULL is returned.  In normal operation, all messages
- * queued to a port are processed before putting the thread back into sleep,
- * mainly for efficiency, but also because it eases synchronization.
- */
-thread_msg_t *
-thread_msg_get(thread_port_t *port)
-{
-       thread_msg_t    *msg = NULL;
-
-       ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       if (SDL_LockMutex(port->lock) != 0)
-               goto err;
-
-       if ((msg = DLIST_TOP(&port->messages)) != NULL) {
-               ASSERT(msg->magic == PMESG_MAGIC);
-               DLIST_UNLINK(&port->messages, (node_t *)msg);
-       }
-
-       (void) SDL_UnlockMutex(port->lock);
-
-err:
-       return (thread_msg_t *)msg;
-}
-
-/*
- * Queues the specified message to the specified port, returning 0 on success.
- * Note that the message data is not copied or moved, but that a pointer
- * system is used to queue the message.  Thus, the message's shared memory
- * region is leased temporarily to the other end.  One has to be careful to
- * not allocate this message space on the stack when asynchroneous operation
- * is needed.  In synchroneous operation mode, it is not a problem, since the
- * sender does not have to modify the data until the other end replies back
- * with the same message after modifying the message if necessary.  In
- * synchroneous mode, we simply delegate that message memory region to the
- * other end until it notifies us with a reply that it is done working with
- * it.  Returns 0 on success, or -1 on error.
- */
-int
-thread_msg_put(thread_port_t *port, thread_msg_t *msg)
-{
-
-       ASSERT(port != NULL && port->magic == PPORT_MAGIC &&
-           msg != NULL && msg->magic == PMESG_MAGIC);
-
-       if (SDL_LockMutex(port->lock) != 0)
-               return -1;
-
-       DLIST_APPEND(&port->messages, (node_t *)msg);
-       if (port->ring != NULL) {
-               if (DLIST_NODES(&port->messages) == 1) {
-                       /*
-                        * We know that there previously were no messages,
-                        * and that the reading thread then waits for any
-                        * message to be available.  Signal it that there at
-                        * least is one message ready.  The other end should
-                        * normally process all available messages before
-                        * going back into waiting.
-                        */
-                       if (SDL_LockMutex(port->ring->mutex) == 0) {
-                               port->ring->event = 1;
-                               (void) SDL_CondSignal(port->ring->cond);
-                               (void) SDL_UnlockMutex(port->ring->mutex);
-                       }
-               }
-       }
-
-       (void) SDL_UnlockMutex(port->lock);
-
-       return 0;
-}
-
-/*
- * Meant to be used in synchroneous message transfer mode.  The initial sender
- * sends a message to the other end, which then uses this function to notify
- * back the initial sender that it is done, often with a success/failure
- * result as part of the message.  Returns 0 on success, or -1 on error.
- */
-int
-thread_msg_reply(thread_msg_t *msg)
-{
-
-       ASSERT(msg != NULL && msg->magic == PMESG_MAGIC && msg->reply != NULL);
-
-       return thread_msg_put(msg->reply, msg);
-}
-
-/*
- * Returns the number of pending messages tied to the port, if any, or -1
- * on error.
- */
-int
-thread_port_pending(thread_port_t *port)
-{
-       int     pending = -1;
-
-       ASSERT(port != NULL && port->magic == PPORT_MAGIC);
-
-       if (SDL_LockMutex(port->lock) == 0) {
-               pending = (int)DLIST_NODES(&port->messages);
-               (void) SDL_UnlockMutex(port->lock);
-       }
-
-       return pending;
-}
-
-/*
- * Initializes the asynchroneous messages pool and mutex.  Must be called
- * before thread_amsg_create() and thread_amsg_destroy() can be used.
- * Returns 0 on success or -1 on error.
- */
-int
-thread_amsg_pool_init(void)
-{
-
-       if (pool_init(&amsg_pool, "amsg_pool", malloc, free, amsg_create,
-           amsg_destroy, sizeof(thread_amsg_t), 64, 1, 0) == -1)
-               return -1;
-
-       if ((amsg_mutex = SDL_CreateMutex()) == NULL) {
-               pool_destroy(&amsg_pool);
-               return -1;
-       }
-
-       amsg_initialized = 1;
-
-       return 0;
-}
-
-static int
-amsg_create(pnode_t *p)
-{
-
-       thread_msg_init((thread_msg_t *)p, NULL);
-
-       return 0;
-}
-
-static void
-amsg_destroy(pnode_t *p)
-{
-
-       thread_msg_destroy((thread_msg_t *)p);
-}
-
-/*
- * Creates an amsg and returns a pointer to it, or NULL on failure.
- * This is useful to efficiently create/send asynchroneous messages to
- * another thread which is expected to receive/destroy it asynchroneously
- * without replying, in which case a pool of distinct messages must be used.
- */
-thread_amsg_t *
-thread_amsg_create(void)
-{
-       thread_amsg_t   *amsg = NULL;
-
-       ASSERT(amsg_initialized);
-
-       if (SDL_LockMutex(amsg_mutex) == 0) {
-               amsg = (thread_amsg_t *)pool_alloc(&amsg_pool, 0);
-               SDL_UnlockMutex(amsg_mutex);
-       }
-
-       return amsg;
-}
-
-/*
- * Destroys an amsg previously created with thread_amsg_create().
- */
-void
-thread_amsg_destroy(thread_amsg_t *amsg)
-{
-
-       ASSERT(amsg_initialized && amsg != NULL);
-
-       if (SDL_LockMutex(amsg_mutex) == 0) {
-               (void) pool_free((pnode_t *)amsg);
-               SDL_UnlockMutex(amsg_mutex);
-       }
-}
diff --git a/tests/sdl-client/thread_msg.h b/tests/sdl-client/thread_msg.h
deleted file mode 100644 (file)
index 157cad8..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* $Id: thread_msg.h,v 1.9 2006/05/19 10:14:35 mmondor Exp $ */
-
-/*
- * Copyright (C) 2006, Matthew Mondor
- * All rights reserved.
- *
- * Adapted from older code intended for use with POSIX threads,
- * for use within SDL.
- */
-
-
-
-#ifndef THREAD_MSG_H
-#define THREAD_MSG_H
-
-
-
-#include <stdint.h>
-
-#include <SDL.h>
-#include <SDL_thread.h>
-
-#include <dlist.h>
-#include <pool.h>
-
-
-
-#define PRING_MAGIC    0x50524e47
-#define        PPORT_MAGIC     0x50505254
-#define PMESG_MAGIC    0x504d5347
-
-#define AMSG_MAXSIZE   256
-
-typedef struct {
-       uint32_t        magic;
-       SDL_cond        *cond;
-       SDL_mutex       *mutex;
-       int             event;
-} thread_ring_t;
-
-typedef struct {
-       uint32_t        magic;
-       thread_ring_t   *ring;
-       SDL_mutex       *lock;
-       list_t          messages;
-} thread_port_t;
-
-typedef struct {
-       pnode_t         node;
-       uint32_t        magic;
-       thread_port_t   *reply;
-} thread_msg_t;
-
-typedef struct {
-       thread_msg_t    msg;
-       size_t          size;
-       uint32_t        data[AMSG_MAXSIZE / 4];
-} thread_amsg_t;
-
-
-
-extern int             thread_ring_init(thread_ring_t *);
-extern int             thread_ring_valid(thread_ring_t *);
-extern void            thread_ring_destroy(thread_ring_t *);
-extern int             thread_ring_wait(thread_ring_t *, Uint32);
-extern int             thread_ring_notify(thread_ring_t *);
-
-extern int             thread_port_init(thread_port_t *);
-extern int             thread_port_valid(thread_port_t *);
-extern void            thread_port_destroy(thread_port_t *);
-extern void            thread_port_set_ring(thread_port_t *, thread_ring_t *);
-extern void            thread_msg_init(thread_msg_t *, thread_port_t *);
-extern int             thread_msg_valid(thread_msg_t *);
-extern void            thread_msg_destroy(thread_msg_t *);
-extern thread_msg_t    *thread_msg_get(thread_port_t *);
-extern int             thread_msg_put(thread_port_t *, thread_msg_t *);
-extern int             thread_msg_reply(thread_msg_t *);
-extern int             thread_port_pending(thread_port_t *);
-
-extern int             thread_amsg_pool_init(void);
-extern thread_amsg_t   *thread_amsg_create(void);
-extern void            thread_amsg_destroy(thread_amsg_t *);
-
-
-
-#endif
diff --git a/tests/sdl-client/thread_net_recv.c b/tests/sdl-client/thread_net_recv.c
deleted file mode 100644 (file)
index efa0da0..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/* $Id: thread_net_recv.c,v 1.4 2006/05/19 14:54:38 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * User events polling thread.  Reports all events to the master thread
- * via efficient inter-thread messages.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <main.h>
-#include <thread_net_recv.h>
-#include <conf.h>
-
-
-
-static void            ssend(thread_msg_t *);
-static int             state_connect(void);
-static void            state_recv(void);
-static ssize_t         server_recv(void *, size_t);
-
-
-
-static thread_ring_t   recv_ring;
-static thread_port_t   recv_port;
-
-
-
-TCPsocket              server_socket = NULL;
-
-
-
-int
-thread_net_recv(void *data)
-{
-
-       /* Initialize reply port and ring */
-       if (thread_ring_init(&recv_ring) == -1) {
-               (void) fprintf(stderr,
-                   "thread_net_recv() - thread_ring_init(recv_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if (thread_port_init(&recv_port) == -1) {
-               (void) fprintf(stderr,
-                   "thread_net_recv() - thread_port_init(recv_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       thread_port_set_ring(&recv_port, &recv_ring);
-
-       if (state_connect() == 0)
-               state_recv();
-
-       /* Wait peacefully until our process exits */
-       for (;;)
-               (void) thread_ring_wait(&recv_ring, -1);
-
-       /* NOTREACHED */
-
-       return 0;
-}
-
-/*
- * Sends a message synchroneously, that is, sends and waits for a reply.
- */
-static void
-ssend(thread_msg_t *msg)
-{
-       thread_msg_t    *rmsg;
-
-       if (thread_msg_put(&main_port, msg) == -1)
-               (void) fprintf(stderr,
-                   "ssend() - thread_msg_put()\n");
-       while ((rmsg = thread_msg_get(&recv_port)) == NULL) {
-               if (thread_ring_wait(&recv_ring, -1) != 0)
-                       (void) fprintf(stderr,
-                           "ssend() - thread_ring_wait()\n");
-       }
-}
-
-/*
- * Attempts to connect to server.  On success, 0 is returned and a success
- * reply packet is sent synchroneously to the main thread.  On error, a
- * failure packet is sent instead and we return -1.
- */
-static int
-state_connect(void)
-{
-       struct msg_connect      msg;
-       IPaddress               addr;
-
-       thread_msg_init(&msg.msg, &recv_port);
-       msg.status = 0;
-       msg.error = NULL;
-
-       if (SDLNet_ResolveHost(&addr, SERVER_HOST, SERVER_PORT) != 0) {
-               msg.status = -1;
-               msg.error = "Could not resolve server hostname";
-               goto end;
-       }
-
-       if ((server_socket = SDLNet_TCP_Open(&addr)) == NULL) {
-               msg.status = -1;
-               msg.error = "Could not connect to server";
-       }
-
-end:
-       ssend(&msg.msg);
-
-       return 0;
-}
-
-/*
- * We endlessly read packets from the server and queue them asynchroneously to
- * the main thread's port, unless a read error occurs, in which case we queue
- * an empty/error special packet and return.
- */
-static void
-state_recv(void)
-{
-       thread_amsg_t   *amsg = NULL;
-
-       for (;;) {
-               uint8_t type, length;
-
-               /*
-                * We must already have an allocated message since we'll read
-                * data directly into its buffer.  If this operation fails,
-                * it's fatal since the receiving main thread will never be
-                * notified.
-                */
-               if ((amsg = thread_amsg_create()) == NULL) {
-                       (void) fprintf(stderr,
-                           "state_recv() - thread_amsg_create()\n");
-                       exit(EXIT_FAILURE);
-               }
-
-               /*
-                * Start reading a single byte, the message type, and evaluate
-                * the message size.  For variable packets, we also must read
-                * another byte for the legth.  Then read the remaining of the
-                * message.  On any invalid message, we error and stop as if
-                * the connection had problems, but we log it.  Upon
-                * successful reception of a complete message, directly
-                * transmit it to the main thread asynchroneously and
-                * continue for another packet.  These read operations are
-                * blocking automatically when no data is available to read.
-                */
-               if (server_recv(amsg->data, 16) == -1)
-                       break;
-               type = *(amsg->data);
-
-               /* XXX */
-               amsg->size = 16;
-
-               /* Valid fixed length packet type?  If so, set length */
-               /* Valid variable length packet type?  Obtain length */
-
-               /* Read remaining of packet */
-
-               /* Asynchroneously send packet to the main thread */
-               (void) thread_msg_put(&main_port, &amsg->msg);
-       }
-
-       /* Send the end of stream message to the main thread */
-       amsg->size = -1;
-       (void) thread_msg_put(&main_port, &amsg->msg);
-}
-
-static ssize_t
-server_recv(void *data, size_t size)
-{
-       size_t  len;
-       int     res;
-
-       for (len = 0; len < size; len += res) {
-               if ((res = SDLNet_TCP_Recv(server_socket, data + len,
-                   size - len)) < 1)
-                       return -1;
-       }
-
-       return len;
-}
diff --git a/tests/sdl-client/thread_net_recv.h b/tests/sdl-client/thread_net_recv.h
deleted file mode 100644 (file)
index 7a977e2..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* $Id: thread_net_recv.h,v 1.1 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * User events polling thread.  Reports all events to the master thread
- * via efficient inter-thread messages.
- */
-
-
-
-#ifndef THREAD_NET_RECV_H
-#define THREAD_NET_RECV_H
-
-
-
-#include <SDL.h>
-#include <SDL_net.h>
-
-#include <thread_msg.h>
-
-
-
-/*
- * The initial message we're waiting for from the read thread.  The read
- * thread will attempt to connect to the server, initiate authentication and
- * then reply using this message with the connection status.  Afterwards, we
- * only expect msg_read packets from that thread.
- * <status> will be 0 on success or -1 on failure, in which case the error
- * message string will be found into <error>.
- */
-struct msg_connect {
-       thread_msg_t    msg;
-       int             status;
-       const char      *error;
-};
-
-/*
- * We receive such a message when a packet was successfully read from the
- * server.  We reply in a synchroneous manner, however the reply delay should
- * be very short compared to the possible delay of the read thread during a
- * blocking read (SDL_net does not support non-blocking I/O operations).
- * If -1 is received for the <data> size, with a NULL <data> pointer, it means
- * that the connection status was lost or that a timeout occurred.
- */
-struct msg_recv {
-       thread_msg_t    msg;
-       void            *data;
-       size_t          size;
-};
-
-
-
-int                    thread_net_recv(void *);
-
-
-
-extern TCPsocket       server_socket;
-
-
-
-#endif
diff --git a/tests/sdl-client/thread_net_send.c b/tests/sdl-client/thread_net_send.c
deleted file mode 100644 (file)
index 4fe7e21..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Id: thread_net_send.c,v 1.1 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Server socket writing thread.  We post all asynchroneous messages
- * (thread_amsg_t) we receive from the main thread to the server socket.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <thread_net_send.h>
-#include <thread_net_recv.h>
-
-
-
-static thread_ring_t   send_ring;
-
-
-
-thread_port_t          send_port;
-
-
-
-int
-thread_net_send(void *data)
-{
-       thread_amsg_t   *amsg;
-
-       /* Initialize reply port and ring */
-       if (thread_ring_init(&send_ring) == -1) {
-               (void) fprintf(stderr,
-                   "thread_net_recv() - thread_ring_init(send_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       if (thread_port_init(&send_port) == -1) {
-               (void) fprintf(stderr,
-                   "thread_net_send() - thread_port_init(send_port) - %s\n",
-                   SDL_GetError());
-               exit(EXIT_FAILURE);
-       }
-       thread_port_set_ring(&send_port, &send_ring);
-
-       /*
-        * Simply process all incomming messages, sending their data to
-        * the server port, and discarding the messages.  When the port is
-        * empty, wait polling until messages become available.
-        */
-       for (;;) {
-               while ((amsg = (thread_amsg_t *)thread_msg_get(&send_port))
-                      != NULL) {
-                       if (SDLNet_TCP_Send(server_socket,
-                           amsg->data, amsg->size) != amsg->size)
-                               (void) fprintf(stderr,
-                                   "Error writing to server socket\n");
-                       thread_amsg_destroy(amsg);
-               }
-               (void) thread_ring_wait(&send_ring, -1);
-       }
-
-       /* NOTREACHED */
-
-       return 0;
-}
diff --git a/tests/sdl-client/thread_net_send.h b/tests/sdl-client/thread_net_send.h
deleted file mode 100644 (file)
index f1ae02f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* $Id: thread_net_send.h,v 1.1 2006/05/19 09:13:42 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-/*
- * Server socket writing thread.  We post all asynchroneous messages
- * (thread_amsg_t) we receive from the main thread to the server socket.
- */
-
-
-
-#ifndef THREAD_NET_SEND_H
-#define THREAD_NET_SEND_H
-
-
-
-#include <SDL.h>
-#include <SDL_net.h>
-
-#include <thread_msg.h>
-
-
-
-int                    thread_net_send(void *);
-
-
-
-extern thread_port_t   send_port;
-
-
-
-#endif
diff --git a/tests/sdl-client/wav/README b/tests/sdl-client/wav/README
deleted file mode 100644 (file)
index 8c7a92a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-For now these have been borrowed from the netrekxp client.
diff --git a/tests/sdl-client/wav/nt_cloaked.wav b/tests/sdl-client/wav/nt_cloaked.wav
deleted file mode 100755 (executable)
index 3e010dd..0000000
Binary files a/tests/sdl-client/wav/nt_cloaked.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_explosion_other.wav b/tests/sdl-client/wav/nt_explosion_other.wav
deleted file mode 100755 (executable)
index b7ba8cb..0000000
Binary files a/tests/sdl-client/wav/nt_explosion_other.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_fire_torp_other.wav b/tests/sdl-client/wav/nt_fire_torp_other.wav
deleted file mode 100755 (executable)
index dddf2c6..0000000
Binary files a/tests/sdl-client/wav/nt_fire_torp_other.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_plasma_hit.wav b/tests/sdl-client/wav/nt_plasma_hit.wav
deleted file mode 100755 (executable)
index 73ecd7c..0000000
Binary files a/tests/sdl-client/wav/nt_plasma_hit.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_shield_down.wav b/tests/sdl-client/wav/nt_shield_down.wav
deleted file mode 100755 (executable)
index 0888f08..0000000
Binary files a/tests/sdl-client/wav/nt_shield_down.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_shield_up.wav b/tests/sdl-client/wav/nt_shield_up.wav
deleted file mode 100755 (executable)
index 909f72c..0000000
Binary files a/tests/sdl-client/wav/nt_shield_up.wav and /dev/null differ
diff --git a/tests/sdl-client/wav/nt_uncloak.wav b/tests/sdl-client/wav/nt_uncloak.wav
deleted file mode 100755 (executable)
index e4df979..0000000
Binary files a/tests/sdl-client/wav/nt_uncloak.wav and /dev/null differ
diff --git a/tests/zlib/README b/tests/zlib/README
deleted file mode 100644 (file)
index aa38152..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-$Id: README,v 1.1 2006/06/15 14:23:24 mmondor Exp $
-
-Simple zlib compression/decompression tests.
diff --git a/tests/zlib/deflate.c b/tests/zlib/deflate.c
deleted file mode 100644 (file)
index 7eff3e4..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* $Id: deflate.c,v 1.1 2006/06/15 14:23:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <zlib.h>
-
-
-
-#define RBUF_SIZE      4096
-#define DBUF_SIZE      (RBUF_SIZE * 2)
-
-
-
-int    main(void);
-
-
-
-int
-main(void)
-{
-       z_stream        s;
-       char            rbuf[RBUF_SIZE], dbuf[DBUF_SIZE];
-       size_t          size;
-
-       if (setvbuf(stdin, NULL, _IONBF, 0) == EOF)
-               perror("setvbuf(stdin)");
-       if (setvbuf(stdout, NULL, _IONBF, 0) == EOF)
-               perror("setvbuf(stdout)");
-
-       s.next_in = s.next_out = NULL;
-       s.avail_in = s.avail_out = 0;
-       s.zalloc = NULL;
-       s.zfree = NULL;
-       s.opaque = NULL;
-
-       if (deflateInit(&s, Z_DEFAULT_COMPRESSION) != Z_OK) {
-               perror("deflateInit()");
-               exit(EXIT_FAILURE);
-       }
-
-       while (!feof(stdin) && !ferror(stdin)) {
-               if ((size = fread(rbuf, 1, RBUF_SIZE, stdin)) < 1)
-                       continue;
-               s.next_in = rbuf;
-               s.avail_in = size;
-               s.next_out = dbuf;
-               s.avail_out = DBUF_SIZE;
-               if (deflate(&s, Z_NO_FLUSH/*Z_SYNC_FLUSH*/) != Z_OK) {
-                       perror("deflate()");
-                       exit(EXIT_FAILURE);
-               }
-               if (fwrite(dbuf, 1, DBUF_SIZE - s.avail_out, stdout)
-                   != DBUF_SIZE - s.avail_out) {
-                       perror("fwrite()");
-                       exit(EXIT_FAILURE);
-               }
-       }
-
-       s.next_in = rbuf;
-       s.avail_in = 0;
-       s.next_out = dbuf;
-       s.avail_out = DBUF_SIZE;
-       if (deflate(&s, Z_FINISH) != Z_STREAM_END) {
-               perror("deflate()");
-               exit(EXIT_FAILURE);
-       }
-       if (fwrite(dbuf, 1, DBUF_SIZE - s.avail_out, stdout)
-           != DBUF_SIZE - s.avail_out) {
-               perror("fwrite()");
-               exit(EXIT_FAILURE);
-       }
-
-       if (deflateEnd(&s) != Z_OK) {
-               perror("deflateEnd()");
-               exit(EXIT_FAILURE);
-       }
-
-       exit(feof(stdin) ? EXIT_SUCCESS : EXIT_FAILURE);
-}
diff --git a/tests/zlib/inflate.c b/tests/zlib/inflate.c
deleted file mode 100644 (file)
index 59b807b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $Id: inflate.c,v 1.1 2006/06/15 14:23:24 mmondor Exp $ */
-
-/*
- * Copyright (c) 2006, Matthew Mondor
- * ALL RIGHTS RESERVED.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <zlib.h>
-
-
-
-#define RBUF_SIZE      4096
-#define IBUF_SIZE      (RBUF_SIZE * 64)
-
-
-
-int    main(void);
-
-
-
-int
-main(void)
-{
-       z_stream        s;
-       char            rbuf[RBUF_SIZE], ibuf[IBUF_SIZE];
-       size_t          size;
-       int             ret;
-
-       if (setvbuf(stdin, NULL, _IONBF, 0) == EOF)
-               perror("setvbuf(stdin)");
-       if (setvbuf(stdout, NULL, _IONBF, 0) == EOF)
-               perror("setvbuf(stdout)");
-
-       s.next_in = s.next_out = NULL;
-       s.avail_in = s.avail_out = 0;
-       s.zalloc = NULL;
-       s.zfree = NULL;
-       s.opaque = NULL;
-
-       if (inflateInit(&s) != Z_OK) {
-               perror("inflateInit()");
-               exit(EXIT_FAILURE);
-       }
-
-       while (!feof(stdin) && !ferror(stdin)) {
-               if ((size = fread(rbuf, 1, RBUF_SIZE, stdin)) < 1)
-                       continue;
-               s.next_in = rbuf;
-               s.avail_in = size;
-               s.next_out = ibuf;
-               s.avail_out = IBUF_SIZE;
-               if ((ret = inflate(&s, Z_SYNC_FLUSH)) != Z_OK &&
-                   ret != Z_STREAM_END) {
-                       perror("inflate()");
-                       exit(EXIT_FAILURE);
-               }
-               if (fwrite(ibuf, 1, IBUF_SIZE - s.avail_out, stdout)
-                   != IBUF_SIZE - s.avail_out) {
-                       perror("fwrite()");
-                       exit(EXIT_FAILURE);
-               }
-               if (ret == Z_STREAM_END)
-                       break;
-       }
-
-       s.next_in = rbuf;
-       s.avail_in = 0;
-       s.next_out = ibuf;
-       s.avail_out = IBUF_SIZE;
-       if (inflate(&s, Z_FINISH) != Z_STREAM_END) {
-               perror("inflate()");
-               exit(EXIT_FAILURE);
-       }
-       if (fwrite(ibuf, 1, IBUF_SIZE - s.avail_out, stdout)
-           != IBUF_SIZE - s.avail_out) {
-               perror("fwrite()");
-               exit(EXIT_FAILURE);
-       }
-
-       if (inflateEnd(&s) != Z_OK) {
-               perror("inflateEnd()");
-               exit(EXIT_FAILURE);
-       }
-
-       exit(feof(stdin) ? EXIT_SUCCESS : EXIT_FAILURE);
-}