Fixed up a few small bugs in the syscall_server stuff
authorKevin Klues <klueska@cs.berkeley.edu>
Tue, 6 Oct 2009 00:08:10 +0000 (02:08 +0200)
committerKevin Klues <klueska@cs.berkeley.edu>
Tue, 6 Oct 2009 02:04:10 +0000 (04:04 +0200)
Additionally, I added a Makefile under tools/newlib that will go through the process of downloading newlib, compiling it, and installing it for use in ROS.

Also, there is now a completely UNTESTED hashtabel implementation in kern/src

13 files changed:
kern/include/hashtable.h [new file with mode: 0644]
kern/include/hashtable_itr.h [new file with mode: 0644]
kern/include/kmalloc.h
kern/src/Makefrag
kern/src/hashtable.c [new file with mode: 0644]
kern/src/hashtable_itr.c [new file with mode: 0644]
kern/src/kmalloc.c
tools/newlib/Makefile [new file with mode: 0644]
tools/syscall_server/Makefile
tools/syscall_server/newlib_trans.c
tools/syscall_server/syscall_server.c
tools/syscall_server/syscall_server.h
user/apps/parlib/run_binary.c

diff --git a/kern/include/hashtable.h b/kern/include/hashtable.h
new file mode 100644 (file)
index 0000000..3e99667
--- /dev/null
@@ -0,0 +1,226 @@
+/* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __ROS_KERN_HASHTABLE_H__
+#define __ROS_KERN_HASHTABLE_H__
+
+#include <ros/common.h>
+
+/*****************************************************************************/
+typedef struct hash_entry
+{
+    void *k, *v;
+    size_t h;
+    struct hash_entry *next;
+} hash_entry_t;
+
+typedef struct hashtable {
+    size_t tablelength;
+    hash_entry_t **table;
+    size_t entrycount;
+    size_t loadlimit;
+    size_t primeindex;
+    size_t (*hashfn) (void *k);
+    ssize_t (*eqfn) (void *k1, void *k2);
+} hashtable_t;
+
+size_t hash(struct hashtable *h, void *k);
+static inline size_t indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+       return (hashvalue % tablelength);
+};
+#define freekey(X) kfree(X)
+
+/*****************************************************************************/
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static size_t         hash_from_key_fn( void *k );
+ *      static ssize_t        keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     kmalloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   kmalloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     panic("Hashtable broken...\n");       }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printk("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printk("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+hashtable_t *
+create_hashtable(size_t minsize,
+                 size_t (*hashfunction) (void*),
+                 ssize_t (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+ssize_t 
+hashtable_insert(hashtable_t *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+ssize_t fnname (hashtable_t *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(hashtable_t *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (hashtable_t *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(hashtable_t *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (hashtable_t *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+size_t
+hashtable_count(hashtable_t *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(hashtable_t *h, int free_values);
+
+#endif /* __ROS_KERN_HASHTABLE_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * 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.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+ * 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.
+*/
diff --git a/kern/include/hashtable_itr.h b/kern/include/hashtable_itr.h
new file mode 100644 (file)
index 0000000..c0946bd
--- /dev/null
@@ -0,0 +1,110 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#ifndef __ROS_KERN_HASHTABLE_ITR_H__
+#define ___ROS_KERN_HASHTABLE_ITR_H__
+
+#include <hashtable.h>
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+typedef struct hashtable_itr {
+    hashtable_t *h;
+    hash_entry_t *e;
+    hash_entry_t *parent;
+    size_t index;
+} hashtable_itr_t;
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+hashtable_itr_t *
+hashtable_iterator(hashtable_t *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(hashtable_itr_t *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(hashtable_itr_t *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+ssize_t
+hashtable_iterator_advance(hashtable_itr_t *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+ssize_t
+hashtable_iterator_remove(hashtable_itr_t *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+ssize_t
+hashtable_iterator_search(hashtable_itr_t *itr,
+                          hashtable_t *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+ssize_t fnname (hashtable_itr_t *i, hashtable_t *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+
+#endif /* __ROS_KERN_HASHTABLE_ITR_H__*/
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * 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.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+ * 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.
+*/
index 90b3edd..2aa7171 100644 (file)
@@ -16,6 +16,7 @@ void* (DALLOC(n) boot_alloc)(uint32_t n, uint32_t align);
 void* (DALLOC(_n*sz) boot_calloc)(uint32_t _n, size_t sz, uint32_t align);
 
 void* (DALLOC(size) kmalloc)(size_t size, int flags);
+void* (DALLOC(size) krealloc)(void* buf, size_t size, int flags);
 void  (DFREE(addr) kfree)(void *addr);
 
 #endif //ROS_KERN_KMALLOC_H
index 48ca3e4..ae700cf 100644 (file)
@@ -37,6 +37,8 @@ KERN_SRCFILES := $(KERN_ARCH_SRCFILES) \
                  $(KERN_SRC_DIR)/kfs.c \
                  $(KERN_SRC_DIR)/process.c \
                  $(KERN_SRC_DIR)/kmalloc.c \
+                 $(KERN_SRC_DIR)/hashtable.c \
+                 $(KERN_SRC_DIR)/hashtable_itr.c \
                  $(KERN_SRC_DIR)/schedule.c \
                  $(KERN_SRC_DIR)/testing.c
 
diff --git a/kern/src/hashtable.c b/kern/src/hashtable.c
new file mode 100644 (file)
index 0000000..4e828b5
--- /dev/null
@@ -0,0 +1,275 @@
+/* Copyright (C) 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
+
+#include <ros/common.h>
+#include <hashtable.h>
+#include <stdio.h>
+#include <string.h>
+#include <kmalloc.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+#define APPLY_MAX_LOAD_FACTOR(size) \
+    ((size * 13)/20)
+//const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+hashtable_t *
+create_hashtable(size_t minsize,
+                 size_t (*hashf) (void*),
+                 ssize_t (*eqf) (void*,void*))
+{
+    hashtable_t *h;
+    size_t pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (hashtable_t *)kmalloc(sizeof(hashtable_t), 0);
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * size, 0);
+    if (NULL == h->table) { kfree(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(hash_entry_t *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = APPLY_MAX_LOAD_FACTOR(size);
+    return h;
+}
+
+/*****************************************************************************/
+size_t
+hash(hashtable_t *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    size_t i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static ssize_t
+hashtable_expand(hashtable_t *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    hash_entry_t **newtable;
+    hash_entry_t *e;
+    hash_entry_t **pE;
+    size_t newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (hash_entry_t **)kmalloc(sizeof(hash_entry_t*) * newsize, 0);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(hash_entry_t*));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        kfree(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (hash_entry_t**)
+                   krealloc(h->table, newsize*sizeof(hash_entry_t*), 0);
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = APPLY_MAX_LOAD_FACTOR(newsize);
+    return -1;
+}
+
+/*****************************************************************************/
+size_t
+hashtable_count(hashtable_t *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+ssize_t
+hashtable_insert(hashtable_t *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    size_t index;
+    hash_entry_t *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (hash_entry_t *)kmalloc(sizeof(hash_entry_t), 0);
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(hashtable_t *h, void *k)
+{
+    hash_entry_t *e;
+    size_t hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(hashtable_t *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    hash_entry_t *e;
+    hash_entry_t **pE;
+    void *v;
+    size_t hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            kfree(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(hashtable_t *h, int free_values)
+{
+    size_t i;
+    hash_entry_t *e, *f;
+    hash_entry_t **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); kfree(f->v); kfree(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); kfree(f); }
+        }
+    }
+    kfree(h->table);
+    kfree(h);
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * 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.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+ * 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.
+*/
diff --git a/kern/src/hashtable_itr.c b/kern/src/hashtable_itr.c
new file mode 100644 (file)
index 0000000..6ee77d5
--- /dev/null
@@ -0,0 +1,188 @@
+/* Copyright (C) 2002, 2004 Christopher Clark  <firstname.lastname@cl.cam.ac.uk> */
+
+#include <ros/common.h>
+#include <kmalloc.h>
+#include <hashtable.h>
+#include <hashtable_itr.h>
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+hashtable_itr_t *
+hashtable_iterator(hashtable_t *h)
+{
+    size_t i, tablelength;
+    hashtable_itr_t *itr = (hashtable_itr_t *)
+        kmalloc(sizeof(hashtable_itr_t), 0);
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* key      - return the key of the (key,value) pair at the current position */
+/* value    - return the value of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_key(hashtable_itr_t *i)
+{ return i->e->k; }
+
+void *
+hashtable_iterator_value(hashtable_itr_t *i)
+{ return i->e->v; }
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+ssize_t
+hashtable_iterator_advance(hashtable_itr_t *itr)
+{
+    size_t j,tablelength;
+    hash_entry_t **table;
+    hash_entry_t *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+ssize_t
+hashtable_iterator_remove(hashtable_itr_t *itr)
+{
+    hash_entry_t *remember_e, *remember_parent;
+    ssize_t ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    kfree(remember_e);
+    return ret;
+}
+
+/*****************************************************************************/
+ssize_t /* returns zero if not found */
+hashtable_iterator_search(hashtable_itr_t *itr,
+                          hashtable_t *h, void *k)
+{
+    hash_entry_t *e, *parent;
+    size_t hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            return -1;
+        }
+        parent = e;
+        e = e->next;
+    }
+    return 0;
+}
+
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * 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.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+ * 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.
+*/
index 93cd003..cd08c27 100644 (file)
@@ -144,6 +144,11 @@ void* kmalloc(size_t size, int flags)
        return ppn2kva(first);
 }
 
+void* krealloc(void* buf, size_t size, int flags) {
+       kfree(buf);
+       return kmalloc(size, flags);
+}
+
 void kfree(void *addr)
 {
        kmallocdebug("incoming address: %p\n", addr);
diff --git a/tools/newlib/Makefile b/tools/newlib/Makefile
new file mode 100644 (file)
index 0000000..504ba43
--- /dev/null
@@ -0,0 +1,41 @@
+SRC_DIR=$(shell pwd)/../../
+INSTALL_DIR=$(SRC_DIR)/user/parlib/newlib
+PACKAGE = newlib-1.17.0
+PACKAGE_TAR = $(PACKAGE).tar.gz
+
+KEVINS_CFLAGS= "-U__linux__ -U__linux -U__gnu_linux__ \
+                -fno-stack-protector -m32"
+OPTIONS=--build=i386 --target=i386 --with-newlib --disable-shared --prefix=$(INSTALL_DIR)
+KEVINS_LDFLAGS="-nostdlib"
+
+all: build         
+
+build:$(PACKAGE_TAR)
+       export KEVINS_CFLAGS=$(KEVINS_CFLAGS); \
+       export KEVINS_LDFLAGS=$(KEVINS_LDFLAGS); \
+       cd $(PACKAGE)/newlib; \
+       cat configure | sed 's/@CFLAGS@,$$CFLAGS,/@CFLAGS@,$$KEVINS_CFLAGS,/' \
+                 | sed 's/@LDFLAGS@,$$LDFLAGS,/@LDFLAGS@,$$KEVINS_LDFLAGS,/' \
+                                  > configure.tmp; \
+       mv configure.tmp configure; \
+       chmod a+x configure; \
+       ./configure $(OPTIONS); \
+       make; \
+       cd doc; \
+       make;
+
+$(PACKAGE_TAR):
+       wget ftp://sources.redhat.com/pub/newlib/$(PACKAGE_TAR);
+       tar -zxvf newlib-1.17.0.tar.gz; \
+
+install:
+       cd newlib-1.17.0/newlib; \
+       make install; \
+       cd $(INSTALL_DIR)/lib; \
+       mkdir -p i386; \
+       mv lib* i386;
+
+clean:
+       rm -rf newlib-1.17.0.tar.gz; \
+       rm -rf newlib-1.17.0; \
+        
index 7c2e3c7..70322bc 100644 (file)
@@ -1,3 +1,4 @@
+#CC = ivycc --deputy
 CFLAGS += -I.
 V = @
 
index c60a97f..fd84642 100644 (file)
@@ -95,7 +95,7 @@ int translate_mode(int newlib_mode) {
        return native_mode;     
 }
 int translate_whence(int newlib_whence) {
-       int native_whence;
+       int native_whence = 0;
        if (newlib_whence == NEWLIB_SEEK_SET)
                native_whence = SEEK_SET;
        else if (newlib_whence == NEWLIB_SEEK_CUR)
index 25ed62b..73b9b1a 100644 (file)
@@ -46,7 +46,7 @@ void run_server()
                debug("Writing response: %d\n", syscall_req.header.id);
                write_syscall_rsp(fd_write, &syscall_rsp);
 
-               if(syscall_req.payload != NULL)
+               if(syscall_req.payload != NULL) 
                        free(syscall_req.payload);
                if(syscall_rsp.payload != NULL)
                        free(syscall_rsp.payload);
@@ -194,7 +194,8 @@ void write_syscall_rsp(int fd, syscall_rsp_t* rsp)
 
 void write_syscall_rsp_header(int fd, syscall_rsp_t* rsp) 
 {
-       int written = write_syscall_server(fd, &rsp->header, sizeof(syscall_rsp_header_t), rsp->payload_len);
+       int written = write_syscall_server(fd, (char*)&rsp->header, 
+                          sizeof(syscall_rsp_header_t), rsp->payload_len);
        if (written < 0)
                error(fd, "Problems writing the syscall response header...");   
 }
@@ -212,7 +213,9 @@ void write_syscall_rsp_payload(int fd, syscall_rsp_t* rsp)
 }
 
 char* sandbox_file_name(char* name, uint32_t len) {
-       char* new_name = malloc(len + strnlen(SANDBOX_DIR));
+       char* new_name = malloc(len + sizeof(SANDBOX_DIR) - 1);
+       if (new_name == NULL) 
+               perror("No free memory!");
        sprintf(new_name, "%s%s", SANDBOX_DIR, name);
        printf("%s\n", new_name);
        return new_name;
@@ -238,6 +241,8 @@ void handle_read(syscall_req_t* req, syscall_rsp_t* rsp)
 {
        read_subheader_t* r = &req->header.subheader.read;      
        rsp->payload = malloc(r->len);
+       if (rsp->payload == NULL) 
+               perror("No free memory!");
        rsp->header.return_val = read(r->fd, rsp->payload, r->len);
        if(rsp->header.return_val >= 0)
                rsp->payload_len = rsp->header.return_val;
@@ -278,6 +283,8 @@ void handle_fstat(syscall_req_t* req, syscall_rsp_t* rsp)
        struct stat native_struct;
        fstat_subheader_t* f = &req->header.subheader.fstat;    
        rsp->payload = malloc(sizeof(newlib_stat_t));
+       if (rsp->payload == NULL) 
+               perror("No free memory!");
        rsp->header.return_val = fstat(f->fd, &native_struct); 
        if(rsp->header.return_val >= 0)
                rsp->payload_len = sizeof(newlib_stat_t);
@@ -295,6 +302,8 @@ void handle_stat(syscall_req_t* req, syscall_rsp_t* rsp)
 {
        struct stat native_struct;
        rsp->payload = malloc(sizeof(newlib_stat_t));
+       if (rsp->payload == NULL) 
+               perror("No free memory!");
        rsp->header.return_val = stat(req->payload, &native_struct); 
        if(rsp->header.return_val >= 0)
                rsp->payload_len = sizeof(newlib_stat_t);
index 68ed685..790d135 100644 (file)
@@ -115,6 +115,7 @@ typedef struct syscall_rsp {
 } syscall_rsp_t;
 
 void run_server();
+int init_syscall_server(int* fd_read, int* fd_write);
 void translate_stat(struct stat* native, struct newlib_stat* newlib);
 int translate_flags(int native_flags);
 int translate_mode(int native_mode);
@@ -127,7 +128,8 @@ void read_syscall_req_payload(int fd, syscall_req_t* req);
 void write_syscall_rsp(int fd, syscall_rsp_t* rsp);
 void write_syscall_rsp_header(int fd, syscall_rsp_t* rsp);
 void write_syscall_rsp_payload(int fd, syscall_rsp_t* rsp);
-int read_from_channel(int fd, void* buf, int len, int peek); 
+int read_syscall_server(int fd, char* buf, int len);
+int write_syscall_server(int fd, char* buf, int len, int bytes_to_follow); 
 void error(int fd, const char* s);
 char* sandbox_file_name(char* name, uint32_t len);
 
index 3904367..5f4e159 100644 (file)
@@ -40,10 +40,10 @@ void run_binary()
                printf("Error reading from console.\n");
                return;
        }
-
        char * file_name = malloc(strlen(readline_result) + 8);
        sprintf(file_name, "./apps/%s", readline_result);
        int fd = open(file_name, O_RDONLY, 0);
+       free(file_name);
        if(fd < 0) { fd_error(); return; };
        
        int iters = 1;
@@ -69,6 +69,5 @@ void run_binary()
        }
        free(binary_buf);
        close(fd);
-
 }