int main(void) { uint16_t i; message_t *m; /*** do one-time pool init for app */ init_mpool(); /*** use the pool */ for (i = 0; i < 1000; i++) { /* grab a message from the pool * linked list: 31 clocks, <16 us on tmote * array impl: 40 clocks, 10 us on tmote */ if ((m = get_from_pool()) == NULL) return FAIL; /* ...use it... */ /* put it back when done * linked list: 26 clocks, <7 us on tmote * array impl: 44 clocks, 11 us on tmote */ return_to_pool(m); } /*** linked list is almost 50% faster *** *** this is largely due to the s-l-o-w multiply-by-46 *** ***/ return SUCCESS; }
memory_pool::pointer memory_pool::allocate(std::size_t size) { if (size >= lower && size <= upper) { std::unique_lock<std::mutex> lock(mutex); std::unique_ptr<uint8_t[]> ptr; if (!pool.empty()) { ptr.reset(pool.top().release()); pool.pop(); lock.unlock(); log_debug("allocating %d bytes from pool", size); } else { lock.unlock(); ptr = allocate_for_pool(); log_debug("allocating %d bytes which will be added to the pool", size); } // The pool may be discarded while the memory is still allocated: in // this case, it is simply freed. std::weak_ptr<memory_pool> self(shared_from_this()); return pointer(ptr.release(), [self] (std::uint8_t *p) { return_to_pool(self, p); }); } else { log_debug("allocating %d bytes without using the pool", size); return pointer(new std::uint8_t[size], std::default_delete<std::uint8_t[]>()); } }