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);
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_);
1024 return shmem_->
ptr(cur_->ptr);
1049 return (cur_ != NULL) ? cur_->size : 0;
1060 return (cur_ != NULL) ? cur_->overhang : 0;