Update libcork to 0.15.0 (#856)

Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
This commit is contained in:
Syrone Wong
2016-09-29 18:00:15 -05:00
committed by Max Lv
parent c9c970cee5
commit dbad716c3d
27 changed files with 1028 additions and 268 deletions
+7 -3
View File
@@ -1,10 +1,9 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2011-2013, RedJack, LLC.
* Copyright © 2011-2015, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license
* details.
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
@@ -28,6 +27,11 @@
/* Otherwise autodetect! */
/**** VERSION ****/
#include <libcork/config/version.h>
/**** ARCHITECTURES ****/
#include <libcork/config/arch.h>
+25
View File
@@ -0,0 +1,25 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2015, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
#ifndef LIBCORK_CONFIG_VERSION_H
#define LIBCORK_CONFIG_VERSION_H
/*-----------------------------------------------------------------------
* Library version
*/
#define CORK_CONFIG_VERSION_MAJOR 0
#define CORK_CONFIG_VERSION_MINOR 15
#define CORK_CONFIG_VERSION_PATCH 0
#define CORK_CONFIG_VERSION_STRING "0.15.0"
#define CORK_CONFIG_REVISION "d6ecc2cfbcdf5013038a72b4544f7d9e6eb8f92d"
#endif /* LIBCORK_CONFIG_VERSION_H */
+368 -34
View File
@@ -1,75 +1,409 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2011-2012, RedJack, LLC.
* Copyright © 2011-2014, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license
* details.
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
#ifndef LIBCORK_CORE_ALLOCATOR_H
#define LIBCORK_CORE_ALLOCATOR_H
#include <assert.h>
#include <stdlib.h>
#include <libcork/core/api.h>
#include <libcork/core/attributes.h>
#include <libcork/core/callbacks.h>
#include <libcork/core/error.h>
#include <libcork/core/types.h>
/*-----------------------------------------------------------------------
* Recoverable
* Allocator interface
*/
#define cork_xmalloc malloc
#define cork_xcalloc calloc
#define cork_xfree free
struct cork_alloc;
#if CORK_HAVE_REALLOCF
#define cork_xrealloc reallocf
#else
CORK_API void *
cork_xrealloc(void *ptr, size_t new_size) CORK_ATTR_MALLOC;
#endif
typedef void *
(*cork_alloc_calloc_f)(const struct cork_alloc *alloc,
size_t count, size_t size);
/* type-based macros */
#define cork_xnew(type) ((type *) cork_xmalloc(sizeof(type)))
typedef void *
(*cork_alloc_malloc_f)(const struct cork_alloc *alloc, size_t size);
/* string-related functions */
/* Must not free `ptr` if allocation fails. */
typedef void *
(*cork_alloc_realloc_f)(const struct cork_alloc *alloc, void *ptr,
size_t old_size, size_t new_size);
CORK_API const char *
cork_xstrdup(const char *str);
typedef void
(*cork_alloc_free_f)(const struct cork_alloc *alloc, void *ptr, size_t size);
struct cork_alloc {
const struct cork_alloc *parent;
void *user_data;
cork_free_f free_user_data;
cork_alloc_calloc_f calloc;
cork_alloc_malloc_f malloc;
cork_alloc_realloc_f realloc;
cork_alloc_calloc_f xcalloc;
cork_alloc_malloc_f xmalloc;
cork_alloc_realloc_f xrealloc;
cork_alloc_free_f free;
};
/* NOT thread-safe; must be called before most other libcork functions.
* Allocator will automatically be freed at process exit. */
CORK_API struct cork_alloc *
cork_alloc_new_alloc(const struct cork_alloc *parent);
CORK_API const char *
cork_xstrndup(const char *str, size_t size);
CORK_API void
cork_strfree(const char *str);
cork_alloc_set_user_data(struct cork_alloc *alloc,
void *user_data, cork_free_f free_user_data);
/* These variants must always return a valid pointer. If allocation fails, they
* should abort the process or transfer control in some other way to an error
* handler or cleanup routine.
*
* If you only provide implementations of the `x` variants, we'll provide
* default implementations of these that abort the process if a memory
* allocation fails. */
CORK_API void
cork_alloc_set_calloc(struct cork_alloc *alloc, cork_alloc_calloc_f calloc);
CORK_API void
cork_alloc_set_malloc(struct cork_alloc *alloc, cork_alloc_malloc_f malloc);
CORK_API void
cork_alloc_set_realloc(struct cork_alloc *alloc, cork_alloc_realloc_f realloc);
/* These variants can return a NULL pointer if allocation fails. */
CORK_API void
cork_alloc_set_xcalloc(struct cork_alloc *alloc, cork_alloc_calloc_f xcalloc);
CORK_API void
cork_alloc_set_xmalloc(struct cork_alloc *alloc, cork_alloc_malloc_f xmalloc);
CORK_API void
cork_alloc_set_xrealloc(struct cork_alloc *alloc,
cork_alloc_realloc_f xrealloc);
CORK_API void
cork_alloc_set_free(struct cork_alloc *alloc, cork_alloc_free_f free);
/* Low-level use of an allocator. */
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_calloc(const struct cork_alloc *alloc, size_t count, size_t size)
{
return alloc->calloc(alloc, count, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_malloc(const struct cork_alloc *alloc, size_t size)
{
return alloc->malloc(alloc, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_realloc(const struct cork_alloc *alloc, void *ptr,
size_t old_size, size_t new_size)
{
return alloc->realloc(alloc, ptr, old_size, new_size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_xcalloc(const struct cork_alloc *alloc, size_t count, size_t size)
{
return alloc->xcalloc(alloc, count, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_xmalloc(const struct cork_alloc *alloc, size_t size)
{
return alloc->xmalloc(alloc, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_xrealloc(const struct cork_alloc *alloc, void *ptr,
size_t old_size, size_t new_size)
{
return alloc->xrealloc(alloc, ptr, old_size, new_size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_alloc_xreallocf(const struct cork_alloc *alloc, void *ptr,
size_t old_size, size_t new_size)
{
void *result = alloc->xrealloc(alloc, ptr, old_size, new_size);
if (result == NULL) {
alloc->free(alloc, ptr, old_size);
return NULL;
} else {
return result;
}
}
CORK_ATTR_UNUSED
static void
cork_alloc_free(const struct cork_alloc *alloc, void *ptr, size_t size)
{
return alloc->free(alloc, ptr, size);
}
CORK_ATTR_UNUSED
static void
cork_alloc_cfree(const struct cork_alloc *alloc, void *ptr,
size_t count, size_t size)
{
assert(count < (SIZE_MAX / size));
return alloc->free(alloc, ptr, count * size);
}
#define cork_alloc_new(alloc, type) \
cork_alloc_malloc((alloc), sizeof(type))
#define cork_alloc_xnew(alloc, type) \
cork_alloc_xmalloc((alloc), sizeof(type))
#define cork_alloc_delete(alloc, type, ptr) \
cork_alloc_free((alloc), (ptr), sizeof(type))
/* string-related helper functions */
CORK_ATTR_MALLOC
CORK_API const char *
cork_alloc_strdup(const struct cork_alloc *alloc, const char *str);
CORK_ATTR_MALLOC
CORK_API const char *
cork_alloc_strndup(const struct cork_alloc *alloc,
const char *str, size_t size);
CORK_ATTR_MALLOC
CORK_API const char *
cork_alloc_xstrdup(const struct cork_alloc *alloc, const char *str);
CORK_ATTR_MALLOC
CORK_API const char *
cork_alloc_xstrndup(const struct cork_alloc *alloc,
const char *str, size_t size);
CORK_API void
cork_alloc_strfree(const struct cork_alloc *alloc, const char *str);
/*-----------------------------------------------------------------------
* Abort on failure
* Using the allocator interface
*/
CORK_API void *
cork_malloc(size_t size) CORK_ATTR_MALLOC;
/* All of the functions that you use to actually allocate memory assume that
* cork_current_allocator() returns the allocator instance that should be used.
* Your easiest approach is to do nothing special; in that case, all of the
* libcork memory allocation functions will transparently use the standard
* malloc/free family of functions.
*
* If you're writing a library, and want to allow your library clients to
* provide a separate custom memory allocator then the one they can already
* override for libcork itself, you should declare a pair of functions for
* getting and setting your library's current allocator (like libcork itself
* does), and (only when compiling the source of your library) define
* `cork_current_allocator` as a macro that aliases the getter function. That
* will cause the libcork memory allocation functions to use whichever allocator
* your library user has provided.
*
* If you're writing an application, and want to provide a single allocator that
* all libcork-using libraries will pick up, just call cork_set_allocator before
* calling any other library functions. Other libraries will use this as a
* default and everything that uses libcork's memory allocation functions will
* use your custom allocator. */
CORK_API void *
cork_calloc(size_t count, size_t size) CORK_ATTR_MALLOC;
CORK_API void *
cork_realloc(void *ptr, size_t new_size) CORK_ATTR_MALLOC;
/* libcork's current allocator */
CORK_API const char *
cork_strdup(const char *src) CORK_ATTR_MALLOC;
extern const struct cork_alloc *cork_allocator;
CORK_API const char *
cork_strndup(const char *src, size_t size) CORK_ATTR_MALLOC;
/* We take control and will free when the process exits. This is *NOT*
* thread-safe; it's only safe to call before you've called *ANY* other libcork
* function (or any function from any other library that uses libcork). You can
* only call this at most once. */
CORK_API void
cork_set_allocator(const struct cork_alloc *alloc);
#define cork_new(type) \
cork_malloc(sizeof(type))
/* The current allocator of whichever library is being compiled. */
#if !defined(cork_current_allocator)
#define cork_current_allocator() (cork_allocator)
#endif
/* using an allocator */
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_calloc(size_t count, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_calloc(alloc, count, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_malloc(size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_malloc(alloc, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_realloc(void *ptr, size_t old_size, size_t new_size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_realloc(alloc, ptr, old_size, new_size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_xcalloc(size_t count, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xcalloc(alloc, count, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_xmalloc(size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xmalloc(alloc, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_xrealloc(void *ptr, size_t old_size, size_t new_size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xrealloc(alloc, ptr, old_size, new_size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static void *
cork_xreallocf(void *ptr, size_t old_size, size_t new_size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xreallocf(alloc, ptr, old_size, new_size);
}
CORK_ATTR_UNUSED
static void
cork_free(void *ptr, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
cork_alloc_free(alloc, ptr, size);
}
CORK_ATTR_UNUSED
static void
cork_cfree(void *ptr, size_t count, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
cork_alloc_cfree(alloc, ptr, count, size);
}
#define cork_new(type) cork_malloc(sizeof(type))
#define cork_xnew(type) cork_xmalloc(sizeof(type))
#define cork_delete(type, ptr) cork_free((ptr), sizeof(type))
/* string-related helper functions */
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static const char *
cork_strdup(const char *str)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_strdup(alloc, str);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static const char *
cork_strndup(const char *str, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_strndup(alloc, str, size);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static const char *
cork_xstrdup(const char *str)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xstrdup(alloc, str);
}
CORK_ATTR_MALLOC
CORK_ATTR_UNUSED
static const char *
cork_xstrndup(const char *str, size_t size)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_xstrndup(alloc, str, size);
}
CORK_ATTR_UNUSED
static void
cork_strfree(const char *str)
{
const struct cork_alloc *alloc = cork_current_allocator();
return cork_alloc_strfree(alloc, str);
}
/*-----------------------------------------------------------------------
* Debugging allocator
*/
/* An allocator that adds some additional debugging checks:
*
* - We verify that every "free" call (cork_free, cork_cfree, cork_delete,
* cork_realloc) is passed the "correct" size — i.e., the same size that was
* passed in to the correspond "new" call (cork_malloc, cork_calloc,
* cork_realloc, cork_new).
*/
struct cork_alloc *
cork_debug_alloc_new(const struct cork_alloc *parent);
#endif /* LIBCORK_CORE_ALLOCATOR_H */
+34 -3
View File
@@ -1,18 +1,23 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2012, RedJack, LLC.
* Copyright © 2012-2015, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license
* details.
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
#ifndef LIBCORK_CORE_API_H
#define LIBCORK_CORE_API_H
#include <libcork/config.h>
#include <libcork/core/attributes.h>
/*-----------------------------------------------------------------------
* Calling conventions
*/
/* If you're using libcork as a shared library, you don't need to do anything
* special; the following will automatically set things up so that libcork's
* public symbols are imported from the library. When we build the shared
@@ -22,4 +27,30 @@
#define CORK_API CORK_IMPORT
#endif
/*-----------------------------------------------------------------------
* Library version
*/
#define CORK_VERSION_MAJOR CORK_CONFIG_VERSION_MAJOR
#define CORK_VERSION_MINOR CORK_CONFIG_VERSION_MINOR
#define CORK_VERSION_PATCH CORK_CONFIG_VERSION_PATCH
#define CORK_MAKE_VERSION(major, minor, patch) \
((major * 1000000) + (minor * 1000) + patch)
#define CORK_VERSION \
CORK_MAKE_VERSION(CORK_VERSION_MAJOR, \
CORK_VERSION_MINOR, \
CORK_VERSION_PATCH)
CORK_API const char *
cork_version_string(void)
CORK_ATTR_CONST;
CORK_API const char *
cork_revision_string(void)
CORK_ATTR_CONST;
#endif /* LIBCORK_CORE_API_H */
+4 -1
View File
@@ -1,6 +1,6 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2013, RedJack, LLC.
* Copyright © 2013-2014, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license details.
@@ -39,5 +39,8 @@ typedef void
typedef void *
(*cork_new_f)(void *user_data);
typedef int
(*cork_run_f)(void *user_data);
#endif /* LIBCORK_CORE_CALLBACKS_H */
+13 -1
View File
@@ -1,6 +1,6 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2012-2013, RedJack, LLC.
* Copyright © 2012-2015, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license details.
@@ -41,6 +41,18 @@ CORK_API void
cork_mempool_free(struct cork_mempool *mp);
CORK_API void
cork_mempool_set_user_data(struct cork_mempool *mp,
void *user_data, cork_free_f free_user_data);
CORK_API void
cork_mempool_set_init_object(struct cork_mempool *mp, cork_init_f init_object);
CORK_API void
cork_mempool_set_done_object(struct cork_mempool *mp, cork_done_f done_object);
/* Deprecated; you should now use separate calls to cork_mempool_set_user_data,
* cork_mempool_set_init_object, and cork_mempool_set_done_object. */
CORK_API void
cork_mempool_set_callbacks(struct cork_mempool *mp,
void *user_data, cork_free_f free_user_data,
+5 -4
View File
@@ -1,10 +1,9 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2012-2013, RedJack, LLC.
* Copyright © 2012-2014, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license
* details.
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
@@ -14,6 +13,7 @@
#include <stdarg.h>
#include <libcork/core/api.h>
#include <libcork/core/callbacks.h>
#include <libcork/core/types.h>
#include <libcork/ds/stream.h>
#include <libcork/threads/basics.h>
@@ -126,7 +126,8 @@ struct cork_subprocess;
/* Takes control of body */
CORK_API struct cork_subprocess *
cork_subprocess_new(struct cork_thread_body *body,
cork_subprocess_new(void *user_data, cork_free_f free_user_data,
cork_run_f run,
struct cork_stream_consumer *stdout_consumer,
struct cork_stream_consumer *stderr_consumer,
int *exit_code);
@@ -23,14 +23,19 @@
#define cork_int_atomic_add __sync_add_and_fetch
#define cork_uint_atomic_add __sync_add_and_fetch
#define cork_size_atomic_add __sync_add_and_fetch
#define cork_int_atomic_pre_add __sync_fetch_and_add
#define cork_uint_atomic_pre_add __sync_fetch_and_add
#define cork_size_atomic_pre_add __sync_fetch_and_add
#define cork_int_atomic_sub __sync_sub_and_fetch
#define cork_uint_atomic_sub __sync_sub_and_fetch
#define cork_size_atomic_sub __sync_sub_and_fetch
#define cork_int_atomic_pre_sub __sync_fetch_and_sub
#define cork_uint_atomic_pre_sub __sync_fetch_and_sub
#define cork_size_atomic_pre_sub __sync_fetch_and_sub
#define cork_int_cas __sync_val_compare_and_swap
#define cork_uint_cas __sync_val_compare_and_swap
#define cork_size_cas __sync_val_compare_and_swap
#define cork_ptr_cas __sync_val_compare_and_swap
+29 -24
View File
@@ -1,10 +1,9 @@
/* -*- coding: utf-8 -*-
* ----------------------------------------------------------------------
* Copyright © 2012, RedJack, LLC.
* Copyright © 2012-2014, RedJack, LLC.
* All rights reserved.
*
* Please see the COPYING file in this distribution for license
* details.
* Please see the COPYING file in this distribution for license details.
* ----------------------------------------------------------------------
*/
@@ -15,6 +14,7 @@
#include <libcork/core/api.h>
#include <libcork/core/attributes.h>
#include <libcork/core/callbacks.h>
#include <libcork/threads/atomics.h>
@@ -32,22 +32,6 @@ CORK_API cork_thread_id
cork_current_thread_get_id(void);
/*-----------------------------------------------------------------------
* Main functions
*/
struct cork_thread_body {
int
(*run)(struct cork_thread_body *self);
void
(*free)(struct cork_thread_body *self);
};
#define cork_thread_body_run(tb) ((tb)->run((tb)))
#define cork_thread_body_free(tb) ((tb)->free((tb)))
/*-----------------------------------------------------------------------
* Threads
*/
@@ -60,7 +44,9 @@ CORK_API struct cork_thread *
cork_current_thread_get(void);
CORK_API struct cork_thread *
cork_thread_new(const char *name, struct cork_thread_body *body);
cork_thread_new(const char *name,
void *user_data, cork_free_f free_user_data,
cork_run_f run);
/* Thread must not have been started yet. */
CORK_API void
@@ -171,20 +157,23 @@ NAME##_get(void) \
return &NAME##__tls; \
}
#define cork_tls_with_alloc(TYPE, NAME, allocate, deallocate) \
cork_tls(TYPE, NAME)
#elif CORK_HAVE_PTHREADS
#include <stdlib.h>
#include <pthread.h>
#include <libcork/core/allocator.h>
#define cork_tls(TYPE, NAME) \
#define cork_tls_with_alloc(TYPE, NAME, allocate, deallocate) \
static pthread_key_t NAME##__tls_key; \
cork_once_barrier(NAME##__tls_barrier); \
\
static void \
NAME##__tls_destroy(void *vself) \
NAME##__tls_destroy(void *self) \
{ \
free(vself); \
deallocate(self); \
} \
\
static void \
@@ -202,12 +191,28 @@ NAME##_get(void) \
cork_once(NAME##__tls_barrier, NAME##__create_key()); \
self = pthread_getspecific(NAME##__tls_key); \
if (CORK_UNLIKELY(self == NULL)) { \
self = cork_calloc(1, sizeof(TYPE)); \
self = allocate(); \
pthread_setspecific(NAME##__tls_key, self); \
} \
return self; \
}
#define cork_tls(TYPE, NAME) \
\
static TYPE * \
NAME##__tls_allocate(void) \
{ \
return cork_calloc(1, sizeof(TYPE)); \
} \
\
static void \
NAME##__tls_deallocate(void *vself) \
{ \
cork_cfree(vself, 1, sizeof(TYPE)); \
} \
\
cork_tls_with_alloc(TYPE, NAME, NAME##__tls_allocate, NAME##__tls_deallocate);
#else
#error "No thread-local storage implementation!"
#endif