MediaProcessors
fair_lock.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Rafael Antoniello
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of copyright holders nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
34 #include "fair_lock.h"
35 
36 #include <stdlib.h>
37 #include <pthread.h>
38 #include <string.h>
39 
40 #include "check_utils.h"
41 #include "log.h"
42 #include "stat_codes.h"
43 
44 /* **** Definitions **** */
45 
46 typedef struct fair_lock_s {
47  volatile unsigned long head, tail;
48  pthread_cond_t cond;
49  pthread_mutex_t mutex;
50 } fair_lock_t;
51 
52 /* **** Prototypes **** */
53 
54 /* **** Implementations **** */
55 
56 fair_lock_t* fair_lock_open()
57 {
58  int ret_code, end_code= STAT_ERROR;
59  fair_lock_t *fair_lock= NULL;
60  LOG_CTX_INIT(NULL);
61 
62  /* Allocate context structure */
63  fair_lock= (fair_lock_t*)calloc(1, sizeof(fair_lock_t));
64  CHECK_DO(fair_lock!= NULL, goto end);
65 
66  /* Initialize context structure */
67  ret_code= pthread_mutex_init(&fair_lock->mutex, NULL);
68  CHECK_DO(ret_code== 0, goto end);
69  ret_code= pthread_cond_init(&fair_lock->cond, NULL);
70  CHECK_DO(ret_code== 0, goto end);
71 
72  end_code= STAT_SUCCESS;
73 end:
74  if(end_code!= STAT_SUCCESS)
75  fair_lock_close(&fair_lock);
76  return fair_lock;
77 }
78 
79 void fair_lock_close(fair_lock_t **ref_fair_lock)
80 {
81  fair_lock_t *fair_lock;
82 
83  if(ref_fair_lock== NULL)
84  return;
85 
86  if((fair_lock= *ref_fair_lock)!= NULL) {
87  pthread_mutex_destroy(&fair_lock->mutex);
88  pthread_cond_destroy(&fair_lock->cond);
89 
90  free(fair_lock);
91  *ref_fair_lock= NULL;
92  }
93 }
94 
95 void fair_lock(fair_lock_t *fair_lock)
96 {
97 #ifndef USE_PTHREAD_MUTEX_ONLY
98  unsigned long queue;
99 #endif
100  LOG_CTX_INIT(NULL);
101 
102  /* Check arguments */
103  CHECK_DO(fair_lock!= NULL, return);
104 
105 #ifndef USE_PTHREAD_MUTEX_ONLY
106  pthread_mutex_lock(&fair_lock->mutex);
107  queue= fair_lock->tail++;
108  while(queue!= fair_lock->head)
109  pthread_cond_wait(&fair_lock->cond, &fair_lock->mutex);
110  pthread_mutex_unlock(&fair_lock->mutex);
111 #else
112  pthread_mutex_lock(&fair_lock->mutex);
113 #endif
114 }
115 
116 void fair_unlock(fair_lock_t *fair_lock)
117 {
118  LOG_CTX_INIT(NULL);
119 
120  /* Check arguments */
121  CHECK_DO(fair_lock!= NULL, return);
122 
123 #ifndef USE_PTHREAD_MUTEX_ONLY
124  pthread_mutex_lock(&fair_lock->mutex);
125  fair_lock->head++;
126  pthread_cond_broadcast(&fair_lock->cond);
127  pthread_mutex_unlock(&fair_lock->mutex);
128 #else
129  pthread_mutex_unlock(&fair_lock->mutex);
130 #endif
131 }
General status codes enumeration.
#define CHECK_DO(COND, ACTION)
Definition: check_utils.h:57