24 #include <blackboard/exceptions.h>
25 #include <blackboard/internal/memory_manager.h>
26 #include <blackboard/shmem/header.h>
27 #include <core/exception.h>
28 #include <core/exceptions/software.h>
29 #include <core/exceptions/system.h>
30 #include <core/threading/mutex.h>
32 #include <utils/ipc/shm.h>
33 #include <utils/ipc/shm_exceptions.h>
45 #define BBMM_MIN_FREE_CHUNK_SIZE sizeof(chunk_list_t)
48 #define chunk_ptr(a) (shmem_ ? (chunk_list_t *)shmem_->ptr(a) : a)
49 #define chunk_addr(a) (shmem_ ? (chunk_list_t *)shmem_->addr(a) : a)
104 shmem_header_ = NULL;
106 memory_ = malloc(memsize);
107 mutex_ =
new Mutex();
111 mlock(memory_, memsize_);
120 alloc_list_head_ = NULL;
134 unsigned int version,
136 const char * shmem_token)
154 delete shmem_header_;
161 delete shmem_header_;
170 delete shmem_header_;
195 mutex_ =
new Mutex();
203 delete shmem_header_;
220 BlackBoardMemoryManager::alloc_nolock(
unsigned int num_bytes)
228 if ((l->
size >= num_bytes) &&
229 ((f == NULL) || (l->
size < f->
size))) {
232 l = chunk_ptr(l->
next);
237 throw OutOfMemoryException(
"BlackBoard ran out of memory");
244 free_list_head_ = list_remove(free_list_head_, f);
260 if (f->
size >= (num_bytes + BBMM_MIN_FREE_CHUNK_SIZE +
sizeof(chunk_list_t))) {
262 chunk_list_t *nfc = (chunk_list_t *)((
char *)f +
sizeof(chunk_list_t) + num_bytes);
263 nfc->ptr = shmem_ ? shmem_->
addr((
char *)nfc +
sizeof(chunk_list_t))
264 : (
char *)nfc +
sizeof(chunk_list_t);
265 nfc->size = f->
size - num_bytes -
sizeof(chunk_list_t);
271 free_list_head_ = list_add(free_list_head_, nfc);
285 return shmem_->
ptr(f->
ptr);
287 alloc_list_head_ = list_add(alloc_list_head_, f);
308 ptr = alloc_nolock(num_bytes);
352 cleanup_free_chunks();
357 chunk_list_t *ac = list_find_ptr(alloc_list_head_, ptr);
363 alloc_list_head_ = list_remove(alloc_list_head_, ac);
367 free_list_head_ = list_add(free_list_head_, ac);
370 cleanup_free_chunks();
390 unsigned int mem = 0;
397 t = chunk_ptr(a->
next);
401 if (next != t->
ptr) {
406 }
else if (a == NULL) {
408 t = chunk_ptr(f->
next);
412 if (next != t->
ptr) {
417 }
else if (f->
ptr == a->
ptr) {
419 }
else if (f->
ptr < a->
ptr) {
421 void *next = (
char *)f->
ptr + f->
size;
422 t = chunk_ptr(f->
next);
423 if ((next != t) && (next != a)) {
429 void *next = (
char *)a->
ptr + a->
size;
430 t = chunk_ptr(a->
next);
431 if ((next != t) && (next != f)) {
438 if (mem != memsize_) {
440 "unmanaged memory found, managed memory size != total memory size");
460 list_print_info(shmem_ ? shmem_header_->
free_list_head() : free_list_head_);
469 list_print_info(shmem_ ? shmem_header_->
alloc_list_head() : alloc_list_head_);
480 printf(
"free chunks: %6u, alloc chunks: %6u, max free: %10u, max alloc: %10u, overhang: %10u\n",
481 list_length(shmem_ ? shmem_header_->
free_list_head() : free_list_head_),
482 list_length(shmem_ ? shmem_header_->
alloc_list_head() : alloc_list_head_),
518 l = chunk_ptr(l->
next);
530 unsigned int alloc_size = 0;
533 alloc_size += l->
size;
534 l = chunk_ptr(l->
next);
545 return list_length(shmem_ ? shmem_header_->
alloc_list_head() : alloc_list_head_);
554 return list_length(shmem_ ? shmem_header_->
free_list_head() : free_list_head_);
573 return shmem_ ? shmem_header_->
version() : 0;
647 unsigned int overhang = 0;
651 a = chunk_ptr(a->
next);
661 BlackBoardMemoryManager::cleanup_free_chunks()
663 bool modified =
true;
670 n = chunk_ptr(l->
next);
679 n = chunk_ptr(l->
next);
691 BlackBoardMemoryManager::list_remove(chunk_list_t *list, chunk_list_t *rmel)
694 throw NullPointerException(
"BlackBoardMemoryManager::list_remove: list == NULL");
696 throw NullPointerException(
"BlackBoardMemoryManager::list_remove: rmel == NULL");
698 chunk_list_t *new_head = list;
699 chunk_list_t *l = list;
700 chunk_list_t *p = NULL;
710 new_head = chunk_ptr(l->next);
715 l = chunk_ptr(l->next);
728 BlackBoardMemoryManager::list_add(chunk_list_t *list, chunk_list_t *addel)
731 throw NullPointerException(
"BlackBoardMemoryManager::list_add: addel == NULL");
733 chunk_list_t *new_head = list;
734 chunk_list_t *l = list;
735 chunk_list_t *p = NULL;
738 if (addel->ptr < l->ptr) {
740 addel->next = chunk_addr(l);
744 p->next = chunk_addr(addel);
753 l = chunk_ptr(l->next);
762 p->next = chunk_addr(addel);
777 BlackBoardMemoryManager::list_find_ptr(chunk_list_t *list,
void *ptr)
779 chunk_list_t *l = list;
785 l = chunk_ptr(l->next);
797 BlackBoardMemoryManager::list_print_info(
const chunk_list_t *list)
const
799 chunk_list_t *l = (chunk_list_t *)list;
803 printf(
"Chunk %3u: 0x%x size=%10u bytes overhang=%10u bytes\n",
805 (
unsigned int)(
size_t)l->ptr,
808 l = chunk_ptr(l->next);
817 BlackBoardMemoryManager::list_length(
const chunk_list_t *list)
const
822 list = chunk_ptr(list->next);
832 BlackBoardMemoryManager::list_get_biggest(
const chunk_list_t *list)
const
834 chunk_list_t *b = (chunk_list_t *)list;
835 chunk_list_t *l = (chunk_list_t *)list;
837 if (l->size > b->size) {
840 l = chunk_ptr(l->next);
849 BlackBoardMemoryManager::ChunkIterator
927 cur_ = chunk_ptr(cur_->next);
952 cur_ = chunk_ptr(cur_->next);
968 for (
unsigned int j = 0; (cur_ != NULL) && (j < i); ++j) {
970 cur_ = chunk_ptr(cur_->next);
984 for (
unsigned int j = 0; (cur_ != NULL) && (j < i); ++j) {
986 cur_ = chunk_ptr(cur_->next);
999 return (cur_ == c.cur_);
1010 return (cur_ != c.cur_);
1025 return shmem_->
ptr(cur_->ptr);
1050 return (cur_ != NULL) ? cur_->size : 0;
1061 return (cur_ != NULL) ? cur_->overhang : 0;
Thrown when BlackBoard memory has been corupted This exception is thrown by the memory manager if the...
Thrown if shared memory could not be opened.
Thrown if BlackBoard is not master and master operation has been requested.
A NULL pointer was supplied where not allowed.
Iterator for memory chunks.
unsigned int size() const
Get size of data segment.
bool operator!=(const ChunkIterator &c) const
Check inequality of two iterators.
bool operator==(const ChunkIterator &c) const
Check equality of two iterators.
ChunkIterator & operator=(const ChunkIterator &c)
Assign iterator.
unsigned int overhang() const
Get number of overhanging bytes.
ChunkIterator & operator++()
Increment iterator.
ChunkIterator & operator+=(unsigned int i)
Advance by a certain amount.
void * operator*() const
Get memory pointer of chunk.
ChunkIterator & operator+(unsigned int i)
Advance by a certain amount.
ChunkIterator()
Constructor.
unsigned int overhang_size() const
Get number of overhanging bytes.
unsigned int num_free_chunks() const
Get number of free chunks.
void unlock()
Unlock memory.
void * alloc(unsigned int num_bytes)
Allocate memory.
void print_free_chunks_info() const
Print out info about free chunks.
void print_allocated_chunks_info() const
Print out info about allocated chunks.
unsigned int memory_size() const
Get size of memory.
void free(void *chunk_ptr)
Free a memory chunk.
unsigned int max_free_size() const
Get maximum allocatable memory size.
~BlackBoardMemoryManager()
Destructor.
ChunkIterator end()
Get end of chunk list.
void check()
Check memory consistency.
bool try_lock()
Try to lock memory.
void print_performance_info() const
Prints out performance info.
ChunkIterator begin()
Get first element for chunk iteration.
unsigned int allocated_size() const
Get total allocated memory.
unsigned int free_size() const
Get total free memory.
unsigned int version() const
Get BlackBoard version.
BlackBoardMemoryManager(size_t memsize)
Heap Memory Constructor.
unsigned int num_allocated_chunks() const
Get number of allocated chunks.
unsigned int max_allocated_size() const
Get maximum alloced memory size.
bool is_master() const
Check if this BB memory manager is the master.
Base class for exceptions in Fawkes.
Mutex mutual exclusion lock.
bool try_lock()
Tries to lock the mutex.
void lock()
Lock this mutex.
void unlock()
Unlock the mutex.
void * addr(void *ptr) const
Get an address from a real pointer.
bool is_valid() const
Check validity of shared memory segment.
void add_semaphore()
Add semaphore to shared memory segment.
void lock_for_write()
Lock shared memory segment for writing.
void * memptr() const
Get a pointer to the shared memory This method returns a pointer to the data-segment of the shared me...
void * ptr(void *addr) const
Get the real pointer to the data based on an address.
void unlock()
Unlock memory.
bool try_lock_for_write()
Try to aquire lock on shared memory segment for writing.
void set_destroy_on_delete(bool destroy)
Set deletion behaviour.
void set_swapable(bool swapable)
Set shared memory swapable.
bool is_creator() const
Determine if the shared memory segment has been created by this instance.
Could not attach to shared memory segment.
Fawkes library namespace.
Chunk lists as stored in BlackBoard shared memory segment.
unsigned int size
total size of chunk, including overhanging bytes, excluding header
chunk_list_t * next
offset to next element in list
unsigned int overhang
number of overhanging bytes in this chunk
void * ptr
pointer to data memory