Skip to content

Instantly share code, notes, and snippets.

@svagionitis
Created October 29, 2013 18:06
Show Gist options
  • Save svagionitis/7219673 to your computer and use it in GitHub Desktop.
Save svagionitis/7219673 to your computer and use it in GitHub Desktop.
Problem with mips 4.4 gcc for inline functions when optimized. #No segmentation /opt/CodeSourcery/mips-4.4/bin/mips-linux-gnu-gcc -EL -o test test.c # Segmentation fault /opt/CodeSourcery/mips-4.4/bin/mips-linux-gnu-gcc -EL -O2 -o test test.c #No segmentation fault /opt/CodeSourcery/mips-4.4/bin/mips-linux-gnu-gcc -EL -O2 -fno-inline -o test test.c
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
typedef struct _ListItem ListItem;
typedef ListItem *List;
struct _ListItem
{
ListItem *next;
ListItem *prev; /* The 'prev' pointer of the first element always points
to the last element of the list, for fast appending ;-) */
};
static __inline__ void
dcchd_list_prepend(List *list, ListItem *link)
{
ListItem *first = *list;
link->next = first;
if (first)
{
link->prev = first->prev;
first->prev = link;
}
else
link->prev = link;
*list = link;
}
static __inline__ void
dcchd_list_append(List *list, ListItem *link)
{
ListItem *first = *list;
link->next = NULL;
if (first)
{
ListItem *last = first->prev;
link->prev = last;
last->next = first->prev = link;
}
else
*list = link->prev = link;
}
static __inline__ void
dcchd_list_insert(List *list, ListItem *after, ListItem *link)
{
ListItem *first = *list;
/*
* special handling if we actually insert at the end of the list,
* update the HEAD's 'prev' pointer according to _ListItem
* definition
*/
if (after->next == NULL)
first->prev = link;
link->next = after->next;
if (link->next)
link->next->prev = link;
link->prev = after;
after->next = link;
}
static __inline__ void
dcchd_list_remove(List *list, ListItem *link)
{
ListItem *next;
ListItem *prev;
next = link->next;
prev = link->prev;
if (next)
next->prev = prev;
else
(*list)->prev = prev;
if (link == *list)
*list = next;
else
prev->next = next;
link->next = link->prev = NULL;
}
typedef struct _ObjectPool ObjectPool;
typedef struct _ObjectPoolDesc ObjectPoolDesc;
struct _ObjectPoolDesc
{
bool shared_mem; // allocate pool in shared memory or in local memory ?
size_t object_size; // size (in bytes) of a pool object
size_t capacity_limit; // maximum capacity of the pool; when it is reached, the pool will not grow anymore
};
struct _ObjectPool
{
ObjectPoolDesc desc;
size_t free_count;
size_t alloc_count;
List free_objs;
List alloc_objs;
};
typedef struct
{
uint32_t dram_addr;
uint32_t size;
uint32_t dram_index;
} MEMORY_REGION;
typedef struct _EM86_MEM_CHUNK
{
ListItem link; ///< used for chunk list manipulation
ListItem af_link; ///< used for operations in the allocated/free chunk lists
int offset; ///< position of the first byte counted from
///< the beginning of the memory region
int size; ///< size of the memory chunk
bool occupied; ///< TRUE if the chunk is allocated
} EM86_MEM_CHUNK;
typedef struct _EM86_MEM_MANAGER_SHARED EM86_MEM_MANAGER_SHARED;
struct _EM86_MEM_MANAGER_SHARED
{
MEMORY_REGION region; ///< descriptor of the managed memory region
uint32_t available_memory; ///< available memory in the memory region [bytes]
unsigned long total_allocated; ///< allocated memory [bytes]
void *pools; ///< non-NULL if fixed size memory pools are used
ObjectPool *chunks_pool; ///< where EM86_MEM_CHUNK objects are allocated (fast)
EM86_MEM_CHUNK *chunk_list; ///< list of memory chunks, both allocated and free
List free_chunk_list; ///< list of references to the free chunks in chunk_list
List alloc_chunk_list; ///< list of references to the allocated chunks in chunk_list
};
typedef struct
{
EM86_MEM_MANAGER_SHARED *shared;
bool shared_is_local; ///< TRUE is 'shared' structure is local to the process
void *mapped_addr; ///< virtual address corresponding to the start of
///< the memory region
} EM86_MEM_MANAGER;
int main(int argc, char *argv[])
{
EM86_MEM_MANAGER *mngr;
mngr = (EM86_MEM_MANAGER *)malloc(1*sizeof(EM86_MEM_MANAGER));
EM86_MEM_MANAGER_SHARED *mngr_shared;
mngr_shared = (EM86_MEM_MANAGER_SHARED *)malloc(1*sizeof(EM86_MEM_MANAGER_SHARED));
MEMORY_REGION *region;
region = (MEMORY_REGION *)malloc(1*sizeof(MEMORY_REGION));
region->size = 8080;
ObjectPoolDesc chunks_desc;
EM86_MEM_CHUNK *chunk;
chunks_desc.shared_mem = true;
chunks_desc.capacity_limit = 0; // no limit
chunks_desc.object_size = sizeof(EM86_MEM_CHUNK);
mngr_shared->chunks_pool = (ObjectPool *)malloc(1*sizeof(ObjectPool));
memcpy(&mngr_shared->chunks_pool->desc, &chunks_desc, sizeof(chunks_desc));
printf("desc: %d %d %d\n", mngr_shared->chunks_pool->desc.shared_mem, mngr_shared->chunks_pool->desc.capacity_limit, mngr_shared->chunks_pool->desc.object_size);
chunk = (EM86_MEM_CHUNK *)malloc(1*sizeof(EM86_MEM_CHUNK));
dcchd_list_append((List *)&mngr_shared->chunk_list, &chunk->link);
// add the chunk to the list of free chunks as well
dcchd_list_append(&mngr_shared->free_chunk_list, &chunk->af_link);
mngr_shared->region = *region;
mngr_shared->available_memory = region->size;
mngr_shared->pools = NULL;
mngr_shared->chunk_list->offset = 0;
mngr_shared->chunk_list->size = mngr_shared->available_memory;
free(mngr);
free(mngr_shared);
free(region);
free(mngr_shared->chunks_pool);
free(chunk);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment