talloc: Add talloc_pooled_object
authorVolker Lendecke <vl@samba.org>
Fri, 6 Sep 2013 22:15:32 +0000 (15:15 -0700)
committerStefan Metzmacher <metze@samba.org>
Tue, 10 Mar 2015 09:55:38 +0000 (10:55 +0100)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit e82320e5197bcdd0330bc829c0963ad09854a36c)

lib/talloc/ABI/pytalloc-util-2.1.0.sigs [new file with mode: 0644]
lib/talloc/ABI/talloc-2.1.0.sigs [new file with mode: 0644]
lib/talloc/talloc.c
lib/talloc/talloc.h
lib/talloc/wscript

diff --git a/lib/talloc/ABI/pytalloc-util-2.1.0.sigs b/lib/talloc/ABI/pytalloc-util-2.1.0.sigs
new file mode 100644 (file)
index 0000000..961c1a8
--- /dev/null
@@ -0,0 +1,6 @@
+pytalloc_CObject_FromTallocPtr: PyObject *(void *)
+pytalloc_Check: int (PyObject *)
+pytalloc_GetObjectType: PyTypeObject *(void)
+pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
+pytalloc_steal: PyObject *(PyTypeObject *, void *)
+pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *)
diff --git a/lib/talloc/ABI/talloc-2.1.0.sigs b/lib/talloc/ABI/talloc-2.1.0.sigs
new file mode 100644 (file)
index 0000000..eae12cc
--- /dev/null
@@ -0,0 +1,64 @@
+_talloc: void *(const void *, size_t)
+_talloc_array: void *(const void *, size_t, unsigned int, const char *)
+_talloc_free: int (void *, const char *)
+_talloc_get_type_abort: void *(const void *, const char *, const char *)
+_talloc_memdup: void *(const void *, const void *, size_t, const char *)
+_talloc_move: void *(const void *, const void *)
+_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t)
+_talloc_realloc: void *(const void *, void *, size_t, const char *)
+_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *)
+_talloc_reference_loc: void *(const void *, const void *, const char *)
+_talloc_set_destructor: void (const void *, int (*)(void *))
+_talloc_steal_loc: void *(const void *, const void *, const char *)
+_talloc_zero: void *(const void *, size_t, const char *)
+_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *)
+talloc_asprintf: char *(const void *, const char *, ...)
+talloc_asprintf_append: char *(char *, const char *, ...)
+talloc_asprintf_append_buffer: char *(char *, const char *, ...)
+talloc_autofree_context: void *(void)
+talloc_check_name: void *(const void *, const char *)
+talloc_disable_null_tracking: void (void)
+talloc_enable_leak_report: void (void)
+talloc_enable_leak_report_full: void (void)
+talloc_enable_null_tracking: void (void)
+talloc_enable_null_tracking_no_autofree: void (void)
+talloc_find_parent_byname: void *(const void *, const char *)
+talloc_free_children: void (void *)
+talloc_get_name: const char *(const void *)
+talloc_get_size: size_t (const void *)
+talloc_increase_ref_count: int (const void *)
+talloc_init: void *(const char *, ...)
+talloc_is_parent: int (const void *, const void *)
+talloc_named: void *(const void *, size_t, const char *, ...)
+talloc_named_const: void *(const void *, size_t, const char *)
+talloc_parent: void *(const void *)
+talloc_parent_name: const char *(const void *)
+talloc_pool: void *(const void *, size_t)
+talloc_realloc_fn: void *(const void *, void *, size_t)
+talloc_reference_count: size_t (const void *)
+talloc_reparent: void *(const void *, const void *, const void *)
+talloc_report: void (const void *, FILE *)
+talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *)
+talloc_report_depth_file: void (const void *, int, int, FILE *)
+talloc_report_full: void (const void *, FILE *)
+talloc_set_abort_fn: void (void (*)(const char *))
+talloc_set_log_fn: void (void (*)(const char *))
+talloc_set_log_stderr: void (void)
+talloc_set_memlimit: int (const void *, size_t)
+talloc_set_name: const char *(const void *, const char *, ...)
+talloc_set_name_const: void (const void *, const char *)
+talloc_show_parents: void (const void *, FILE *)
+talloc_strdup: char *(const void *, const char *)
+talloc_strdup_append: char *(char *, const char *)
+talloc_strdup_append_buffer: char *(char *, const char *)
+talloc_strndup: char *(const void *, const char *, size_t)
+talloc_strndup_append: char *(char *, const char *, size_t)
+talloc_strndup_append_buffer: char *(char *, const char *, size_t)
+talloc_total_blocks: size_t (const void *)
+talloc_total_size: size_t (const void *)
+talloc_unlink: int (const void *, void *)
+talloc_vasprintf: char *(const void *, const char *, va_list)
+talloc_vasprintf_append: char *(char *, const char *, va_list)
+talloc_vasprintf_append_buffer: char *(char *, const char *, va_list)
+talloc_version_major: int (void)
+talloc_version_minor: int (void)
index 198bab95f6a5851696f34db6a854e3ed0955bc53..1cb4d7dead792dad9bf362a1fb1025b3f802767d 100644 (file)
@@ -684,6 +684,72 @@ _PUBLIC_ void *talloc_pool(const void *context, size_t size)
        return result;
 }
 
