kinetic-c  v0.12.0
Seagate Kinetic Protocol Client Library for C
kinetic_countingsemaphore.c
Go to the documentation of this file.
1 /*
2 * kinetic-c
3 * Copyright (C) 2015 Seagate Technology.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
22 #include "kinetic_logger.h"
23 #include <stdlib.h>
24 #include <assert.h>
25 
26 KineticCountingSemaphore * KineticCountingSemaphore_Create(uint32_t counts)
27 {
28  KineticCountingSemaphore * sem = calloc(1, sizeof(KineticCountingSemaphore));
29  if (sem == NULL) { return NULL; }
30  pthread_mutex_init(&sem->mutex, NULL);
31  pthread_cond_init(&sem->available, NULL);
32  sem->count = counts;
33  sem->max = counts;
34  sem->num_waiting = 0;
35  return sem;
36 }
37 
38 void KineticCountingSemaphore_Take(KineticCountingSemaphore * const sem) // WAIT
39 {
40  KINETIC_ASSERT(sem != NULL);
41  pthread_mutex_lock(&sem->mutex);
42 
43  sem->num_waiting++;
44 
45  while (sem->count == 0) {
46  pthread_cond_wait(&sem->available, &sem->mutex);
47  }
48 
49  sem->num_waiting--;
50 
51  uint32_t before = sem->count--;
52  uint32_t after = sem->count;
53  uint32_t waiting = sem->num_waiting;
54 
55  pthread_mutex_unlock(&sem->mutex);
56 
57  LOGF3("Concurrent ops throttle -- TAKE: %u => %u (waiting=%u)", before, after, waiting);
58 }
59 
60 void KineticCountingSemaphore_Give(KineticCountingSemaphore * const sem) // SIGNAL
61 {
62  KINETIC_ASSERT(sem != NULL);
63  pthread_mutex_lock(&sem->mutex);
64 
65  if (sem->count == 0 && sem->num_waiting > 0) {
66  pthread_cond_signal(&sem->available);
67  }
68 
69  uint32_t before = sem->count++;
70  uint32_t after = sem->count;
71  uint32_t waiting = sem->num_waiting;
72 
73  pthread_mutex_unlock(&sem->mutex);
74 
75  LOGF3("Concurrent ops throttle -- GIVE: %u => %u (waiting=%u)", before, after, waiting);
76  KINETIC_ASSERT(sem->max >= after);
77 }
78 
79 void KineticCountingSemaphore_Destroy(KineticCountingSemaphore * const sem)
80 {
81  KINETIC_ASSERT(sem != NULL);
82  pthread_mutex_destroy(&sem->mutex);
83  pthread_cond_destroy(&sem->available);
84  free(sem);
85 }
void KineticCountingSemaphore_Destroy(KineticCountingSemaphore *const sem)
void KineticCountingSemaphore_Take(KineticCountingSemaphore *const sem)
void KineticCountingSemaphore_Give(KineticCountingSemaphore *const sem)
#define KINETIC_ASSERT(cond)
#define LOGF3(message,...)
KineticCountingSemaphore * KineticCountingSemaphore_Create(uint32_t counts)