--- Functionality changes from Asterisk 14 to Asterisk 15 --------------------
------------------------------------------------------------------------------
+Build System
+------------------
+ * LOW_MEMORY no longer has an effect on Asterisk ABI. Symbols that were
+ previously suppressed by LOW_MEMORY are now replaced by stub functions.
+ Asterisk built with LOW_MEMORY can now successfully load binary modules
+ built without LOW_MEMORY and vice versa.
+
chan_sip
------------------
* If an offer is received with optional SRTP (a media stream with RTP/AVP but
=== UPGRADE-13.txt -- Upgrade info for 12 to 13
=== UPGRADE-14.txt -- Upgrade info for 13 to 14
===========================================================
+
+Build System:
+ - The LOW_MEMORY compile option no longer disables inline API. To disable
+ inline API you must use the DISABLE_INLINE option.
-o "${x}" = "BETTER_BACKTRACES" \
-o "${x}" = "LOTS_OF_SPANS" \
-o "${x}" = "BUILD_NATIVE" \
+ -o "${x}" = "LOW_MEMORY" \
-o "${x}" = "REF_DEBUG" \
-o "${x}" = "AO2_DEBUG" \
-o "${x}" = "REBUILD_PARSERS" \
*/
int ast_shutdown_final(void);
-#if !defined(LOW_MEMORY)
/*!
* \brief Register the version of a source code file with the core.
* \param file the source file name
__ast_unregister_file(__FILE__); \
}
#endif /* !MTX_PROFILE */
-#else /* LOW_MEMORY */
-#define ASTERISK_REGISTER_FILE()
-#endif /* LOW_MEMORY */
-#if !defined(LOW_MEMORY)
/*!
* \brief support for event profiling
*
int ast_add_profile(const char *, uint64_t scale);
int64_t ast_profile(int, int64_t);
int64_t ast_mark(int, int start1_stop0);
-#else /* LOW_MEMORY */
-#define ast_add_profile(a, b) 0
-#define ast_profile(a, b) do { } while (0)
-#define ast_mark(a, b) do { } while (0)
-#endif /* LOW_MEMORY */
/*! \brief
* Definition of various structures that many asterisk files need,
copies of the function body are not built in different modules.
However, since this doesn't work for clang, we go with 'static'
anyway and hope for the best!
- - when LOW_MEMORY is defined, inlining should be disabled
+ - when DISABLE_INLINE is defined, inlining should be disabled
completely, even if the compiler is configured to support it
The AST_INLINE_API macro allows this to happen automatically, when
including the header file
*/
-#if !defined(LOW_MEMORY) && !defined(DISABLE_INLINE)
+#if !defined(DISABLE_INLINE)
#if !defined(AST_API_MODULE)
#if defined(__clang__) || defined(__GNUC_STDC_INLINE__)
#define AST_INLINE_API(hdr, body) hdr; hdr body
#endif
-#else /* defined(LOW_MEMORY) */
+#else /* defined(DISABLE_INLINE) */
#if !defined(AST_API_MODULE)
#define AST_INLINE_API(hdr, body) hdr;
* lock info struct. The lock is marked as pending as the thread is waiting
* on the lock. ast_mark_lock_acquired() will mark it as held by this thread.
*/
-#if !defined(LOW_MEMORY)
#ifdef HAVE_BKTR
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt);
int line_num, const char *func, const char *lock_name, void *lock_addr);
#endif /* HAVE_BKTR */
-#else
-
-#ifdef HAVE_BKTR
-#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS,BUD)
-#else
-#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS)
-#endif /* HAVE_BKTR */
-#endif /* !defined(LOW_MEMORY) */
-
/*!
* \brief Mark the last lock as acquired
*/
-#if !defined(LOW_MEMORY)
void ast_mark_lock_acquired(void *lock_addr);
-#else
-#define ast_mark_lock_acquired(ignore)
-#endif
/*!
* \brief Mark the last lock as failed (trylock)
*/
-#if !defined(LOW_MEMORY)
void ast_mark_lock_failed(void *lock_addr);
-#else
-#define ast_mark_lock_failed(ignore)
-#endif
/*!
* \brief remove lock info for the current thread
* this gets called by ast_mutex_unlock so that information on the lock can
* be removed from the current thread's lock info struct.
*/
-#if !defined(LOW_MEMORY)
#ifdef HAVE_BKTR
void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt);
#else
#endif /* HAVE_BKTR */
void ast_suspend_lock_info(void *lock_addr);
void ast_restore_lock_info(void *lock_addr);
-#else
-#ifdef HAVE_BKTR
-#define ast_remove_lock_info(ignore,me)
-#else
-#define ast_remove_lock_info(ignore)
-#endif /* HAVE_BKTR */
-#define ast_suspend_lock_info(ignore);
-#define ast_restore_lock_info(ignore);
-#endif /* !defined(LOW_MEMORY) */
/*!
* \brief log info for the current lock with ast_log().
* this gets called during deadlock avoidance, so that the information may
* be preserved as to what location originally acquired the lock.
*/
-#if !defined(LOW_MEMORY)
int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size);
-#else
-#define ast_find_lock_info(a,b,c,d,e,f,g,h) -1
-#endif
/*!
* \brief Unlock a lock briefly
* Thread management support (should be moved to lock.h or a different header)
*/
-#define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
+#define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
+#define AST_STACKSIZE_LOW (((sizeof(void *) * 8 * 2) - 16) * 1024)
-#if defined(LOW_MEMORY)
-#define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
-#else
-#define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
-#endif
+int ast_background_stacksize(void);
+
+#define AST_BACKGROUND_STACKSIZE ast_background_stacksize()
void ast_register_thread(char *name);
void ast_unregister_thread(void *id);
};
static AST_RWLIST_HEAD_STATIC(registered_files, registered_file);
+#endif /* ! LOW_MEMORY */
void __ast_register_file(const char *file)
{
+#if !defined(LOW_MEMORY)
struct registered_file *reg;
reg = ast_calloc(1, sizeof(*reg));
AST_RWLIST_WRLOCK(®istered_files);
AST_RWLIST_INSERT_HEAD(®istered_files, reg, list);
AST_RWLIST_UNLOCK(®istered_files);
+#endif /* ! LOW_MEMORY */
}
void __ast_unregister_file(const char *file)
{
+#if !defined(LOW_MEMORY)
struct registered_file *find;
AST_RWLIST_WRLOCK(®istered_files);
if (find) {
ast_free(find);
}
+#endif /* ! LOW_MEMORY */
}
char *ast_complete_source_filename(const char *partial, int n)
{
+#if !defined(LOW_MEMORY)
struct registered_file *find;
size_t len = strlen(partial);
int count = 0;
}
AST_RWLIST_UNLOCK(®istered_files);
return res;
+#else /* if defined(LOW_MEMORY) */
+ return NULL;
+#endif
}
+#if !defined(LOW_MEMORY)
struct thread_list_t {
AST_RWLIST_ENTRY(thread_list_t) list;
char *name;
};
static struct profile_data *prof_data;
+#endif /* ! LOW_MEMORY */
/*! \brief allocates a counter with a given name and scale.
* \return Returns the identifier of the counter.
*/
int ast_add_profile(const char *name, uint64_t scale)
{
+#if !defined(LOW_MEMORY)
int l = sizeof(struct profile_data);
int n = 10; /* default entries */
prof_data->e[n].mark = 0;
prof_data->e[n].scale = scale;
return n;
+#else /* if defined(LOW_MEMORY) */
+ return 0;
+#endif
}
int64_t ast_profile(int i, int64_t delta)
{
+#if !defined(LOW_MEMORY)
if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
return 0;
if (prof_data->e[i].scale > 1)
prof_data->e[i].value += delta;
prof_data->e[i].events++;
return prof_data->e[i].value;
+#else /* if defined(LOW_MEMORY) */
+ return 0;
+#endif
}
+#if !defined(LOW_MEMORY)
/* The RDTSC instruction was introduced on the Pentium processor and is not
* implemented on certain clones, like the Cyrix 586. Hence, the previous
* expectation of __i386__ was in error. */
return 0;
}
#endif
+#endif /* ! LOW_MEMORY */
int64_t ast_mark(int i, int startstop)
{
+#if !defined(LOW_MEMORY)
if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
return 0;
if (startstop == 1)
prof_data->e[i].events++;
}
return prof_data->e[i].mark;
+#else /* if defined(LOW_MEMORY) */
+ return 0;
+#endif
}
+#if !defined(LOW_MEMORY)
#define DEFINE_PROFILE_MIN_MAX_VALUES min = 0; \
max = prof_data->entries;\
if (a->argc > 3) { /* specific entries */ \
#undef pthread_create /* For ast_pthread_create function only */
#endif /* !__linux__ */
-#if !defined(LOW_MEMORY)
-
#ifdef DEBUG_THREADS
+#if !defined(LOW_MEMORY)
/*! \brief A reasonable maximum number of locks a thread would be holding ... */
#define AST_MAX_LOCKS 64
* \brief The thread storage key for per-thread lock info
*/
AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
+#endif /* ! LOW_MEMORY */
+
#ifdef HAVE_BKTR
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
int line_num, const char *func, const char *lock_name, void *lock_addr)
#endif
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
int i;
lock_info->num_locks++;
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
void ast_mark_lock_acquired(void *lock_addr)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
lock_info->locks[lock_info->num_locks - 1].pending = 0;
}
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
void ast_mark_lock_failed(void *lock_addr)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
lock_info->locks[lock_info->num_locks - 1].times_locked--;
}
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
int i = 0;
pthread_mutex_unlock(&lock_info->lock);
return 0;
+#else /* if defined(LOW_MEMORY) */
+ return -1;
+#endif
}
void ast_suspend_lock_info(void *lock_addr)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
int i = 0;
lock_info->locks[i].suspended = 1;
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
void ast_restore_lock_info(void *lock_addr)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
int i = 0;
lock_info->locks[i].suspended = 0;
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
void ast_remove_lock_info(void *lock_addr)
#endif
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
int i = 0;
lock_info->num_locks--;
pthread_mutex_unlock(&lock_info->lock);
+#endif /* ! LOW_MEMORY */
}
+#if !defined(LOW_MEMORY)
static const char *locktype2str(enum ast_lock_type type)
{
switch (type) {
}
ast_reentrancy_unlock(lt);
}
-
+#endif /* ! LOW_MEMORY */
/*! This function can help you find highly temporal locks; locks that happen for a
short time, but at unexpected times, usually at times that create a deadlock,
*/
void ast_log_show_lock(void *this_lock_addr)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
struct ast_str *str;
}
pthread_mutex_unlock(&lock_infos_lock.mutex);
ast_free(str);
+#endif /* ! LOW_MEMORY */
}
struct ast_str *ast_dump_locks(void)
{
+#if !defined(LOW_MEMORY)
struct thr_lock_info *lock_info;
struct ast_str *str;
"\n");
return str;
+#else /* if defined(LOW_MEMORY) */
+ return NULL;
+#endif
}
+#if !defined(LOW_MEMORY)
static char *handle_show_locks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct ast_str *str;
static struct ast_cli_entry utils_cli[] = {
AST_CLI_DEFINE(handle_show_locks, "Show which locks are held by which thread"),
};
-
+#endif /* ! LOW_MEMORY */
#endif /* DEBUG_THREADS */
+#if !defined(LOW_MEMORY)
/*
* support for 'show threads'. The start routine is wrapped by
* dummy_start(), so that ast_register_thread() and
#endif /* !LOW_MEMORY */
+int ast_background_stacksize(void)
+{
+#if !defined(LOW_MEMORY)
+ return AST_STACKSIZE;
+#else
+ return AST_STACKSIZE_LOW;
+#endif
+}
+
int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
void *data, size_t stacksize, const char *file, const char *caller,
int line, const char *start_fn)
int option_debug = 0;
int option_verbose = 0;
-#if !defined(LOW_MEMORY)
void __ast_register_file(const char *file) { }
void __ast_unregister_file(const char *file) { }
-#endif
/*** MODULEINFO
<depend>res_ael_share</depend>
return 0; /* in "standalone" mode, functions are just not avail */
}
-#if !defined(LOW_MEMORY)
int ast_add_profile(const char *x, uint64_t scale)
{
if (!no_comp)
return 0;
}
-#endif
int ast_loader_register(int (*updater)(void))
{
}
#ifdef DEBUG_THREADS
-#if !defined(LOW_MEMORY)
void ast_mark_lock_acquired(void *lock_addr)
{
}
void ast_restore_lock_info(void *lock_addr)
{
}
-#endif /* !defined(LOW_MEMORY) */
#endif /* DEBUG_THREADS */
{
}
-#if !defined(LOW_MEMORY)
int ast_add_profile(const char *, uint64_t scale);
int ast_add_profile(const char *s, uint64_t scale)
{
{
return 0;
}
-#endif /* LOW_MEMORY */
/* end of dummy functions */
#endif
#ifdef DEBUG_THREADS
-#if !defined(LOW_MEMORY)
#ifdef HAVE_BKTR
void ast_store_lock_info(enum ast_lock_type type, const char *filename,
int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt);
{
/* not a lot to do in a standalone w/o threading! */
}
-#endif
#endif /* DEBUG_THREADS */
void __ast_register_file(const char *file);
void __ast_register_file(const char *file) { }
-#if !defined(LOW_MEMORY)
int ast_add_profile(const char *x, uint64_t scale) { return 0;}
-#endif
int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
{
int ret;
void __ast_unregister_file(const char *file)
{
}
-#if !defined(LOW_MEMORY)
int ast_add_profile(const char *x, uint64_t scale) { return 0;}
-#endif
/* Our own version of ast_log, since the expr parser uses it. -- stolen from utils/check_expr.c */
void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__((format(printf,5,6)));
}
#ifdef DEBUG_THREADS
-#if !defined(LOW_MEMORY)
void ast_mark_lock_acquired(void *lock_addr)
{
}
void ast_restore_lock_info(void *lock_addr)
{
}
-#endif /* !defined(LOW_MEMORY) */
#endif /* DEBUG_THREADS */