summaryrefslogtreecommitdiffstats
path: root/pk/kernel/pk_semaphore_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'pk/kernel/pk_semaphore_core.c')
-rw-r--r--pk/kernel/pk_semaphore_core.c318
1 files changed, 0 insertions, 318 deletions
diff --git a/pk/kernel/pk_semaphore_core.c b/pk/kernel/pk_semaphore_core.c
deleted file mode 100644
index 0e1e34d4..00000000
--- a/pk/kernel/pk_semaphore_core.c
+++ /dev/null
@@ -1,318 +0,0 @@
-//-----------------------------------------------------------------------------
-// *! (C) Copyright International Business Machines Corp. 2014
-// *! All Rights Reserved -- Property of IBM
-// *! *** IBM Confidential ***
-//-----------------------------------------------------------------------------
-
-/// \file pk_semaphore_core.c
-/// \brief PK semaphore APIs
-///
-/// The entry points in this file are considered 'core' routines that will
-/// always be present at runtime in any PK application that enables
-/// semaphores.
-
-#include "pk.h"
-
-/// Post a count to a semaphore
-///
-/// \param semaphore A pointer to the semaphore
-///
-/// If any thread is pending on the semaphore, the highest priority thread
-/// will be made runnable and the internal count will remain 0.
-///
-/// If no thread is pending on the semaphore then the internal count will be
-/// incremented by 1, with overflow wrapping the internal count through 0. If
-/// the \a max_count argument supplied when the semaphore was created is
-/// non-zero and the new internal count is greater than the \a max_count, an
-/// overflow error will be signalled.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_POST The \a semaphore is a null (0) pointer.
-///
-/// \retval -PK_SEMAPHORE_OVERFLOW The \a max_count argument supplied when
-/// the semaphore was created is non-zero and the new internal count is
-/// greater than the \a max_count.
-
-int
-pk_semaphore_post(PkSemaphore *semaphore)
-{
- PkMachineContext ctx;
- PkThreadPriority priority;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_POST);
- }
-
- pk_critical_section_enter(&ctx);
-
- priority = __pk_thread_queue_min(&(semaphore->pending_threads));
-
- if (priority != PK_IDLE_THREAD_PRIORITY) {
-
- __pk_thread_queue_delete(&(semaphore->pending_threads), priority);
- __pk_thread_queue_insert(&__pk_run_queue, priority);
-
- PK_KERN_TRACE("THREAD_SEMAPHORE_POST(%d)", priority);
-
- __pk_schedule();
-
- } else {
-
- semaphore->count++;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF((semaphore->max_count > 0) &&
- (semaphore->count > semaphore->max_count),
- PK_SEMAPHORE_OVERFLOW);
- }
- }
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Pend on a semaphore with timeout
-///
-/// \param semaphore A pointer to the semaphore
-///
-/// \param timeout A relative timeout in PK timebase ticks, including the
-/// special values PK_NO_WAIT and PK_WAIT_FOREVER
-///
-/// This API is normally called from threads, and can only be successfully
-/// called from interupt handlers under special conditions.
-///
-/// If the internal count of the \a semaphore is non-zero, the internal count
-/// is decremented by one and execution of the caller continues.
-///
-/// If the internal count of the \a semaphore is zero and the \a timeout is
-/// PK_NO_WAIT (0) then the call returns immediately with the informational
-/// code -PK_SEMAPHORE_PEND_NO_WAIT.
-///
-/// If the internal count of the \a semaphore is zero and the \a timeout is
-/// non-zero then a thread will block until either a semaphore count is
-/// acquired or the relative timeout expires. If this condition occurs in a
-/// call from an interrupt context or before threads have been started then
-/// the call will fail with the error \c -PK_SEMAPHORE_PEND_WOULD_BLOCK.
-///
-/// Once timed out the thread is removed from the semaphore pending queue and
-/// made runnable, and the pk_semaphore_pend() operation will fail, even if
-/// the semaphore count becomes available before the thread runs again. The
-/// pk_semaphore_pend() API returns the informational code
-/// -PK_SEMAPHORE_PEND_TIMED_OUT in this case.
-///
-/// By convention, a timeout interval equal to the maximum possible value of
-/// the \c PkInterval type is taken to mean "wait forever". A thread blocked
-/// on a semaphore in this mode will never time out. PK provides this
-/// constant as \c PK_WAIT_FOREVER.
-///
-/// Return values other than PK_OK (0) are not necessarily errors; see \ref
-/// pk_errors
-///
-/// The following return codes are non-error codes:
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_SEMAPHORE_PEND_NO_WAIT timeout is set to PK_NO_WAIT
-///
-/// \retval -PK_SEMAPHORE_PEND_TIMED_OUT The semaphore was not acquired
-/// before the timeout expired.
-///
-/// The following return codes are error codes:
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_PEND The \a semaphore is a null (0)
-/// pointer.
-///
-/// \retval -PK_SEMAPHORE_PEND_WOULD_BLOCK The call was made from an
-/// interrupt context (or before threads have been started), the semaphore
-/// internal count was 0 and a non-zero timeout was specified.
-
-// Note: Casting __pk_current_thread removes the 'volatile' attribute.
-
-int
-pk_semaphore_pend(PkSemaphore *semaphore,
- PkInterval timeout)
-{
- PkMachineContext ctx;
- PkThreadPriority priority;
- PkThread *thread;
- PkTimer *timer = 0;
- PkInterval scaled_timeout = PK_INTERVAL_SCALE(timeout);
-
- int rc = PK_OK;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_PEND);
- }
-
- pk_critical_section_enter(&ctx);
-
- if (semaphore->count != 0) {
-
- semaphore->count--;
-
- } else if (timeout == PK_NO_WAIT) {
-
- rc = -PK_SEMAPHORE_PEND_NO_WAIT;
-
- } else {
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF_CRITICAL(!__pk_kernel_context_thread(),
- PK_SEMAPHORE_PEND_WOULD_BLOCK,
- &ctx);
- }
-
- thread = (PkThread *)__pk_current_thread;
- priority = thread->priority;
-
- __pk_thread_queue_insert(&(semaphore->pending_threads), priority);
-
- thread->semaphore = semaphore;
- thread->flags |= PK_THREAD_FLAG_SEMAPHORE_PEND;
-
- PK_KERN_TRACE("THREAD_SEMAPHORE_PEND(%d)", priority);
-
- if (timeout != PK_WAIT_FOREVER) {
- timer = &(thread->timer);
- timer->timeout = pk_timebase_get() + scaled_timeout;
- __pk_timer_schedule(timer);
- thread->flags |= PK_THREAD_FLAG_TIMER_PEND;
- }
-
- __pk_thread_queue_delete(&__pk_run_queue, priority);
- __pk_schedule();
-
- thread->flags &= ~PK_THREAD_FLAG_SEMAPHORE_PEND;
-
- if (thread->flags & PK_THREAD_FLAG_TIMER_PEND) {
- if (thread->flags & PK_THREAD_FLAG_TIMED_OUT) {
- rc = -PK_SEMAPHORE_PEND_TIMED_OUT;
- __pk_thread_queue_delete(&(semaphore->pending_threads), thread->priority);
- } else {
- __pk_timer_cancel(timer);
- }
- thread->flags &=
- ~(PK_THREAD_FLAG_TIMER_PEND | PK_THREAD_FLAG_TIMED_OUT);
- }
- }
-
- pk_critical_section_exit(&ctx);
-
- return rc;
-}
-
-
-/// Release all threads blocked on a semaphore
-///
-/// \param semaphore A pointer to a semaphore
-///
-/// This API is provided to allow an PK semaphore to be used as a thread
-/// barrier. pk_semaphore_release_all() simultaneously unblocks all threads
-/// (if any) currently pending on a semaphore. A semaphore to be used as a
-/// thread barrier will typically be initialized with
-/// pk_semaphore_create(\a sem, 0, 0), and sxx_semaphore_post() would never be
-/// called on the \a sem.
-///
-/// This API never modifies the \a count field of the semaphore; If any
-/// threads are blocked on a semaphore the semaphore count is 0 by definition.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_RELEASE The \a semaphore is a null (0)
-/// pointer.
-
-int
-pk_semaphore_release_all(PkSemaphore* semaphore)
-{
- PkMachineContext ctx;
-
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_RELEASE);
- }
-
- pk_critical_section_enter(&ctx);
-
- __pk_thread_queue_union(&__pk_run_queue, &(semaphore->pending_threads));
- __pk_thread_queue_clear(&(semaphore->pending_threads));
- __pk_schedule();
-
- pk_critical_section_exit(&ctx);
-
- return PK_OK;
-}
-
-
-/// Get information about a semaphore.
-///
-/// \param semaphore A pointer to the PkSemaphore to query
-///
-/// \param count The value returned through this pointer is the current count
-/// of the semaphore. The caller can set this parameter to the null pointer
-/// (0) if this information is not required.
-///
-/// \param pending The value returned through this pointer is the current
-/// number of threads pending on the semaphore. The caller can set this
-/// parameter to the null pointer (0) if this information is not required.
-///
-/// The information returned by this API can only be guaranteed consistent if
-/// the API is called from a critical section.
-///
-/// Return values other than PK_OK (0) are errors; see \ref pk_errors
-///
-/// \retval 0 Successful completion
-///
-/// \retval -PK_INVALID_SEMAPHORE_AT_INFO The \a semaphore is a null (0)
-/// pointer.
-
-int
-pk_semaphore_info_get(PkSemaphore* semaphore,
- PkSemaphoreCount* count,
- int* pending)
-
-{
- if (PK_ERROR_CHECK_API) {
- PK_ERROR_IF(semaphore == 0, PK_INVALID_SEMAPHORE_AT_INFO);
- }
-
- if (count) {
- *count = semaphore->count;
- }
- if (pending) {
- *pending = __pk_thread_queue_count(&(semaphore->pending_threads));
- }
-
- return PK_OK;
-}
-
-
-/// An simple interrupt handler that posts to a semaphore.
-///
-/// To implement basic event-driven blocking of a thread, install
-/// pk_semaphore_post_handler() as the handler for an interrupt
-/// and provide a pointer to the semaphore as the \a arg argument in
-/// pk_irq_handler_set(). The semaphore should be initialized with
-/// pk_semaphore_create(&sem, 0, 1). This handler simply disables (masks)
-/// the interrupt, clears the status and calls pk_semaphore_post() on the
-/// semaphore.
-///
-/// Note that clearing the status in the interrupt controller as done here is
-/// effectively a no-op for level-sensitive interrupts. In the level-sensitive
-/// case any thread pending on the semaphore must reset the interrupt
-/// condition in the device before re-enabling the interrupt.
-#if 0
-void
-pk_semaphore_post_handler(void *arg, PkIrqId irq, int priority)
-{
- pk_irq_disable(irq);
- pk_irq_status_clear(irq);
- pk_semaphore_post((PkSemaphore *)arg);
-}
-
-#endif
OpenPOWER on IntegriCloud