📄 rmtimeoutsemaphore.c
字号:
/***************************************** Copyright 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************/#ifndef ALLOW_OS_CODE#define ALLOW_OS_CODE#endif#include "../include/rmlibcw.h"#if 0 #define TOSDBG ENABLE#else #define TOSDBG DISABLE#endif#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include <sys/time.h>#include <unistd.h>#include <errno.h>// _NP below means Non Posix. This code uses GNU features (recursive mutex)#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#include <pthread.h>#include <semaphore.h>#include "robust.h"struct _RMtimeoutSemaphore { pthread_cond_t cond; pthread_mutex_t mutex; int count;};RMtimeoutSemaphore RMCreateTimeoutSemaphore(RMuint32 initialCount){/* pthread_mutexattr_t attr; */ RMtimeoutSemaphore tos; tos = (RMtimeoutSemaphore) RMMalloc(sizeof(struct _RMtimeoutSemaphore)); if (robust_pthread_cond_init(&(tos->cond), (pthread_condattr_t *) NULL) != 0) RMPanic(RM_FATAL_TOS);/* if (robust_pthread_mutexattr_init(&attr) != 0) *//* RMPanic(RM_FATAL_TOS); *//* if (robust_pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP) !=0) *//* RMPanic(RM_FATAL_TOS); */ if (robust_pthread_mutex_init(&(tos->mutex), (pthread_mutexattr_t *) NULL) != 0) RMPanic(RM_FATAL_TOS); /* if (robust_pthread_mutexattr_destroy(&attr) != 0) *//* RMPanic(RM_FATAL_TOS); */ tos->count = initialCount; return tos;}void RMDeleteTimeoutSemaphore(RMtimeoutSemaphore tos){ if (robust_pthread_cond_destroy(&(tos->cond)) != 0) RMPanic(RM_FATAL_TOS); if (robust_pthread_mutex_destroy(&(tos->mutex)) != 0) RMPanic(RM_FATAL_TOS); RMFree(tos);} RMstatus RMWaitForTimeoutSemaphore(RMtimeoutSemaphore tos, RMuint64 microsec){ struct timeval now; struct timespec timeout; int retcode; RMstatus status; if (microsec > 0) { robust_pthread_mutex_lock(&(tos->mutex)); gettimeofday(&now, (struct timezone *) NULL); timeout.tv_sec = now.tv_sec + (time_t) (microsec / 1000000) + (time_t) ((now.tv_usec + (microsec % 1000000)) / 1000000); timeout.tv_nsec = (RMuint32) (((now.tv_usec + (microsec % 1000000)) % 1000000) * 1000); retcode = 0; while ((tos->count <= 0) && (retcode != ETIMEDOUT)) { /* THIS IS NOT THE ROBUST CALL */ /* if (now > timeout) this call return EINTR for ever */ retcode = pthread_cond_timedwait(&(tos->cond), &(tos->mutex), &timeout); } if (retcode == ETIMEDOUT) { status = RM_TOS_TIMEOUT; } else { tos->count --; status = RM_TOS_EVENT; } robust_pthread_mutex_unlock(&(tos->mutex)); } else { robust_pthread_mutex_lock(&(tos->mutex)); while (tos->count <= 0) { retcode = robust_pthread_cond_wait(&(tos->cond), &(tos->mutex)); } tos->count --; status = RM_TOS_EVENT; robust_pthread_mutex_unlock(&(tos->mutex)); } return status;}void RMReleaseTimeoutSemaphore(RMtimeoutSemaphore tos, RMuint32 releaseCount){ robust_pthread_mutex_lock(&(tos->mutex)); tos->count += releaseCount; RMDBGLOG((TOSDBG, "release count = %d\n", tos->count)); robust_pthread_cond_broadcast(&(tos->cond)); robust_pthread_mutex_unlock(&(tos->mutex));}RMtimeoutSemaphoreOps g_timeoutSem_ops={ Create:RMCreateTimeoutSemaphore, Delete:RMDeleteTimeoutSemaphore, WaitFor:RMWaitForTimeoutSemaphore, Release:RMReleaseTimeoutSemaphore,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -