diff -NaurbB rtlinux-3.2-pre2.old/include/rtl_malloc.h rtlinux-3.2-pre2/include/rtl_malloc.h --- rtlinux-3.2-pre2.old/include/rtl_malloc.h 1970-01-01 01:00:00.000000000 +0100 +++ rtlinux-3.2-pre2/include/rtl_malloc.h 2003-07-17 11:28:45.000000000 +0200 @@ -0,0 +1,155 @@ +/* + * Doubly indexed dynamic memory allocator (DIDMA) + * Version 1.0 + * + * Written by Miguel Masmano Tello + * Copyright (C) Dec, 2002 OCERA Consortium + * Release under the terms of the GNU General Public License Version 2 + * + */ + +#ifndef _DOUBLY_INDEXED_MALLOC_H_ +#define _DOUBLY_INDEXED_MALLOC_H_ + + +/*------------------------------------------------------------------------*/ +/******************************/ +/* CONFIGURATION PARAMETERS */ +/******************************/ + +// The following parameters allows to tune DIDMA + +/* DIDMA_PREF defines the prefix + used by all DIDMA functions */ +// #define WITH_RTL_PREFIX + +/* + * MAX_FL_INDEX defines the maximum first index which + * will be used by DIDMA. The maximum first index is + * calculated in the init_memory_pool (size) + * + * if (log2 (size) <= MAX_FL_INDEX) then + * max_fl_index := log2 (size); + * else + * max_fl_index := MAX_FL_INDEX; + * end if; + * + */ + +#define MAX_FL_INDEX 24 // DIDMA default MAX_FL_INDEX is 16 MBytes + +/*------------------------------------------------------------------------*/ + +#if defined(__KERNEL__) && !defined(__RTL__) +#error "This modules can only be used in RTLinux or user space" +#endif + +#include + +#ifdef __RTL__ + +/* RTLinux module */ + +#include + +#define PRINT_MSG rtl_printf +#define PRINT_DBG_C(message) rtl_printf(message) +#define PRINT_DBG_D(message) rtl_printf("%i", message); +//#define PRINT_DBG_F(message) rtl_printf("%f", message); +#define PRINT_DBG_H(message) rtl_printf("%x", message); + +#else + +/* User space */ + +#include +#define PRINT_MSG printf +#define PRINT_DBG_C(message) printf(message) +#define PRINT_DBG_D(message) printf("%i", message); +#define PRINT_DBG_F(message) printf("%f", message); +#define PRINT_DBG_H(message) printf("%x", message); + +#endif + +extern char *main_buffer; // This buffer is associated with + // a block of memory by the user + +/* + * associate buffer allows to indicate to DIDMA that one specific + * buffer must be used by default, this allow to the user to use + * malloc, free, calloc and realloc functions + */ + +#define associate_buffer(ptr) main_buffer = (char *) ptr; + +/* + * max_sl_log2_index defines the maximum second index which will be + * used by DIDMA. + * + * max_sl_log2_index allows to the user to tune the maximum internal + * fragmentation, but a high max_sl_log2_index value will cause big + * DIDMA structure. + * + * max_sl_log2_index max. internal fragmentation (approximately) + * ----------------- ------------------------------------------- + * 1 25 % + * 2 12.5 % + * 3 6.25 % + * 4 3.125 % + * 5 1.563 % + */ + +// max_size is in Kbytes +int init_memory_pool (int max_size, + int max_sl_log2_index, char *block_ptr); + +void destroy_memory_pool (char *block_ptr); + +/* see man malloc */ +#ifdef WITH_RTL_PREFIX +#define rtl_malloc(size) rtl_malloc_ex (size, main_buffer); +void *rtl_malloc_ex (size_t size, char *block_ptr); +#else +#define malloc(size) malloc_ex (size, main_buffer); +void *malloc_ex (size_t size, char *block_ptr); +#endif + +/* see man realloc */ +#ifdef WITH_RTL_PREFIX +#define rtl_realloc(p, new_len) rtl_realloc_ex (p, new_len, main_buffer); +void *rtl_realloc_ex (void *p, size_t new_len, char *block_ptr); +#else +#define realloc(p, new_len) realloc_ex (p, new_len, main_buffer); +void *realloc_ex (void *p, size_t new_len, char *block_ptr); +#endif + +/* see man calloc */ +#ifdef WITH_RTL_PREFIX +#define rtl_calloc(nelem, elem_size) \ +rtl_calloc_ex (nelem, elem_size, main_buffer); +void *rtl_calloc_ex (size_t nelem, size_t elem_size, char *block_ptr); +#else +#define calloc(nelem, elem_size) \ +calloc_ex (nelem, elem_size, main_buffer); +void *calloc_ex (size_t nelem, size_t elem_size, char *block_ptr); +#endif + +/* + * see man free + * + * free () is only guaranteed to work if ptr is the address + * of a block allocated by rt_malloc() (and not yet freed). + */ + +#ifdef WITH_RTL_PREFIX +#define rtl_free(ptr) rtl_free_ex (ptr, main_buffer); +void rtl_free_ex (void *ptr, char *block_ptr); +#else +#define free(ptr) free_ex (ptr, main_buffer); +void free_ex (void *ptr, char *block_ptr); +#endif + +void free_blocks_status (char *block_ptr); +void structure_status (char *block_ptr); + +#endif // #ifndef _DOUBLY_INDEXED_MALLOC_H_ diff -NaurbB rtlinux-3.2-pre2.old/include/rtl_signal.h rtlinux-3.2-pre2/include/rtl_signal.h --- rtlinux-3.2-pre2.old/include/rtl_signal.h 2003-03-12 17:35:16.000000000 +0100 +++ rtlinux-3.2-pre2/include/rtl_signal.h 2003-07-17 11:28:55.000000000 +0200 @@ -11,7 +11,18 @@ #define RTL_SIGUSR1 (RTL_SIGNAL_READY+1) #define RTL_SIGUSR2 (RTL_SIGUSR1+1) -#define RTL_SIGRTMIN (RTL_SIGUSR2+1) + +/* + * Trap and fault signals + * Added by Miguel Masmano + */ +#define RTL_SIGFPE (RTL_SIGUSR2+1) +#define RTL_SIGTRAP (RTL_SIGUSR2+2) +#define RTL_SIGSEGV (RTL_SIGUSR2+3) +#define RTL_SIGILL (RTL_SIGUSR2+4) +#define RTL_SIGBUS (RTL_SIGUSR2+5) +#define RTL_SIGHUP (RTL_SIGUSR2+6) +#define RTL_SIGRTMIN (RTL_SIGUSR2+7) #define RTL_SIGRTMAX RTL_MAX_SIGNAL /*TODO How will this work on PPC */ diff -NaurbB rtlinux-3.2-pre2.old/Makefile rtlinux-3.2-pre2/Makefile --- rtlinux-3.2-pre2.old/Makefile 2003-04-23 19:42:36.000000000 +0200 +++ rtlinux-3.2-pre2/Makefile 2003-07-17 11:28:20.000000000 +0200 @@ -172,6 +171,10 @@ MODULE_DIRS += debugger endif +ifeq ($(CONFIG_OC_RTL_MALLOC),y) +MODULE_DIRS += rtl_malloc +endif + ifdef CONFIG_RTL_V1_API ifndef CONFIG_SMP MODULE_DIRS += semaphores @@ -284,10 +287,11 @@ # the touch are necessary for CVS - as CVS dischars empty files... symlinks: dummy - rm -f include/arch main/arch + rm -f include/arch main/arch rtl_malloc/arch ln -s $(ARCH) include/arch ln -s $(ARCH) main/arch ln -s $(ARCH) schedulers/arch + ln -s $(ARCH) rtl_malloc/arch touch schedulers/i386/sw.S touch schedulers/i386/Makefile touch main/arch/arch.c diff -NaurbB rtlinux-3.2-pre2.old/rtl_malloc/i386/bits.h rtlinux-3.2-pre2/rtl_malloc/i386/bits.h --- rtlinux-3.2-pre2.old/rtl_malloc/i386/bits.h 1970-01-01 01:00:00.000000000 +0100 +++ rtlinux-3.2-pre2/rtl_malloc/i386/bits.h 2003-07-17 11:28:38.000000000 +0200 @@ -0,0 +1,92 @@ +/* + * Some of this code has been taken from bitops.h + * Copyright 1992, Linus Torvalds. + * + * Others functions has been added by + * Miguel Masmano Tello + * Copyright (C) Feb, 2003 OCERA Consortium + * Release under the terms of the GNU General Public License Version 2 + */ + +#define ADDR (*(volatile long *) addr) + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + + +static __inline__ int DIDMA_ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r; +} + + +/** + * fls - find last bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int DIDMA_fls(int x) +{ + int r; + + __asm__("bsrl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r; +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +/* +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +*/ +/** + * __clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is non-atomic and may be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void __clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + + + + diff -NaurbB rtlinux-3.2-pre2.old/rtl_malloc/Makefile rtlinux-3.2-pre2/rtl_malloc/Makefile --- rtlinux-3.2-pre2.old/rtl_malloc/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ rtlinux-3.2-pre2/rtl_malloc/Makefile 2003-07-17 11:28:38.000000000 +0200 @@ -0,0 +1,15 @@ +all: malloc.o +main: all + +include ../rtl.mk + +malloc.o: rtl_malloc.o + cp -f rtl_malloc.o ../modules/ + +clean: +# rm -f arch + find . \( -name '*~' -o -name '*.o' -o -name core \) -exec /bin/rm -r '{}' \; + +.PHONY: dummy + +include $(RTL_DIR)/Rules.make diff -NaurbB rtlinux-3.2-pre2.old/rtl_malloc/rtl_malloc.c rtlinux-3.2-pre2/rtl_malloc/rtl_malloc.c --- rtlinux-3.2-pre2.old/rtl_malloc/rtl_malloc.c 1970-01-01 01:00:00.000000000 +0100 +++ rtlinux-3.2-pre2/rtl_malloc/rtl_malloc.c 2003-07-17 11:28:38.000000000 +0200 @@ -0,0 +1,970 @@ +/* + * Doubly indexed dynamic memory allocator (DIDMA) + * Version 1.0 + * + * Written by Miguel Masmano Tello + * Copyright (C) Dec, 2002 OCERA Consortium + * Release under the terms of the GNU General Public License Version 2 + * + */ + +#include +#include "arch/bits.h" + +// linux/types.h includes definitions +// for the standard types +#include + +#if !defined (__RTL__) && defined (__KERNEL__) +#error "This modules can only be used by RTLinux or by user space" +#endif + +#if defined (__RTL__) + +#include + +#define INIT_THREAD_MUTEX() +#define THREAD_LOCK() __asm__ __volatile__ ("cli"); +#define THREAD_UNLOCK() __asm__ __volatile__ ("sti"); + +MODULE_AUTHOR("Miguel Masmano Tello "); +MODULE_DESCRIPTION("Doubly Indexed Memory Allocator (DIDMA) V1.0"); + +MODULE_LICENSE("GPL"); + +static int max_size = 1024; // 1 MByte + +MODULE_PARM(max_size, "i"); +MODULE_PARM_DESC(max_size, "Memory pool size in Kb (default=1024)"); + +static unsigned char *ptr_mem; + +/* This DIDMA version only can be used with BIGPHYSAREA patch */ +#if defined(CONFIG_BIGPHYSAREA) || defined(CONFIG_BIGPHYS_AREA) +#include +#else +#error BIGPHYSAREA PATCH MUST BE INSTALLED +#endif + +int init_module(void){ + // First of all we reserve the memory that will be used later + ptr_mem = (unsigned char *) bigphysarea_alloc(max_size * 1024); + if (ptr_mem == NULL) { + rtl_printf ("rtl_malloc PANIC: Error reserving memory!!"); + return -1; + } + if (init_memory_pool (max_size, 5, ptr_mem) < 0) return -1; + associate_buffer (ptr_mem); + + return 0; +} + +void cleanup_module(void){ + destroy_memory_pool(ptr_mem); + bigphysarea_free((caddr_t) ptr_mem, 0); +} + +#else // #if defined (__RTL__) + +#define INIT_THREAD_MUTEX() +#define THREAD_LOCK() +#define THREAD_UNLOCK() + +#endif // #if defined (__RTL__) + +/* + * The following TAD will be a double level indexed array, the most + * important thing is that the time is bounded, the reason of this is + * because DIDMA has been designed to be used by real time programs. + * + * First level Second level + * it is indexed it is indexed by 2**n+(2**n/m*index_number) + * by power of 2 + * 0 1 m-1 m + * ----> NULL --> NULL ----> NUL + * | | | + * ------- ---------------------...--------------------- + * 2**n | n | -----> |2**n+(2**n/m*0)|...| |...|2**n+(2**n/m*m)| + * |-----| ---------------------...--------------------- + * 2**n-1| n-1 | -----> .... | + * |-----| --->NULL + * ..... + */ + +/* + * Some defaults values; + * please, don't touch these macros + */ + +#define MIN_LOG2_SIZE 4 +#define MIN_SIZE (1 << MIN_LOG2_SIZE) +#define MAX_LOG2_SIZE 32 // 4 GBytes I think that this size is too much +//#define MAX_SL_INDEX (1 << MAX_SL_LOG2_INDEX) + +/* + * The following structure defines the pointers used + * by the header to know the position of the free blocks + */ + +typedef struct free_ptr_struct { + struct beg_block_header_struct *prev; + struct beg_block_header_struct *next; + + /* + * first_index and second_index are used to store + * mapping_function results, that's how we get some extra + * nanoseconds + */ + __u8 first_index; + __u8 second_index; +} free_ptr_t; + +/* + * BLOCK_USED must be used like mask with the magic number + * i.e. + * if ((magic_number & BLOCK_USED) = BLOCK_USED) then + * return USED; + * else + * return FREE + * end if; + */ + +#define BLOCK_USED 0x80000000 +#define BLOCK_FREE ~BLOCK_USED //0x7FFFFFFF + +#define LAST_BLOCK 0x40000000 +#define NOT_LAST_BLOCK ~LAST_BLOCK //0xBFFFFFFF + +/* + * The magic number must be calculated like: + * if ((magic_number & MAGIC_NUMBER) = MAGIC_NUMBER) then + * return OK; + * else + * return ERROR; + * end if; + */ + +#define MAGIC_NUMBER 0x2A59FA59 + +typedef struct beg_block_header_struct { + /* + * MAGIC_NUMBER is a sanity byte and it also codifies if + * the block is used or free + */ + __u32 magic_number; + + /* The size of the block in bytes */ + __u32 size; + + /* + * This pointer is used in order to have + * a quick access to the end of the block + */ + struct end_block_header_struct *block_tail; + + union { + struct free_ptr_struct free_ptr; + __u8 buffer[sizeof(struct free_ptr_struct)]; + } ptr; + +} beg_block_header_t; + +// This is a pointer to the head of the block +typedef struct end_block_header_struct { + beg_block_header_t *block_header; +} end_block_header_t; + +/* first level index array */ +typedef struct fl_array_struct { + /* ptr is pointer to next level */ + beg_block_header_t **sl_array; + + /* bitmapSL is the second level bitmap */ + __u32 bitmapSL; +} fl_array_t; + +/* + * When the user calls init_memory_pool, he must give a block of memory + * block, this block will be used to store the DIDMA structure + */ + +typedef struct DIDMA_struct { + __u32 magic_number; + /* + * max_fl_index, max_sl_index and max_sl_log2_index + * must be __u8 but the compiler assigns 32 bits by efficiency, + * we also do that + */ + __u32 max_fl_index; + __u32 max_fl_pow2_index; + __u32 max_sl_index; + __u32 max_sl_log2_index; + /* bitmapFL is the bitmap of the first level */ + __u32 bitmapFL; + __s32 total_size; + /* first_bh will be our first memory block allocated by MALLOC function */ + beg_block_header_t *first_bh; + beg_block_header_t *memory_pool; + + /* + * fl_array will be our first level array, + * it will be an array of [max_fl_index] elements + */ + fl_array_t *fl_array; +} DIDMA_t; + +/* + * header_overhead has size of blocks_header - 2 * ptr to next free block + */ +static __s32 beg_header_overhead = 0, end_header_overhead = 0; + +#define DIDMA__set_bit(num, mem) mem |= (1 << num) +#define DIDMA__clear_bit(num, mem) mem &= ~(1 << num) + +char *main_buffer = NULL; + +/* + * log2size () returns cell of log2 (len) it does a search between + * MIN_SIZE and MAX_SIZE values in order to find the log2 of the size. + * Theorically we have obtained that this method is more efficient + * than the asm instruction which does the same operation + */ + +static inline __s32 log2size (size_t size, size_t *new_size) { + + __s32 i; + + if (size <= 0) { + *new_size = -1; + return -1; + } + + if (size <= MIN_SIZE){ + *new_size = MIN_SIZE; + return MIN_LOG2_SIZE; + } + + /* One method in order to find log2 of a given number */ + /*-----------------*/ + /* + for (i = MIN_LOG2_SIZE; + (i <= MAX_LOG2_SIZE) && (size > (*new_size = (1 << i))) ; i++); + */ + /*-----------------*/ + + /* Other method more machine dependent */ + /*------------------------------*/ + i = DIDMA_fls(size); + + i = ((1 << i) != size )? ++i: i; + + *new_size = (1 << i); + + if (i < MIN_LOG2_SIZE) { + *new_size = MIN_SIZE; + return MIN_LOG2_SIZE; + } + + /*----------------------------*/ + + if (i > MAX_LOG2_SIZE) { + return -1; + } + + return i; +} + +/* + * mapping_function () returns first and second level index + * + * first level index function is: + * fl = log2 (size) + * + * and second level index function is: + * sl = (size - 2**(log2size (size))) / (log2 (size) - log2 (MAX_SL_INDEX)) + * + */ + +static inline __s32 mapping_function (size_t size, __s32 *fl, __s32 *sl, + DIDMA_t *ptr_DIDMA){ + __s32 aux, new_len; + + // first level = log2 (size) + *fl = log2size (size, &new_len); + + if (new_len == size) { + // if 2**fl == size, second level must be 0 + *sl = 0; + } else { + -- *fl; + aux = *fl - ptr_DIDMA -> max_sl_log2_index; + if (aux >= 0) + *sl = (int)((size - (new_len >> 1)) >> aux); + else + *sl = (int)(size - (new_len >> 1)); + } + + return 0; +} + +// max_size is in Kbytes +int init_memory_pool (int max_size, + int max_sl_log2_index, char *block_ptr) { + __s32 n, free_mem = 0; + + end_block_header_t *header_end; + __s32 size_fl_sl_array, i; + DIDMA_t *ptr_DIDMA; + + if (!(max_size > 0)) { + PRINT_MSG ("ERROR: size must be > 0\n"); + return -1; + } + INIT_THREAD_MUTEX(); + //if ((int) max_sl_log2_index > MIN_LOG2_SIZE) { + // PRINT_MSG ("ERROR: max_sl_log2_index (%d) must be < %d\n", + // max_sl_log2_index, MIN_LOG2_SIZE); + // return -1; + //} + + if (max_sl_log2_index <= 0) { + PRINT_MSG ("ERROR: max_sl_log2_index (%d) must be >= 0\n", + max_sl_log2_index); + return -1; + } + + memset ((char *) block_ptr, 0, max_size * 1024); + + ptr_DIDMA = (DIDMA_t *) block_ptr; + + ptr_DIDMA -> magic_number = MAGIC_NUMBER; + /* Total size of the block, DIDMA_struct + free_memory */ + ptr_DIDMA -> total_size = max_size * 1024; + ptr_DIDMA -> max_sl_log2_index = max_sl_log2_index; + ptr_DIDMA -> max_sl_index = (1 << ptr_DIDMA -> max_sl_log2_index); + + size_fl_sl_array = (__s32) sizeof (fl_array_t) + + ((__s32) sizeof (beg_block_header_t *) + * (__s32) ptr_DIDMA -> max_sl_index); + + + free_mem = ptr_DIDMA -> total_size + - sizeof (DIDMA_t) + - size_fl_sl_array; + + for (n = MIN_LOG2_SIZE + 1; + ((int) free_mem - (int) size_fl_sl_array) > (1< max_fl_index = n; + ptr_DIDMA -> max_fl_pow2_index = (1 << ptr_DIDMA -> max_fl_index); + + n -= MIN_LOG2_SIZE; + + /* max_fl_index will never be greater than MAX_FL_INDEX */ + if (ptr_DIDMA -> max_fl_index < 0 || MAX_FL_INDEX < 0) return -1; + + ptr_DIDMA -> fl_array = ( fl_array_t *) + ((__u32) &(ptr_DIDMA -> fl_array) + + (__u32) sizeof (ptr_DIDMA -> fl_array)); + + + for (i = 0 ; i < n; i ++) + ptr_DIDMA -> fl_array [i] .sl_array = (beg_block_header_t **) + (((__s32) ptr_DIDMA -> fl_array + ((__s32) sizeof (fl_array_t) * n)) + + ((__s32) sizeof (beg_block_header_t *) * + (__s32) ptr_DIDMA -> max_sl_index * i)); + + ptr_DIDMA -> memory_pool = (beg_block_header_t *) + ((__u32) ptr_DIDMA -> fl_array + + (size_fl_sl_array * n)); + + ptr_DIDMA -> first_bh = ptr_DIDMA -> memory_pool; + + beg_header_overhead = (int) (ptr_DIDMA -> memory_pool -> ptr.buffer) + - (int) ptr_DIDMA -> memory_pool; + + end_header_overhead = sizeof (end_block_header_t); + + ptr_DIDMA -> bitmapFL = 0; + + /* memory_pool initialization */ + + // the block is free + ptr_DIDMA -> memory_pool -> magic_number = MAGIC_NUMBER | LAST_BLOCK; + ptr_DIDMA -> memory_pool -> size = + free_mem - beg_header_overhead - end_header_overhead; + ptr_DIDMA -> memory_pool -> ptr.free_ptr.prev = NULL; + ptr_DIDMA -> memory_pool -> ptr.free_ptr.next = NULL; + + header_end = (end_block_header_t *) + (((__u32) ptr_DIDMA -> memory_pool -> ptr.buffer) + + (__u32) ptr_DIDMA -> memory_pool -> size); + + header_end -> block_header = ptr_DIDMA -> memory_pool; + ptr_DIDMA -> memory_pool -> block_tail = header_end; + return ptr_DIDMA -> memory_pool -> size; +} + +void destroy_memory_pool (char *block_ptr) { + DIDMA_t *ptr_DIDMA; + ptr_DIDMA = (DIDMA_t *) block_ptr; + ptr_DIDMA -> magic_number = 0; +} + +/* see man malloc */ +/* + * malloc searchs a free block of size 'size', + * after the free block will be splitted in two new blocks, + * one of these new blocks will be given to the user and the + * other will be inserted into DIDMA structure + * + * The cost of this operation is + * best case: (K) = (1) + * worst case: (MAX_FL_LOG2_INDEX - MIN_FL_LOG2_INDEX + MAX_SL_INDEX + K) + * = (1) + * where K is a constant integer + */ + +#ifdef WITH_RTL_PREFIX +void *rtl_malloc_ex (size_t size, char *block_ptr) { +#else +void *malloc_ex (size_t size, char *block_ptr) { +#endif + DIDMA_t *ptr_DIDMA; + + int for_free_block = 0, fl, sl, n, found = 0; + beg_block_header_t *bh = NULL, *bh2 = NULL; + end_block_header_t *e_bh = NULL, *e_bh2 = NULL; + + ptr_DIDMA = (DIDMA_t *) block_ptr; + + if (ptr_DIDMA == NULL || ptr_DIDMA -> magic_number != MAGIC_NUMBER) { + PRINT_MSG ("FATAL ERROR: DIDMA structure not initialized\n"); + return NULL; + } + + if (!(size > 0)) { + PRINT_MSG ("ERROR: Memory pool exhausted!!!\n"); + return NULL; + } + + if (size <= MIN_SIZE) { + size = MIN_SIZE; + fl = 0; + sl = 0; + } else { + + mapping_function (size, &fl, &sl, ptr_DIDMA); + + if (++sl == ptr_DIDMA -> max_sl_index) { + fl ++; + sl = 0; + } + + /* + * This is the reason of the internal fragmentation + * The block given is greater that the size demanded + */ + size = (1 << fl); + + /* size can be smaller that maximum SLI, in this case the mapping function + has problems calculating fl and sl values */ + if (size < (1 << ptr_DIDMA -> max_sl_log2_index)) + size = size + ((size >> MIN_LOG2_SIZE) * sl); + else + size = size + ((size >> ptr_DIDMA -> max_sl_log2_index) * sl); + + fl -= MIN_LOG2_SIZE; + } + + /*----------------------------------------*/ + /* The search for a free block begins now */ + /*----------------------------------------*/ + + /* + * Our first try, we take the first free block + * from fl_array or its buddy + */ + THREAD_LOCK(); + sl = ptr_DIDMA -> fl_array[fl].bitmapSL & ((~0) << sl); + if (sl != 0) { + sl = DIDMA_fls(sl); + bh = ptr_DIDMA -> fl_array [fl].sl_array [sl]; + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh -> ptr.free_ptr.next; + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] != NULL) + ptr_DIDMA ->fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = NULL; + else { + DIDMA__clear_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + if (!ptr_DIDMA -> fl_array[fl].bitmapSL) + DIDMA__clear_bit (fl, ptr_DIDMA -> bitmapFL); + } + found = 1; + goto out; + } + + /* + * if fl_array is empty we will take a free block + * from free_block pointer + */ + + if (ptr_DIDMA -> memory_pool != NULL && + ptr_DIDMA -> memory_pool -> size >= size) { + bh = ptr_DIDMA -> memory_pool; + ptr_DIDMA -> memory_pool = NULL; + for_free_block = 1; + found = 1; + goto out; + } + + /* + * On the last case a free block is searched using a bitmap + */ + + fl = DIDMA_fls(ptr_DIDMA -> bitmapFL & ((~0) << (fl + 1))); + + if (fl > 0) { + sl = DIDMA_fls(ptr_DIDMA -> fl_array[fl].bitmapSL); + bh = ptr_DIDMA -> fl_array [fl].sl_array [sl]; + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh -> ptr.free_ptr.next; + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] != NULL){ + ptr_DIDMA -> fl_array [fl].sl_array [sl] + -> ptr.free_ptr.prev = NULL; + } else { + DIDMA__clear_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + if (!ptr_DIDMA -> fl_array[fl].bitmapSL) + DIDMA__clear_bit (fl, ptr_DIDMA -> bitmapFL); + } + found = 1; + goto out; + } + /* end of the search */ + /*------------------------------------------------------------*/ + + out: + + /* + * HUGGGG, NOT ENOUGHT MEMORY + * I think that we have done all that we have been able, I'm sorry + */ + + if (!found) { + THREAD_UNLOCK(); + PRINT_MSG ("ERROR: Memory pool exhausted!!!\n"); + return NULL; + } + + /* + * we can say: YESSSSSSSSSSS, we have enought memory!!!! + */ + + /* can bh be splitted? */ + n = (int)(bh -> size - size - beg_header_overhead - end_header_overhead); + if (n >= (int) MIN_SIZE) { + /* + * Yes, bh will be splitted + */ + /* The new block will begin at the end of the current block */ + bh -> size = size; + e_bh = (end_block_header_t *) ((__u8 *) (bh -> ptr.buffer) + bh -> size); + + bh -> block_tail = e_bh; + + + e_bh -> block_header = bh; + + bh2 = (beg_block_header_t *) ((__u8 *) bh -> ptr.buffer + size + + end_header_overhead); + + + bh2 -> magic_number = bh -> magic_number; + bh -> magic_number = MAGIC_NUMBER | BLOCK_USED; + + bh2 -> size = n; + e_bh2 = (end_block_header_t *) + ((__u8 *) (bh2 -> ptr.buffer) + bh2 -> size); + + bh2 -> block_tail = e_bh2; + e_bh2 -> block_header = bh2; + + /* Has free block been taken from memory pool or from DIDMA structure? */ + + if (!for_free_block) { + mapping_function (bh2 -> size, &fl, &sl, ptr_DIDMA); + fl -= MIN_LOG2_SIZE; + bh2 -> ptr.free_ptr.first_index = fl; + bh2 -> ptr.free_ptr.second_index = sl; + bh2 -> ptr.free_ptr.prev = NULL; + bh2 -> ptr.free_ptr.next = ptr_DIDMA -> fl_array [fl].sl_array [sl]; + + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] != NULL) + ptr_DIDMA -> fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = bh2; + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh2; + DIDMA__set_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + DIDMA__set_bit (fl, ptr_DIDMA -> bitmapFL); + } else ptr_DIDMA -> memory_pool = bh2; + } + + bh -> magic_number |= BLOCK_USED; + THREAD_UNLOCK(); + return (void *) bh -> ptr.buffer; +} + +/* see man realloc */ +#ifdef WITH_RTL_PREFIX +void *rtl_realloc_ex (void *p, size_t new_len, char *block_ptr) { +#else +void *realloc_ex (void *p, size_t new_len, char *block_ptr) { +#endif + __u8 *ptr_aux; + beg_block_header_t *b; + + if (p == NULL) +#ifdef WITH_RTL_PREFIX + return (void *) rtl_malloc_ex (new_len, block_ptr); +#else + return (void *) malloc_ex (new_len, block_ptr); +#endif + else if (new_len == 0) { +#ifdef WITH_RTL_PREFIX + rtl_free_ex (p, block_ptr); +#else + free_ex (p, block_ptr); +#endif + return NULL; + } + +#ifdef WITH_RTL_PREFIX + ptr_aux = (__u8 *) rtl_malloc_ex (new_len * sizeof (__u8), block_ptr); +#else + ptr_aux = (__u8 *) malloc_ex (new_len * sizeof (__u8), block_ptr); +#endif + + b = (beg_block_header_t *) (((__u8 *) p) - beg_header_overhead); + memcpy ((__u8 *) ptr_aux, (__u8 *) b, b -> size); +#ifdef WITH_RTL_PREFIX + rtl_free_ex (p, block_ptr); +#else + free_ex (p, block_ptr); +#endif + + return ((void *) ptr_aux); +} + +/* see man calloc */ +#ifdef WITH_RTL_PREFIX +void *rtl_calloc_ex (size_t nelem, size_t elem_size, char *block_ptr) { +#else +void *calloc_ex (size_t nelem, size_t elem_size, char *block_ptr) { +#endif + + __u8 *p; + + if (nelem <= 0 || elem_size <= 0) return NULL; + +#ifdef WITH_RTL_PREFIX + if ((p = (__u8 *) rtl_malloc_ex (nelem * elem_size, block_ptr)) == NULL) + return NULL; +#else + if ((p = (__u8 *) malloc_ex (nelem * elem_size, block_ptr)) == NULL ) + return NULL; +#endif + + memset (p, 0, nelem * elem_size); + + return ((void *) p); + +} + +/* + * see man free + * + * free () is only guaranteed to work if ptr is the address + * of a block allocated by rt_malloc() (and not yet freed). + */ + +#ifdef WITH_RTL_PREFIX +void rtl_free_ex (void *ptr, char *block_ptr) { +#else +void free_ex (void *ptr, char *block_ptr) { +#endif + int fl, sl, for_free_block = 0; + beg_block_header_t *bh = NULL, *bh2 = NULL; + end_block_header_t *e_bh = NULL, *e_bh2 = NULL; + + DIDMA_t *ptr_DIDMA; + + ptr_DIDMA = (DIDMA_t *) block_ptr; + + if (ptr_DIDMA == NULL || ptr_DIDMA -> magic_number != MAGIC_NUMBER) { + PRINT_MSG ("FATAL ERROR: DIDMA structure not initialized\n"); + return; + } + + bh = (beg_block_header_t *) (ptr - beg_header_overhead); + + if ((bh -> magic_number & MAGIC_NUMBER) != MAGIC_NUMBER) + return; + THREAD_LOCK(); + /* now bh is a free block */ + + bh -> magic_number &= BLOCK_FREE; + bh -> ptr.free_ptr.prev = NULL; + bh -> ptr.free_ptr.next = NULL; + + /* + * first of all, we will try to merge bh with the + * physically contiguos free block and + * after we will inserte bh into DIDMA structure + */ + + if ((bh -> magic_number & LAST_BLOCK) == LAST_BLOCK) + for_free_block = 1; + else { + /* is it free the next block? */ + /* The next block is easy to found */ + bh2 = (beg_block_header_t *) ((__u8 *) bh -> ptr.buffer + + bh -> size + end_header_overhead); + e_bh2 = (end_block_header_t *) bh2 -> block_tail; + + if ((bh2 -> magic_number & MAGIC_NUMBER) != MAGIC_NUMBER) { + THREAD_UNLOCK(); + PRINT_MSG ("ERROR: block corrupted found\n"); + return; + } + + /* Here we merge bh with the next contiguos block */ + if ((bh2 -> magic_number & BLOCK_USED) != BLOCK_USED) { + + /* we are lucky, we can merge bh with the next block */ + + if ((bh2 -> magic_number & LAST_BLOCK) == LAST_BLOCK) for_free_block = 1; + + if (!for_free_block) { + if (bh2 -> ptr.free_ptr.next != NULL) + bh2 -> ptr.free_ptr.next -> ptr.free_ptr.prev = + bh2 -> ptr.free_ptr.prev; + + if (bh2 -> ptr.free_ptr.prev != NULL) + bh2 -> ptr.free_ptr.prev -> ptr.free_ptr.next = + bh2 -> ptr.free_ptr.next; + + fl = bh2 -> ptr.free_ptr.first_index; + sl = bh2 -> ptr.free_ptr.second_index; + + /* bh2 must be erased from fl_array */ + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] == bh2) + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh2 -> ptr.free_ptr.next; + + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] == NULL){ + DIDMA__clear_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + if (!ptr_DIDMA -> fl_array[fl].bitmapSL) + DIDMA__clear_bit (fl, ptr_DIDMA -> bitmapFL); + + } + } + + bh -> size += bh2 -> size + beg_header_overhead + end_header_overhead; + bh -> block_tail = e_bh2; + bh -> magic_number = e_bh2 -> block_header -> magic_number; + e_bh2 -> block_header = bh; + + } + } + + /* is it free the previous block? */ + if (ptr_DIDMA -> first_bh != bh) { // This block is not the first block + + e_bh2 = (end_block_header_t *) ((__u8 *) bh + - end_header_overhead); + + /* is it free the previous block? */ + + bh2 = (beg_block_header_t *) e_bh2 -> block_header; + + e_bh = (end_block_header_t *) bh -> block_tail; + + if ((bh2 -> magic_number & MAGIC_NUMBER) == MAGIC_NUMBER && + (BLOCK_USED & bh2 -> magic_number) != BLOCK_USED) { + + bh2 -> magic_number = e_bh -> block_header -> magic_number; + + if (bh2 -> ptr.free_ptr.next != NULL) + bh2 -> ptr.free_ptr.next -> ptr.free_ptr.prev = + bh2 -> ptr.free_ptr.prev; + + if (bh2 -> ptr.free_ptr.prev != NULL) + bh2 -> ptr.free_ptr.prev -> ptr.free_ptr.next = + bh2 -> ptr.free_ptr.next; + + fl = bh2 -> ptr.free_ptr.first_index; + sl = bh2 -> ptr.free_ptr.second_index; + + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] == bh2) + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh2 -> ptr.free_ptr.next; + + if (ptr_DIDMA -> fl_array[fl].sl_array[sl] == NULL){ + + DIDMA__clear_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + if (!ptr_DIDMA -> fl_array[fl].bitmapSL) + DIDMA__clear_bit (fl, ptr_DIDMA -> bitmapFL); + + } + + + bh2 -> size += bh -> size + beg_header_overhead + end_header_overhead; + e_bh -> block_header = bh2; + bh2 -> block_tail = e_bh; + bh = bh2; + } + } + + /* + * and now we can merge the free block with the initial memory + */ + if (for_free_block) { + ptr_DIDMA -> memory_pool = bh; + bh -> ptr.free_ptr.next = NULL; + bh -> ptr.free_ptr.prev = NULL; + } else { + + /* + * or we insert the free block in the TAD + */ + mapping_function (bh -> size, &fl, &sl, ptr_DIDMA); + fl -= MIN_LOG2_SIZE; + bh -> ptr.free_ptr.first_index = fl; + bh -> ptr.free_ptr.second_index = sl; + bh -> ptr.free_ptr.next = ptr_DIDMA -> fl_array [fl].sl_array [sl]; + bh -> ptr.free_ptr.prev = NULL; + + if (ptr_DIDMA -> fl_array [fl].sl_array [sl] != NULL) + ptr_DIDMA -> fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = bh; + ptr_DIDMA -> fl_array [fl].sl_array [sl] = bh; + + DIDMA__set_bit (sl, ptr_DIDMA -> fl_array[fl].bitmapSL); + DIDMA__set_bit (fl, ptr_DIDMA -> bitmapFL); + + } + THREAD_UNLOCK(); +} + +static void print_block (beg_block_header_t *b){ + if (b == NULL) return; + PRINT_DBG_C (">>>> MNum 0x"); + PRINT_DBG_H (b -> magic_number & BLOCK_FREE & NOT_LAST_BLOCK); + PRINT_DBG_C (" Address 0x"); + PRINT_DBG_H (b); + if ((b -> magic_number & BLOCK_USED) != BLOCK_USED) + PRINT_DBG_C ("\n>>>> Status FREE"); + else + PRINT_DBG_C ("\n>>>> Status USED"); + if ((b -> magic_number & LAST_BLOCK) == LAST_BLOCK) + PRINT_DBG_C (" Position LAST BLOCK"); + else + PRINT_DBG_C (" Position NOT LAST BLOCK"); + PRINT_DBG_C (" Size "); + PRINT_DBG_D (b -> size); + PRINT_DBG_C (" bytes\n-- Tail address 0x"); + PRINT_DBG_H (b -> block_tail); + PRINT_DBG_C (" tail -> header address 0x"); + PRINT_DBG_H (b -> block_tail -> block_header); + if ((b -> magic_number & BLOCK_FREE) == BLOCK_FREE){ + PRINT_DBG_C ("\n---- Prev Free 0x"); + PRINT_DBG_H (b -> ptr.free_ptr.prev); + PRINT_DBG_C (" Next Free 0x"); + PRINT_DBG_H (b -> ptr.free_ptr.next); + } + PRINT_DBG_C ("\n\n"); +} + +/* + * structure_status () shows the status of all the blocks + */ +void structure_status (char *block_ptr) { + beg_block_header_t *b; + DIDMA_t *ptr_DIDMA; + int end = 0; + + ptr_DIDMA = (DIDMA_t *) block_ptr; + if (ptr_DIDMA == NULL || ptr_DIDMA -> magic_number != MAGIC_NUMBER) { + PRINT_MSG ("FATAL ERROR: DIDMA structure not initialized\n"); + return; + } + + b = ptr_DIDMA -> first_bh; + PRINT_DBG_C ("\nDIDMA structure address 0x"); + PRINT_DBG_H (ptr_DIDMA); + PRINT_DBG_C ("\nMax. first level index: "); + PRINT_DBG_D (ptr_DIDMA -> max_fl_index); + PRINT_DBG_C ("\nMax. second level index: "); + PRINT_DBG_D (ptr_DIDMA -> max_sl_log2_index); + PRINT_DBG_C ("\n\nALL BLOCKS\n"); + while (!end) { + print_block (b); + if ((b -> magic_number & LAST_BLOCK) == LAST_BLOCK) + end = 1; + else + b = (beg_block_header_t *) ((__u8 *) b -> block_tail + + end_header_overhead); + } + +} + +/* + * free_blocks_status () only shows the status + * of the free blocks + */ +void free_blocks_status (char *block_ptr){ + int i, j; + beg_block_header_t *b; + + DIDMA_t *ptr_DIDMA; + + ptr_DIDMA = (DIDMA_t *) block_ptr; + if (ptr_DIDMA == NULL || ptr_DIDMA -> magic_number != MAGIC_NUMBER) { + PRINT_MSG ("FATAL ERROR: DIDMA structure not initialized\n"); + return; + } + + PRINT_DBG_C ("\nDIDMA structure address 0x"); + PRINT_DBG_H (ptr_DIDMA); + PRINT_DBG_C ("\nFREE BLOCKS\n"); + PRINT_DBG_C ("MEMORY POOL\n"); + print_block (ptr_DIDMA -> memory_pool); + PRINT_DBG_C ("FRAGMENTED BLOCKS\n"); + for (i = ptr_DIDMA -> max_fl_index - 1 - MIN_LOG2_SIZE; i >= 0; i--) { + if (ptr_DIDMA -> fl_array [i].bitmapSL > 0) + for (j = ptr_DIDMA -> max_sl_index - 1; j >= 0; j--) { + if (ptr_DIDMA -> fl_array [i].sl_array[j] != NULL) { + b = ptr_DIDMA -> fl_array [i].sl_array [j]; + PRINT_DBG_C ("["); + PRINT_DBG_D (i + MIN_LOG2_SIZE); + PRINT_DBG_C ("] "); + PRINT_DBG_D (1 << (i + MIN_LOG2_SIZE)); + PRINT_DBG_C (" bytes -> Free blocks: 0x"); + PRINT_DBG_H (ptr_DIDMA -> fl_array [i].bitmapSL); + PRINT_DBG_C ("\n"); + + while (b != NULL) { + PRINT_DBG_C (">>>> First_Level ["); + PRINT_DBG_D (i + MIN_LOG2_SIZE); + PRINT_DBG_C ("] Second Level ["); + PRINT_DBG_D (j); + PRINT_DBG_C ("] -> "); + PRINT_DBG_D ( (1 << (i + MIN_LOG2_SIZE)) + + ( ((1 << (i + MIN_LOG2_SIZE)) / + ptr_DIDMA -> max_sl_index) * j)); + + PRINT_DBG_C (" bytes\n"); + print_block (b); + b = b -> ptr.free_ptr.next; + } + } + } + } +} diff -NaurbB rtlinux-3.2-pre2.old/schedulers/i386/rtl_exceptions.c rtlinux-3.2-pre2/schedulers/i386/rtl_exceptions.c --- rtlinux-3.2-pre2.old/schedulers/i386/rtl_exceptions.c 1970-01-01 01:00:00.000000000 +0100 +++ rtlinux-3.2-pre2/schedulers/i386/rtl_exceptions.c 2003-07-17 11:29:17.000000000 +0200 @@ -0,0 +1,231 @@ +/* + * rtl_exceptions.c contains some code from Debugger module + * + * March, 2003 Miguel Masmano + * Copyright (C) April, 2003 OCERA Consortium + * Release under the terms of the GNU General Public License Version 2 + * + * Thanks to Josep Vidal + */ + +#include +#include +#include +#include +#include /* for linux pt_regs struct */ +#include +#include +#include +#include +#include + +/* RTLinux support */ +#define __NO_VERSION__ +#include + +#include +#include + +#include + +#ifdef CONFIG_OC_PSIGNALS + +static int rtl_exec_system = 0; + +#define rtl_running_linux() (pthread_self() == &LOCAL_SCHED->rtl_linux_task) + +static struct hard_trap_info +{ + unsigned int tt; /* Trap type code for i386 */ + unsigned char signo; /* Signal that we map this trap into */ +} hard_trap_info[] = { + { 0, RTL_SIGFPE }, + { 1, RTL_SIGTRAP }, + { 2, RTL_SIGSEGV }, + { 3, RTL_SIGTRAP }, + { 4, RTL_SIGSEGV }, + { 5, RTL_SIGSEGV }, + { 6, RTL_SIGILL }, + { 7, RTL_SIGSEGV }, + { 8, RTL_SIGSEGV }, + { 9, RTL_SIGFPE }, + { 10, RTL_SIGSEGV }, + { 11, RTL_SIGBUS }, + { 12, RTL_SIGBUS }, + { 13, RTL_SIGSEGV }, + { 17, RTL_SIGSEGV }, + { 18, RTL_SIGSEGV }, + { 19, RTL_SIGSEGV } +}; + +static int computeSignal (unsigned int tt) { + int i; + + for (i = 0; i < sizeof(hard_trap_info)/sizeof(hard_trap_info[0]); i++) { + if (hard_trap_info[i].tt == tt) { + return hard_trap_info[i].signo; + } + } + + return RTL_SIGHUP; /* default for things we don't know about */ +} + +typedef void (*signal_handler_t) (int, struct sigcontext *); + +#define CURRENT_ESP(var) __asm__ __volatile__ ("mov %%esp, %0\n\t": "=m"(var):) + +static inline void _signal_handler_ (int signo, int vectorException, + int error_code, struct pt_regs *regs){ + signal_handler_t r_fun; + unsigned int reg; + struct sigcontext sigcontext; + unsigned long flags, initial_interrupt_state; + pthread_t t = pthread_self (); + int sig = signo; + void (*fun)(int)=NULL; + + rtl_no_interrupts(initial_interrupt_state); + + sigcontext.edi = regs -> edi; + sigcontext.esi = regs -> esi; + sigcontext.ebp = regs -> ebp; + + // current esp + + CURRENT_ESP (reg); + sigcontext.esp = reg; + sigcontext.ebx = regs -> ebx; + sigcontext.edx = regs -> edx; + sigcontext.ecx = regs -> ecx; + sigcontext.eax = regs -> eax; + sigcontext.trapno = vectorException; + sigcontext.err= error_code; + sigcontext.eip = regs -> eip; + sigcontext.eflags = regs -> eflags; + sigcontext.esp_at_signal = regs -> esp; + sigcontext.fpstate = NULL; + sigcontext.oldmask = 0; + + sigcontext.cr2 = 0; + + if (!test_bit(sig, &t->blocked)){ + //if (rtl_sigact[sig].owner == t){ + sigcontext.esi = regs -> esi; + sigcontext.ebp = regs -> ebp; + // current esp + CURRENT_ESP (reg); + sigcontext.esp = reg; + sigcontext.ebx = regs -> ebx; + sigcontext.edx = regs -> edx; + sigcontext.ecx = regs -> ecx; + sigcontext.eax = regs -> eax; + sigcontext.trapno = vectorException; + sigcontext.err= error_code; + sigcontext.eip = regs -> eip; + sigcontext.eflags = regs -> eflags; + sigcontext.esp_at_signal = regs -> esp; + sigcontext.fpstate = NULL; + sigcontext.oldmask = 0; + sigcontext.cr2 = 0; + + fun = rtl_sigact[sig].sa_handler; + if (fun) { + // Block signal being managed. + set_bit(sig, &t->blocked); + set_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&t->pending); + /* Here we must pop sigcontext structure (linux kernel behaviour) + Care must been taken, sematic used is not the same that the linux + kernel */ + r_fun = (signal_handler_t) fun; + rtl_allow_interrupts(); + // Here we call a void handler (int signal) with + // the address of sigcontext poped on the stack + r_fun(sig, &sigcontext); + rtl_no_interrupts(flags); + + regs -> edi = sigcontext.edi; + regs -> esi = sigcontext.esi; + regs -> ebp = sigcontext.ebp; + + regs -> ebx = sigcontext.ebx; + regs -> edx = sigcontext.edx; + regs -> ecx = sigcontext.ecx; + regs -> eax = sigcontext.eax; + + regs -> eip = sigcontext.eip; + regs -> eflags = sigcontext.eflags; + regs -> esp = sigcontext.esp_at_signal; + + clear_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&t->pending); + clear_bit(sig,&t->blocked); + + if (test_and_clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE, + &t->threadflags)){ + pthread_kill(t,RTL_SIGNAL_WAKEUP); + } + clear_bit (RTL_SCHED_TIMER_OK, &LOCAL_SCHED->sched_flags); + goto end; + } else { + rtl_allow_interrupts(); + rtl_printf ("[0x%x] Exiting: there is not a handler for signal %d: %d : %d\n", + pthread_self(), signo, vectorException, error_code); + pthread_exit ((void *) 0); + //} + } + /* The bit should be pending until unblocked. */ + clear_bit(sig,&t->pending); + rtl_allow_interrupts (); + /* Not to handle a fault is a problem for the system stability */ + rtl_printf ("[0x%x] Exiting: signal %d blocked\n", pthread_self(), signo); + pthread_exit ((void *) 0); + + } +end: + rtl_restore_interrupts(initial_interrupt_state); +} + +static int rtl_handle_exception (int vectorException, struct pt_regs *regs, + int error_code) { + unsigned long flags = 0; + int signo = computeSignal(vectorException); + + if (user_mode(regs) && !(rtl_is_psc_active())) { + return 0; + } + + rtl_hard_savef_and_cli(flags); /* shall we get a spinlock? */ + + if (rtl_running_linux() && vectorException != 1 + && vectorException != 3) { + rtl_hard_restore_flags(flags); + return 0; + } + + /* + * Here we must modify eip to execute the user handler. + * On others words, here we can play with the registers. + */ + + /**/ + /* regs -> eip = (unsigned int) tag_trap; */ + + rtl_hard_restore_flags(flags); + _signal_handler_ (signo, vectorException, error_code, regs); + + return 1; +} + +int set_exceptions_system (void){ + if (rtl_exec_system){ + return -1; + } + rtl_request_traps(&rtl_handle_exception); + rtl_exec_system = 1; + return 0; +} + +void unset_exceptions_system (void) { + rtl_request_traps(0); + rtl_exec_system = 0; +} +#endif diff -NaurbB rtlinux-3.2-pre2.old/schedulers/Makefile rtlinux-3.2-pre2/schedulers/Makefile --- rtlinux-3.2-pre2.old/schedulers/Makefile 2003-03-12 17:35:16.000000000 +0100 +++ rtlinux-3.2-pre2/schedulers/Makefile 2003-07-17 11:29:06.000000000 +0200 @@ -23,8 +23,8 @@ depend: rtl_sched.o $(CC) ${INCLUDE} ${CFLAGS} -M rtl_sched.c > .depends -rtl_sched.o: rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o $(LIBGCC) - $(LD) $(LDFLAGS) -r -o rtl_sched.o rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o -static ${LIBGCC} +rtl_sched.o: rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o rtl_exceptions.o $(LIBGCC) + $(LD) $(LDFLAGS) -r -o rtl_sched.o rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o rtl_exceptions.o -static ${LIBGCC} cp -f rtl_sched.o ../modules/ rtl_sched_tmp.o: rtl_sched.c ../include/rtl_sched.h @@ -39,6 +39,9 @@ sw.o: $(ARCH)/sw.S ../include/rtl_sched.h $(CC) ${INCLUDE} ${CFLAGS} -D__ASSEMBLY__ -o sw.o -c $(ARCH)/sw.S +rtl_exceptions.o: $(ARCH)/rtl_exceptions.c ../include/rtl_sched.h + $(CC) ${INCLUDE} ${CFLAGS} -o rtl_exceptions.o -c $(ARCH)/rtl_exceptions.c + rtl_time_tmp.o: $(ARCH)/rtl_time.c ../include/arch/rtl_time.h ../include/rtl_time.h $(CC) ${INCLUDE} ${CFLAGS} -c -o $@ $< diff -NaurbB rtlinux-3.2-pre2.old/scripts/config.in rtlinux-3.2-pre2/scripts/config.in --- rtlinux-3.2-pre2.old/scripts/config.in 2003-04-23 18:56:21.000000000 +0200 +++ rtlinux-3.2-pre2/scripts/config.in 2003-07-17 11:28:33.000000000 +0200 @@ -32,6 +32,7 @@ comment 'Support options' bool 'Posix Standard IO' CONFIG_RTL_POSIX_IO bool 'POSIX Priority Protection' _RTL_POSIX_THREAD_PRIO_PROTECT +bool 'Dynamic memory manager' CONFIG_OC_RTL_MALLOC bool 'Dev Mem Support' CONFIG_RTL_DEVMEM_SUPPORT bool 'Enable Debugging' CONFIG_RTL_DEBUG bool 'rtl_printf uses printk' CONFIG_RTL_SLOW_CONSOLE