24 #include <blackboard/internal/memory_manager.h> 25 #include <blackboard/exceptions.h> 26 #include <blackboard/shmem/header.h> 28 #include <core/exception.h> 29 #include <core/exceptions/software.h> 30 #include <core/exceptions/system.h> 31 #include <core/threading/mutex.h> 33 #include <utils/ipc/shm.h> 34 #include <utils/ipc/shm_exceptions.h> 47 #define BBMM_MIN_FREE_CHUNK_SIZE sizeof(chunk_list_t) 50 #define chunk_ptr(a) (__shmem ? (chunk_list_t *)__shmem->ptr(a) : a) 51 #define chunk_addr(a) (__shmem ? (chunk_list_t *)__shmem->addr(a) : a) 110 __shmem_header = NULL;
112 __memory = malloc(memsize);
113 __mutex =
new Mutex();
117 mlock(__memory, __memsize);
125 __free_list_head = f;
126 __alloc_list_head = NULL;
143 const char *shmem_token)
160 delete __shmem_header;
167 delete __shmem_header;
176 delete __shmem_header;
201 __mutex =
new Mutex();
210 delete __shmem_header;
228 BlackBoardMemoryManager::alloc_nolock(
unsigned int num_bytes)
236 if ( (l->
size >= num_bytes) &&
237 ( (f == NULL) || (l->
size < f->
size) ) ) {
240 l = chunk_ptr(l->
next);
252 __free_list_head = list_remove(__free_list_head, f);
268 if ( f->
size >= (num_bytes + BBMM_MIN_FREE_CHUNK_SIZE +
sizeof(
chunk_list_t)) ) {
278 __free_list_head = list_add(__free_list_head, nfc);
292 return __shmem->
ptr(f->
ptr);
294 __alloc_list_head = list_add(__alloc_list_head, f);
316 ptr = alloc_nolock(num_bytes);
318 if (__shmem) __shmem->
unlock();
322 if (__shmem) __shmem->
unlock();
359 cleanup_free_chunks();
364 chunk_list_t *ac = list_find_ptr(__alloc_list_head, ptr);
370 __alloc_list_head = list_remove(__alloc_list_head, ac);
374 __free_list_head = list_add(__free_list_head, ac);
377 cleanup_free_chunks();
398 unsigned int mem = 0;
405 t = chunk_ptr(a->
next);
409 if ( next != t->
ptr ) {
414 }
else if ( a == NULL ) {
416 t = chunk_ptr(f->
next);
420 if ( next != t->
ptr ) {
425 }
else if ( f->
ptr == a->
ptr ) {
427 }
else if ( f->
ptr < a->
ptr ) {
429 void *next = (
char *)f->
ptr + f->
size;
430 t = chunk_ptr(f->
next);
431 if ( (next != t) && (next != a) ) {
437 void *next = (
char *)a->
ptr + a->
size;
438 t = chunk_ptr(a->
next);
439 if ( (next != t) && (next != f) ) {
446 if ( mem != __memsize ) {
469 list_print_info( __shmem ? __shmem_header->
free_list_head() : __free_list_head );
479 list_print_info( __shmem ? __shmem_header->
alloc_list_head() : __alloc_list_head );
491 printf(
"free chunks: %6u, alloc chunks: %6u, max free: %10u, max alloc: %10u, overhang: %10u\n",
492 list_length( __shmem ? __shmem_header->
free_list_head() : __free_list_head),
493 list_length( __shmem ? __shmem_header->
alloc_list_head() : __alloc_list_head),
528 free_size += l->
size;
529 l = chunk_ptr(l->
next);
542 unsigned int alloc_size = 0;
545 alloc_size += l->
size;
546 l = chunk_ptr(l->
next);
558 return list_length( __shmem ? __shmem_header->
alloc_list_head() : __alloc_list_head );
568 return list_length( __shmem ? __shmem_header->
free_list_head() : __free_list_head );
589 return __shmem ? __shmem_header->
version() : 0;
636 if (__shmem) __shmem->
unlock();
666 unsigned int overhang = 0;
670 a = chunk_ptr(a->
next);
681 BlackBoardMemoryManager::cleanup_free_chunks()
683 bool modified =
true;
689 l = __shmem ? __shmem_header->
free_list_head() : __free_list_head;
690 n = chunk_ptr(l->
next);
699 n = chunk_ptr(l->
next);
732 new_head = chunk_ptr(l->
next);
737 l = chunk_ptr(l->
next);
761 if ( addel->
ptr < l->
ptr ) {
763 addel->
next = chunk_addr(l);
767 p->
next = chunk_addr(addel);
776 l = chunk_ptr(l->
next);
785 p->
next = chunk_addr(addel);
801 BlackBoardMemoryManager::list_find_ptr(
chunk_list_t *list,
void *ptr)
805 if ( l->
ptr == ptr ) {
809 l = chunk_ptr(l->
next);
822 BlackBoardMemoryManager::list_print_info(
const chunk_list_t *list)
const 828 printf(
"Chunk %3u: 0x%x size=%10u bytes overhang=%10u bytes\n",
830 l = chunk_ptr(l->
next);
841 BlackBoardMemoryManager::list_length(
const chunk_list_t *list)
const 846 list = chunk_ptr(list->
next);
857 BlackBoardMemoryManager::list_get_biggest(
const chunk_list_t *list)
const 865 l = chunk_ptr(l->
next);
938 __shmem = it.__shmem;
956 if ( __cur != NULL ) __cur = chunk_ptr(__cur->next);
981 if ( __cur != NULL ) __cur = chunk_ptr(__cur->next);
998 for (
unsigned int j = 0; (__cur != NULL) && (j < i); ++j) {
999 if ( __cur != NULL ) __cur = chunk_ptr(__cur->next);
1014 for (
unsigned int j = 0; (__cur != NULL) && (j < i); ++j) {
1015 if ( __cur != NULL ) __cur = chunk_ptr(__cur->next);
1029 return (__cur == c.__cur);
1041 return (__cur != c.__cur);
1053 if ( __cur == NULL )
return NULL;
1055 if (__shmem)
return __shmem->
ptr(__cur->ptr);
1056 else return __cur->ptr;
1068 __shmem = c.__shmem;
1081 return ( __cur != NULL ) ? __cur->size : 0;
1093 return ( __cur != NULL ) ? __cur->overhang : 0;
Thrown when BlackBoard memory has been corupted This exception is thrown by the memory manager if the...
ChunkIterator begin()
Get first element for chunk iteration.
void print_performance_info() const
Prints out performance info.
void print_allocated_chunks_info() const
Print out info about allocated chunks.
bool is_creator() const
Determine if the shared memory segment has been created by this instance.
unsigned int overhang_size() const
Get number of overhanging bytes.
void lock_for_write()
Lock shared memory segment for writing.
Fawkes library namespace.
ChunkIterator end()
Get end of chunk list.
void unlock()
Unlock the mutex.
void * operator*() const
Get memory pointer of chunk.
unsigned int size() const
Get size of data segment.
unsigned int overhang() const
Get number of overhanging bytes.
bool try_lock_for_write()
Try to aquire lock on shared memory segment for writing.
bool is_master() const
Check if this BB memory manager is the master.
bool operator==(const ChunkIterator &c) const
Check equality of two iterators.
A NULL pointer was supplied where not allowed.
chunk_list_t * next
offset to next element in list
void * alloc(unsigned int num_bytes)
Allocate memory.
unsigned int num_allocated_chunks() const
Get number of allocated chunks.
void print_free_chunks_info() const
Print out info about free chunks.
unsigned int size
total size of chunk, including overhanging bytes, excluding header
bool try_lock()
Try to lock memory.
Chunk lists as stored in BlackBoard shared memory segment.
unsigned int max_allocated_size() const
Get maximum alloced memory size.
unsigned int overhang
number of overhanging bytes in this chunk
BlackBoardMemoryManager(size_t memsize)
Heap Memory Constructor.
A NULL pointer was supplied where not allowed.
ChunkIterator & operator++()
Increment iterator.
void * addr(void *ptr) const
Get an address from a real pointer.
void set_swapable(bool swapable)
Set shared memory swapable.
ChunkIterator & operator+=(unsigned int i)
Advance by a certain amount.
void * ptr(void *addr) const
Get the real pointer to the data based on an address.
void * ptr
pointer to data memory
Base class for exceptions in Fawkes.
Thrown if shared memory could not be opened.
ChunkIterator & operator+(unsigned int i)
Advance by a certain amount.
unsigned int max_free_size() const
Get maximum allocatable memory size.
ChunkIterator()
Constructor.
Thrown if BlackBoard is not master and master operation has been requested.
void set_destroy_on_delete(bool destroy)
Set deletion behaviour.
Could not attach to shared memory segment.
bool try_lock()
Tries to lock the mutex.
Iterator for memory chunks.
void add_semaphore()
Add semaphore to shared memory segment.
unsigned int memory_size() const
Get size of memory.
void unlock()
Unlock memory.
void check()
Check memory consistency.
void free(void *chunk_ptr)
Free a memory chunk.
unsigned int version() const
Get BlackBoard version.
~BlackBoardMemoryManager()
Destructor.
void * memptr() const
Get a pointer to the shared memory This method returns a pointer to the data-segment of the shared me...
void lock()
Lock this mutex.
bool operator!=(const ChunkIterator &c) const
Check inequality of two iterators.
Mutex mutual exclusion lock.
unsigned int allocated_size() const
Get total allocated memory.
bool is_valid() const
Check validity of shared memory segment.
System ran out of memory and desired operation could not be fulfilled.
void unlock()
Unlock memory.
ChunkIterator & operator=(const ChunkIterator &c)
Assign iterator.
unsigned int free_size() const
Get total free memory.
unsigned int num_free_chunks() const
Get number of free chunks.