blob: 4a245980b434b72eb8f12890db30c8ee09985a9b [file] [log] [blame]
// umlrtmutex.cc
/*******************************************************************************
* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
#include <errno.h>
#include <time.h>
#include "basefatal.hh"
#include "umlrtmutex.hh"
#include "umlrttimespec.hh"
// UMLRTMutex is platform-independent mutual-exclusion.
// Bug 32 tracks the move of this implementation to +/os/linux/osmutex.cc
UMLRTMutex::UMLRTMutex()
{
pthread_mutex_init(&mutex, NULL);
}
// Can create a mutex which starts life as taken already.
UMLRTMutex::UMLRTMutex( bool taken )
{
if (taken)
{
take();
}
}
UMLRTMutex::~UMLRTMutex()
{
pthread_mutex_destroy(&mutex);
}
// Wait forever for mutex.
void UMLRTMutex::take()
{
if (pthread_mutex_lock(&mutex) < 0)
{
FATAL_ERRNO("pthread_mutex_lock");
}
}
// Timed - returns non-zero for success, zero for timeout.
#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
int UMLRTMutex::take( uint32_t msec )
{
struct timespec timeout;
int success = !0;
UMLRTTimespec::timespecAbsAddMsec( &timeout, msec );
if (pthread_mutex_timedlock(&mutex, &timeout) < 0)
{
int errno_ = errno;
if (errno_ != ETIMEDOUT)
{
FATAL_ERRNO("pthread_mutex_timedlock");
}
success = 0;
}
return success;
}
#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406)
#pragma GCC diagnostic pop
#endif
// Give mutex back.
void UMLRTMutex::give()
{
if (pthread_mutex_unlock(&mutex) < 0)
{
FATAL_ERRNO("pthread_mutex_unlock");
}
}