+/*
+ * Create a talloc pool correctly sized for a basic size plus
+ * a number of subobjects whose total size is given. Essentially
+ * a custom allocator for talloc to reduce fragmentation.
+ */
+
+_PUBLIC_ void *_talloc_pooled_object(const void *ctx,
+                                    size_t type_size,
+                                    const char *type_name,
+                                    unsigned num_subobjects,
+                                    size_t total_subobjects_size)
+{
+       size_t poolsize, subobjects_slack, tmp;
+       struct talloc_chunk *tc;
+       struct talloc_pool_hdr *pool_hdr;
+       void *ret;
+
+       poolsize = type_size + total_subobjects_size;
+
+       if ((poolsize < type_size) || (poolsize < total_subobjects_size)) {
+               goto overflow;
+       }
+
+       if (num_subobjects == UINT_MAX) {
+               goto overflow;
+       }
+       num_subobjects += 1;       /* the object body itself */
+
+       /*
+        * Alignment can increase the pool size by at most 15 bytes per object
+        * plus alignment for the object itself
+        */
+       subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects;
+       if (subobjects_slack < num_subobjects) {
+               goto overflow;
+       }
+
+       tmp = poolsize + subobjects_slack;
+       if ((tmp < poolsize) || (tmp < subobjects_slack)) {
+               goto overflow;
+       }
+       poolsize = tmp;
+
+       ret = talloc_pool(ctx, poolsize);
+       if (ret == NULL) {
+               return NULL;
+       }
+
+       tc = talloc_chunk_from_ptr(ret);
+       tc->size = type_size;
+
+       pool_hdr = talloc_pool_from_chunk(tc);
+
+#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
+       VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size);
+#endif
+
+       pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size));
+
+       talloc_set_name_const(ret, type_name);
+       return ret;
+
+overflow:
+       return NULL;
+}
+
 /*
   setup a destructor to be called on free of a pointer
   the destructor should return 0 on success, or -1 on failure.
index aa9864b436fea9a4fa444abdd8cb3b24d8b29dbf..1b59390e33aa467811b00b04bc7d35ccab2d582c 100644 (file)
@@ -847,6 +847,43 @@ void *talloc_find_parent_bytype(const void *ptr, #type);
  */
 void *talloc_pool(const void *context, size_t size);
 
+#ifdef DOXYGEN
+/**
+ * @brief Allocate a talloc object as/with an additional pool.
+ *
+ * This is like talloc_pool(), but's it's more flexible
+ * and allows an object to be a pool for its children.
+ *
+ * @param[in] ctx                   The talloc context to hang the result off.
+ *
+ * @param[in] type                  The type that we want to allocate.
+ *
+ * @param[in] num_subobjects        The expected number of subobjects, which will
+ *                                  be allocated within the pool. This allocates
+ *                                  space for talloc_chunk headers.
+ *
+ * @param[in] total_subobjects_size The size that all subobjects can use in total.
+ *
+ *
+ * @return              The allocated talloc object, NULL on error.
+ */
+void *talloc_pooled_object(const void *ctx, #type,
+                          unsigned num_subobjects,
+                          size_t total_subobjects_size);
+#else
+#define talloc_pooled_object(_ctx, _type, \
+                            _num_subobjects, \
+                            _total_subobjects_size) \
+       (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \
+                                       (_num_subobjects), \
+                                       (_total_subobjects_size))
+void *_talloc_pooled_object(const void *ctx,
+                           size_t type_size,
+                           const char *type_name,
+                           unsigned num_subobjects,
+                           size_t total_subobjects_size);
+#endif
+
 /**
  * @brief Free a talloc chunk and NULL out the pointer.
  *
index ecc5e24d4755f2dd08e202d998f4eff403821b91..1ca41f69dc1af2f1314b1ce7be70eb0863f5f782 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'talloc'
-VERSION = '2.0.8'
+VERSION = '2.1.0'
 
 
 blddir = 'bin'