mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 02:26:23 +00:00
Convert translation core linked list over to read/write based one, since it spends most of it's time only reading.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@46972 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -49,7 +49,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#define MAX_RECALC 200 /* max sample recalc */
|
#define MAX_RECALC 200 /* max sample recalc */
|
||||||
|
|
||||||
/*! \brief the list of translators */
|
/*! \brief the list of translators */
|
||||||
static AST_LIST_HEAD_STATIC(translators, ast_translator);
|
static AST_RWLIST_HEAD_STATIC(translators, ast_translator);
|
||||||
|
|
||||||
struct translator_path {
|
struct translator_path {
|
||||||
struct ast_translator *step; /*!< Next step translator */
|
struct ast_translator *step; /*!< Next step translator */
|
||||||
@@ -256,7 +256,7 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
|
|||||||
source = powerof(source);
|
source = powerof(source);
|
||||||
dest = powerof(dest);
|
dest = powerof(dest);
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_RDLOCK(&translators);
|
||||||
|
|
||||||
while (source != dest) {
|
while (source != dest) {
|
||||||
struct ast_trans_pvt *cur;
|
struct ast_trans_pvt *cur;
|
||||||
@@ -264,14 +264,14 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
|
|||||||
if (!t) {
|
if (!t) {
|
||||||
ast_log(LOG_WARNING, "No translator path from %s to %s\n",
|
ast_log(LOG_WARNING, "No translator path from %s to %s\n",
|
||||||
ast_getformatname(source), ast_getformatname(dest));
|
ast_getformatname(source), ast_getformatname(dest));
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(cur = newpvt(t))) {
|
if (!(cur = newpvt(t))) {
|
||||||
ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
|
ast_log(LOG_WARNING, "Failed to build translator step from %d to %d\n", source, dest);
|
||||||
if (head)
|
if (head)
|
||||||
ast_translator_free_path(head);
|
ast_translator_free_path(head);
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!head)
|
if (!head)
|
||||||
@@ -284,7 +284,7 @@ struct ast_trans_pvt *ast_translator_build_path(int dest, int source)
|
|||||||
source = cur->t->dstfmt;
|
source = cur->t->dstfmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +426,7 @@ static void rebuild_matrix(int samples)
|
|||||||
bzero(tr_matrix, sizeof(tr_matrix));
|
bzero(tr_matrix, sizeof(tr_matrix));
|
||||||
|
|
||||||
/* first, compute all direct costs */
|
/* first, compute all direct costs */
|
||||||
AST_LIST_TRAVERSE(&translators, t, list) {
|
AST_RWLIST_TRAVERSE(&translators, t, list) {
|
||||||
if (!t->active)
|
if (!t->active)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -494,8 +494,6 @@ static int show_translation(int fd, int argc, char *argv[])
|
|||||||
|
|
||||||
if (argc > 5)
|
if (argc > 5)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
|
||||||
|
|
||||||
if (argv[3] && !strcasecmp(argv[3], "recalc")) {
|
if (argv[3] && !strcasecmp(argv[3], "recalc")) {
|
||||||
z = argv[4] ? atoi(argv[4]) : 1;
|
z = argv[4] ? atoi(argv[4]) : 1;
|
||||||
@@ -510,9 +508,13 @@ static int show_translation(int fd, int argc, char *argv[])
|
|||||||
z = MAX_RECALC;
|
z = MAX_RECALC;
|
||||||
}
|
}
|
||||||
ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
|
ast_cli(fd, " Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
|
||||||
|
AST_RWLIST_WRLOCK(&translators);
|
||||||
rebuild_matrix(z);
|
rebuild_matrix(z);
|
||||||
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AST_RWLIST_RDLOCK(&translators);
|
||||||
|
|
||||||
ast_cli(fd, " Translation times between formats (in milliseconds) for one second of data\n");
|
ast_cli(fd, " Translation times between formats (in milliseconds) for one second of data\n");
|
||||||
ast_cli(fd, " Source Format (Rows) Destination Format (Columns)\n\n");
|
ast_cli(fd, " Source Format (Rows) Destination Format (Columns)\n\n");
|
||||||
/* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
|
/* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
|
||||||
@@ -551,7 +553,7 @@ static int show_translation(int fd, int argc, char *argv[])
|
|||||||
ast_build_string(&buf, &left, "\n");
|
ast_build_string(&buf, &left, "\n");
|
||||||
ast_cli(fd, line);
|
ast_cli(fd, line);
|
||||||
}
|
}
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,28 +641,28 @@ int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
|
|||||||
added_cli++;
|
added_cli++;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_WRLOCK(&translators);
|
||||||
|
|
||||||
/* find any existing translators that provide this same srcfmt/dstfmt,
|
/* find any existing translators that provide this same srcfmt/dstfmt,
|
||||||
and put this one in order based on cost */
|
and put this one in order based on cost */
|
||||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
|
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
|
||||||
if ((u->srcfmt == t->srcfmt) &&
|
if ((u->srcfmt == t->srcfmt) &&
|
||||||
(u->dstfmt == t->dstfmt) &&
|
(u->dstfmt == t->dstfmt) &&
|
||||||
(u->cost > t->cost)) {
|
(u->cost > t->cost)) {
|
||||||
AST_LIST_INSERT_BEFORE_CURRENT(&translators, t, list);
|
AST_RWLIST_INSERT_BEFORE_CURRENT(&translators, t, list);
|
||||||
t = NULL;
|
t = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AST_LIST_TRAVERSE_SAFE_END;
|
AST_RWLIST_TRAVERSE_SAFE_END;
|
||||||
|
|
||||||
/* if no existing translator was found for this format combination,
|
/* if no existing translator was found for this format combination,
|
||||||
add it to the beginning of the list */
|
add it to the beginning of the list */
|
||||||
if (t)
|
if (t)
|
||||||
AST_LIST_INSERT_HEAD(&translators, t, list);
|
AST_RWLIST_INSERT_HEAD(&translators, t, list);
|
||||||
|
|
||||||
rebuild_matrix(0);
|
rebuild_matrix(0);
|
||||||
|
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -672,40 +674,40 @@ int ast_unregister_translator(struct ast_translator *t)
|
|||||||
struct ast_translator *u;
|
struct ast_translator *u;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_WRLOCK(&translators);
|
||||||
AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
|
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
|
||||||
if (u == t) {
|
if (u == t) {
|
||||||
AST_LIST_REMOVE_CURRENT(&translators, list);
|
AST_RWLIST_REMOVE_CURRENT(&translators, list);
|
||||||
if (option_verbose > 1)
|
if (option_verbose > 1)
|
||||||
ast_verbose(VERBOSE_PREFIX_2 "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt));
|
ast_verbose(VERBOSE_PREFIX_2 "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1 << t->srcfmt), ast_getformatname(1 << t->dstfmt));
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AST_LIST_TRAVERSE_SAFE_END;
|
AST_RWLIST_TRAVERSE_SAFE_END;
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
rebuild_matrix(0);
|
rebuild_matrix(0);
|
||||||
|
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
|
|
||||||
return (u ? 0 : -1);
|
return (u ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_translator_activate(struct ast_translator *t)
|
void ast_translator_activate(struct ast_translator *t)
|
||||||
{
|
{
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_WRLOCK(&translators);
|
||||||
t->active = 1;
|
t->active = 1;
|
||||||
rebuild_matrix(0);
|
rebuild_matrix(0);
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_translator_deactivate(struct ast_translator *t)
|
void ast_translator_deactivate(struct ast_translator *t)
|
||||||
{
|
{
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_WRLOCK(&translators);
|
||||||
t->active = 0;
|
t->active = 0;
|
||||||
rebuild_matrix(0);
|
rebuild_matrix(0);
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Calculate our best translator source format, given costs, and a desired destination */
|
/*! \brief Calculate our best translator source format, given costs, and a desired destination */
|
||||||
@@ -728,7 +730,7 @@ int ast_translator_best_choice(int *dst, int *srcs)
|
|||||||
*srcs = *dst = cur;
|
*srcs = *dst = cur;
|
||||||
return 0;
|
return 0;
|
||||||
} else { /* No, we will need to translate */
|
} else { /* No, we will need to translate */
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_RDLOCK(&translators);
|
||||||
for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) {
|
for (cur = 1, y = 0; y < MAX_FORMAT; cur <<= 1, y++) {
|
||||||
if (! (cur & *dst))
|
if (! (cur & *dst))
|
||||||
continue;
|
continue;
|
||||||
@@ -746,7 +748,7 @@ int ast_translator_best_choice(int *dst, int *srcs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
if (best > -1) {
|
if (best > -1) {
|
||||||
*srcs = best;
|
*srcs = best;
|
||||||
*dst = bestdst;
|
*dst = bestdst;
|
||||||
@@ -764,12 +766,12 @@ unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src)
|
|||||||
src = powerof(src);
|
src = powerof(src);
|
||||||
dest = powerof(dest);
|
dest = powerof(dest);
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_RDLOCK(&translators);
|
||||||
|
|
||||||
if (tr_matrix[src][dest].step)
|
if (tr_matrix[src][dest].step)
|
||||||
res = tr_matrix[src][dest].multistep + 1;
|
res = tr_matrix[src][dest].multistep + 1;
|
||||||
|
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -794,7 +796,7 @@ unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src
|
|||||||
if (src_video)
|
if (src_video)
|
||||||
src_video = powerof(src_video);
|
src_video = powerof(src_video);
|
||||||
|
|
||||||
AST_LIST_LOCK(&translators);
|
AST_RWLIST_RDLOCK(&translators);
|
||||||
|
|
||||||
/* For a given source audio format, traverse the list of
|
/* For a given source audio format, traverse the list of
|
||||||
known audio formats to determine whether there exists
|
known audio formats to determine whether there exists
|
||||||
@@ -848,7 +850,7 @@ unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src
|
|||||||
res &= ~x;
|
res &= ~x;
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_LIST_UNLOCK(&translators);
|
AST_RWLIST_UNLOCK(&translators);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user