[asterisk-commits] dlee: branch dlee/taskprocessor-optimization r399544 - in /team/dlee/taskproc...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 20 13:06:10 CDT 2013
Author: dlee
Date: Fri Sep 20 13:06:08 2013
New Revision: 399544
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=399544
Log:
Doc; cleanup
Modified:
team/dlee/taskprocessor-optimization/include/asterisk/sem.h
team/dlee/taskprocessor-optimization/main/sem.c
Modified: team/dlee/taskprocessor-optimization/include/asterisk/sem.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/taskprocessor-optimization/include/asterisk/sem.h?view=diff&rev=399544&r1=399543&r2=399544
==============================================================================
--- team/dlee/taskprocessor-optimization/include/asterisk/sem.h (original)
+++ team/dlee/taskprocessor-optimization/include/asterisk/sem.h Fri Sep 20 13:06:08 2013
@@ -19,7 +19,15 @@
#ifndef ASTERISK_SEMAPHORE_H
#define ASTERISK_SEMAPHORE_H
+/*!
+ * \file Asterisk semaphore API
+ *
+ * This API is a thin wrapper around the POSIX semaphore API (when available),
+ * so see the POSIX documentation for further details.
+ */
+
#ifdef HAS_WORKING_SEMAPHORE
+/* Working semaphore implementation detected */
#include <semaphore.h>
@@ -27,28 +35,125 @@
sem_t real_sem;
};
+#define AST_SEM_VALUE_MAX SEM_VALUE_MAX
+
#else
+/* Unnamed semaphores don't work. Rolling our own, I guess... */
#include "asterisk/lock.h"
+#include <limits.h>
+
struct ast_sem {
+ /*! Current count of this semaphore */
int count;
+ /*! Number of threads currently waiting for this semaphore */
int waiters;
+ /*! Mutual exclusion */
ast_mutex_t mutex;
+ /*! Condition for singalling waiters */
ast_cond_t cond;
};
+#define AST_SEM_VALUE_MAX INT_MAX
+
#endif
+/*!
+ * \brief Initialize a semaphore.
+ *
+ * \param sem Semaphore to initialize.
+ * \param pshared Pass true (nonzero) to share this thread between processes.
+ * Not be supported on all platforms, so be wary!
+ * \param value Initial value of the semaphore.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value);
+/*!
+ * \brief Destroy a semaphore.
+ *
+ * Destroying a semaphore that other threads are currently blocked on produces
+ * undefined behavior.
+ *
+ * \param sem Semaphore to destroy.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
int ast_sem_destroy(struct ast_sem *sem);
+/*!
+ * \brief Increments the semaphore, unblocking a waiter if necessary.
+ *
+ * \param sem Semaphore to increment.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
int ast_sem_post(struct ast_sem *sem);
+/*!
+ * \brief Decrements the semaphore.
+ *
+ * If the semaphore's current value is zero, this function blocks until another
+ * thread posts (ast_sem_post()) to the semaphore (or is interrupted by a signal
+ * handler, which sets errno to EINTR).
+ *
+ * \param sem Semaphore to decrement.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
int ast_sem_wait(struct ast_sem *sem);
+/*!
+ * \brief Gets the current value of the semaphore.
+ *
+ * If threads are blocked on this semaphore, POSIX allows the return value to be
+ * either 0 or a negative number whose absolute value is the number of threads
+ * blocked. Don't assume that it will give you one or the other; Asterisk has
+ * been ported to just about everything.
+ *
+ * \param sem Semaphore to query.
+ * \param[out] sval Output value.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
int ast_sem_getvalue(struct ast_sem *sem, int *sval);
+#ifdef HAS_WORKING_SEMAPHORE
+
+/* These are thin wrappers; might as well inline them */
+
+static force_inline int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
+{
+ return sem_init(&sem->real_sem, pshared, value);
+}
+
+static force_inline int ast_sem_destroy(struct ast_sem *sem)
+{
+ return sem_destroy(&sem->real_sem);
+}
+
+static force_inline int ast_sem_post(struct ast_sem *sem)
+{
+ return sem_post(&sem->real_sem);
+}
+
+static force_inline int ast_sem_wait(struct ast_sem *sem)
+{
+ return sem_wait(&sem->real_sem);
+}
+
+static force_inline int ast_sem_getvalue(struct ast_sem *sem, int *sval)
+{
+ return sem_getvalue(&sem->real_sem, sval);
+}
+
+#endif /* HAS_WORKING_SEMAPHORE */
#endif /* ASTERISK_SEMAPHORE_H */
Modified: team/dlee/taskprocessor-optimization/main/sem.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/taskprocessor-optimization/main/sem.c?view=diff&rev=399544&r1=399543&r2=399544
==============================================================================
--- team/dlee/taskprocessor-optimization/main/sem.c (original)
+++ team/dlee/taskprocessor-optimization/main/sem.c Fri Sep 20 13:06:08 2013
@@ -28,38 +28,19 @@
#include "asterisk/sem.h"
#include "asterisk/utils.h"
-#ifdef HAS_WORKING_SEMAPHORE
+#ifndef HAS_WORKING_SEMAPHORE
+
+/* DIY semaphores! */
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
{
- return sem_init(&sem->real_sem, pshared, value);
-}
+ if (pshared) {
+ /* Don't need it... yet */
+ errno = ENOSYS;
+ return -1;
+ }
-int ast_sem_destroy(struct ast_sem *sem)
-{
- return sem_destroy(&sem->real_sem);
-}
-
-int ast_sem_post(struct ast_sem *sem)
-{
- return sem_post(&sem->real_sem);
-}
-
-int ast_sem_wait(struct ast_sem *sem)
-{
- return sem_wait(&sem->real_sem);
-}
-
-int ast_sem_getvalue(struct ast_sem *sem, int *sval)
-{
- return sem_getvalue(&sem->real_sem, sval);
-}
-
-#else
-
-int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
-{
- sem->count = 0;
+ sem->count = value;
sem->waiters = 0;
ast_mutex_init(&sem->mutex);
ast_cond_init(&sem->cond, NULL);
@@ -79,8 +60,15 @@
ast_assert(sem->count >= 0);
+ if (sem->count == INT_MAX) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ /* Give it up! */
++sem->count;
+ /* Release a waiter, if needed */
if (sem->waiters) {
ast_cond_signal(&sem->cond);
}
@@ -94,12 +82,14 @@
ast_assert(sem->count >= 0);
+ /* Wait for a non-zero count */
+ ++sem->waiters;
while (sem->count == 0) {
- ++sem->waiters;
ast_cond_wait(&sem->cond, &sem->mutex);
- --sem->waiters;
}
+ --sem->waiters;
+ /* Take it! */
--sem->count;
return 0;
@@ -110,7 +100,9 @@
SCOPED_MUTEX(lock, &sem->mutex);
ast_assert(sem->count >= 0);
+
*sval = sem->count;
+
return 0;
}
More information about the asterisk-commits
mailing list