+
+/* Return the size of a memory buffer */
+int32_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf)
+{
+ char *cp = (char *)obuf;
+
+ ASSERT(obuf);
+ cp -= HEAD_SIZE;
+ return ((struct abufhead *)cp)->ablen;
+}
+
+/* Realloc pool memory buffer */
+POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, int32_t size)
+{
+ char *cp = (char *)obuf;
+ void *buf;
+ int pool;
+
+ ASSERT(obuf);
+ P(mutex);
+ cp -= HEAD_SIZE;
+ buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE);
+ if (buf == NULL) {
+ V(mutex);
+ Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size);
+ }
+ ((struct abufhead *)buf)->ablen = size;
+ pool = ((struct abufhead *)buf)->pool;
+ if (size > pool_ctl[pool].max_size) {
+ pool_ctl[pool].max_size = size;
+ }
+ V(mutex);
+ return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
+}
+
+POOLMEM *sm_check_pool_memory_size(char *fname, int lineno, POOLMEM *obuf, int32_t size)
+{
+ ASSERT(obuf);
+ if (size <= sizeof_pool_memory(obuf)) {
+ return obuf;
+ }
+ return realloc_pool_memory(obuf, size);
+}
+
+/* Free a memory buffer */
+void sm_free_pool_memory(char *fname, int lineno, POOLMEM *obuf)
+{
+ struct abufhead *buf;
+ int pool;
+
+ ASSERT(obuf);
+ P(mutex);
+ buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
+ pool = buf->pool;
+ pool_ctl[pool].in_use--;
+ if (pool == 0) {
+ free((char *)buf); /* free nonpooled memory */
+ } else { /* otherwise link it to the free pool chain */
+#ifdef DEBUG
+ struct abufhead *next;
+ /* Don't let him free the same buffer twice */
+ for (next=pool_ctl[pool].free_buf; next; next=next->next) {
+ if (next == buf) {
+ Dmsg4(300, "bad free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno);
+ V(mutex); /* unblock the pool */
+ ASSERT(next != buf); /* attempt to free twice */
+ }
+ }
+#endif
+ buf->next = pool_ctl[pool].free_buf;
+ pool_ctl[pool].free_buf = buf;
+ }
+ Dmsg4(300, "free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno);
+ V(mutex);
+}
+
+