232 lines
4.8 KiB
C++
Executable File
232 lines
4.8 KiB
C++
Executable File
/*
|
|
* Copyright (C) Texas Instruments - http://www.ti.com/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
|
|
#include "Semaphore.h"
|
|
#include <time.h>
|
|
#include <utils/Log.h>
|
|
namespace android {
|
|
|
|
/**
|
|
@brief Constructor for the semaphore class
|
|
|
|
@param none
|
|
@return none
|
|
*/
|
|
Semaphore::Semaphore()
|
|
{
|
|
///Initialize the semaphore to NULL
|
|
mSemaphore = NULL;
|
|
}
|
|
|
|
/**
|
|
@brief Destructor of the semaphore class
|
|
|
|
@param none
|
|
@return none
|
|
|
|
*/
|
|
Semaphore::~Semaphore()
|
|
{
|
|
Release();
|
|
}
|
|
|
|
/**
|
|
@brief: Releases semaphore
|
|
|
|
@param count >=0
|
|
@return NO_ERROR On Success
|
|
@return One of the android error codes based on semaphore de-initialization
|
|
*/
|
|
|
|
status_t Semaphore::Release()
|
|
{
|
|
int status = 0;
|
|
|
|
///Destroy only if the semaphore has been created
|
|
if(mSemaphore)
|
|
{
|
|
status = sem_destroy(mSemaphore);
|
|
|
|
free(mSemaphore);
|
|
|
|
mSemaphore = NULL;
|
|
}
|
|
|
|
///Initialize the semaphore and return the status
|
|
return (status);
|
|
|
|
}
|
|
|
|
/**
|
|
@brief Create the semaphore with initial count value
|
|
|
|
@param count >=0
|
|
@return NO_ERROR On Success
|
|
@return NO_MEMORY If unable to allocate memory for the semaphore
|
|
@return BAD_VALUE If an invalid count value is passed (<0)
|
|
@return One of the android error codes based on semaphore initialization
|
|
*/
|
|
|
|
status_t Semaphore::Create(int count)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
|
|
///count cannot be less than zero
|
|
if(count<0)
|
|
{
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
ret = Release();
|
|
if ( NO_ERROR != ret )
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
///allocate memory for the semaphore
|
|
mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ;
|
|
|
|
///if memory is unavailable, return error
|
|
if(!mSemaphore)
|
|
{
|
|
ALOGD("%s(%d):failed to alloc mem",__FUNCTION__,__LINE__);
|
|
return NO_MEMORY;
|
|
}
|
|
|
|
///Initialize the semaphore and return the status
|
|
return sem_init(mSemaphore, 0x00, count);
|
|
|
|
}
|
|
|
|
/**
|
|
@brief Wait operation
|
|
|
|
@param none
|
|
@return BAD_VALUE if the semaphore is not initialized
|
|
@return NO_ERROR On success
|
|
@return One of the android error codes based on semaphore wait operation
|
|
*/
|
|
status_t Semaphore::Wait()
|
|
{
|
|
///semaphore should have been created first
|
|
if(!mSemaphore)
|
|
{
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
///Wait and return the status after signalling
|
|
return sem_wait(mSemaphore);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
@brief Signal operation
|
|
|
|
@param none
|
|
@return BAD_VALUE if the semaphore is not initialized
|
|
@return NO_ERROR On success
|
|
@return One of the android error codes based on semaphore signal operation
|
|
*/
|
|
|
|
status_t Semaphore::Signal()
|
|
{
|
|
///semaphore should have been created first
|
|
if(!mSemaphore)
|
|
{
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
///Post to the semaphore
|
|
return sem_post(mSemaphore);
|
|
|
|
}
|
|
|
|
/**
|
|
@brief Current semaphore count
|
|
|
|
@param none
|
|
@return Current count value of the semaphore
|
|
*/
|
|
int Semaphore::Count()
|
|
{
|
|
int val;
|
|
|
|
///semaphore should have been created first
|
|
if(!mSemaphore)
|
|
{
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
///get the value of the semaphore
|
|
sem_getvalue(mSemaphore, &val);
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
@brief Wait operation with a timeout
|
|
|
|
@param timeoutMicroSecs The timeout period in micro seconds
|
|
@return BAD_VALUE if the semaphore is not initialized
|
|
@return NO_ERROR On success
|
|
@return One of the android error codes based on semaphore wait operation
|
|
*/
|
|
|
|
status_t Semaphore::WaitTimeout(int timeoutMicroSecs)
|
|
{
|
|
status_t ret = NO_ERROR;
|
|
|
|
struct timespec timeSpec;
|
|
struct timeval currentTime;
|
|
|
|
///semaphore should have been created first
|
|
if( NULL == mSemaphore)
|
|
{
|
|
ret = BAD_VALUE;
|
|
}
|
|
|
|
if ( NO_ERROR == ret )
|
|
{
|
|
|
|
///setup the timeout values - timeout is specified in seconds and nanoseconds
|
|
gettimeofday(¤tTime, NULL);
|
|
timeSpec.tv_sec = currentTime.tv_sec;
|
|
timeSpec.tv_nsec = currentTime.tv_usec * 1000;
|
|
timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 );
|
|
timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000;
|
|
|
|
///Wait for the timeout or signal and return the result based on whichever event occurred first
|
|
ret = sem_timedwait(mSemaphore, &timeSpec);
|
|
}
|
|
|
|
if ( NO_ERROR != ret )
|
|
{
|
|
Signal();
|
|
Create(0);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|