#ifndef INCLUDED_OS_COUNTDOWNLATCH_H #define INCLUDED_OS_COUNTDOWNLATCH_H #ifndef INCLUDED_OS_MUTEX_H #include #endif /*INCLUDED_OS_MUTEX_H*/ #ifndef INCLUDED_OS_CONDV_H #include #endif /*INCLUDED_OS_CONDV_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef struct { os_mutex_t lock; os_condv_t condv; os_int_t count; }os_countdownlatch_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ OS_STATIC_FORCE_INLINE void os_countdownlatch_init(os_countdownlatch_t* self, os_int_t cnt){ os_mutex_init(&self->lock); os_condv_init(&self->condv); self->count = cnt; } OS_STATIC_FORCE_INLINE void os_countdownlatch_destroy(os_countdownlatch_t* self){ os_condv_destroy(&self->condv); os_mutex_destroy(&self->lock); } OS_STATIC_FORCE_INLINE void os_countdownlatch_await(os_countdownlatch_t* self){ os_mutex_lock(&self->lock); while(self->count>0){ os_condv_wait(&self->condv, &self->lock); } os_mutex_unlock(&self->lock); } OS_STATIC_FORCE_INLINE os_err_t os_countdownlatch_timed_await(os_countdownlatch_t* self, os_tick_t ticks){ os_err_t err = OS_ERR_OK; os_mutex_lock(&self->lock); while(self->count>0){ err = os_condv_timed_wait(&self->condv, &self->lock, ticks); if(err==OS_ERR_TIMEOUT){ break; } } os_mutex_unlock(&self->lock); return err; } OS_STATIC_FORCE_INLINE void os_countdownlatch_count_down(os_countdownlatch_t* self){ os_mutex_lock(&self->lock); if(self->count>0){ self->count--; if(self->count==0){ os_mutex_unlock(&self->lock); os_condv_notify_all(&self->condv); return; } } os_mutex_unlock(&self->lock); } OS_STATIC_FORCE_INLINE os_int_t os_countdownlatch_get_count(os_countdownlatch_t* self){ os_int_t count; os_mutex_lock(&self->lock); count = self->count; os_mutex_unlock(&self->lock); return count; } #endif /*INCLUDED_OS_COUNTDOWNLATCH_H*/