source: rtems-libbsd/rtemsbsd/src/rtems-bsd-condvar.c @ cbffdb7f

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since cbffdb7f was cbffdb7f, checked in by Joel Sherrill <joel.sherrill@…>, on 03/07/12 at 22:14:13

Separate RTEMS Specific Files from Those Direct from FreeBSD

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bsd_rtems
5 *
6 * @brief TODO.
7 */
8
9/*
10 * Copyright (c) 2009, 2010 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.com/license/LICENSE.
21 */
22
23/* Necessary to obtain some internal functions */
24#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
25
26#include <rtems/freebsd/machine/rtems-bsd-config.h>
27
28#include <rtems/posix/cond.h>
29
30#include <rtems/freebsd/sys/param.h>
31#include <rtems/freebsd/sys/types.h>
32#include <rtems/freebsd/sys/systm.h>
33#include <rtems/freebsd/sys/lock.h>
34#include <rtems/freebsd/sys/mutex.h>
35#include <rtems/freebsd/sys/condvar.h>
36
37RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_condvar_chain);
38
39void
40cv_init(struct cv *cv, const char *desc)
41{
42        int rv = pthread_cond_init(&cv->cv_id, NULL);
43
44        BSD_ASSERT_RV(rv);
45
46        cv->cv_description = desc;
47
48        rtems_chain_append(&rtems_bsd_condvar_chain, &cv->cv_node);
49}
50
51void
52cv_destroy(struct cv *cv)
53{
54        int rv = pthread_cond_destroy(&cv->cv_id);
55
56        BSD_ASSERT_RV(rv);
57
58        rtems_chain_extract(&cv->cv_node);
59}
60
61static int _cv_wait_support(struct cv *cv, struct lock_object *lock, int timo, bool relock)
62{
63        rtems_status_code sc = RTEMS_SUCCESSFUL;
64        int eno = 0;
65        Objects_Locations location = OBJECTS_ERROR;
66        POSIX_Condition_variables_Control *pcv = _POSIX_Condition_variables_Get(&cv->cv_id, &location);
67
68        if (location == OBJECTS_LOCAL) {
69                if (pcv->Mutex != POSIX_CONDITION_VARIABLES_NO_MUTEX && pcv->Mutex != lock->lo_id) {
70                        _Thread_Enable_dispatch();
71
72                        BSD_ASSERT(false);
73
74                        return EINVAL;
75                }
76
77                sc = rtems_semaphore_release(lock->lo_id);
78                if (sc != RTEMS_SUCCESSFUL) {
79                        _Thread_Enable_dispatch();
80
81                        BSD_ASSERT(false);
82
83                        return EINVAL;
84                }
85
86                pcv->Mutex = lock->lo_id;
87
88                _Thread_queue_Enter_critical_section(&pcv->Wait_queue);
89                _Thread_Executing->Wait.return_code = 0;
90                _Thread_Executing->Wait.queue = &pcv->Wait_queue;
91                _Thread_Executing->Wait.id = cv->cv_id;
92
93                /* FIXME: Integer conversion */
94                _Thread_queue_Enqueue(&pcv->Wait_queue, (Watchdog_Interval) timo);
95
96                DROP_GIANT();
97
98                _Thread_Enable_dispatch();
99
100                PICKUP_GIANT();
101
102                eno = (int) _Thread_Executing->Wait.return_code;
103                if (eno != 0) {
104                        if (eno == ETIMEDOUT) {
105                                eno = EWOULDBLOCK;
106                        } else {
107                                BSD_ASSERT(false);
108
109                                eno = EINVAL;
110                        }
111                }
112
113                if (relock) {
114                        sc = rtems_semaphore_obtain(lock->lo_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
115                        if (sc != RTEMS_SUCCESSFUL) {
116                                BSD_ASSERT(false);
117
118                                eno = EINVAL;
119                        }
120                }
121
122                return eno;
123        }
124
125        BSD_PANIC("unexpected object location");
126}
127
128void
129_cv_wait(struct cv *cv, struct lock_object *lock)
130{
131        _cv_wait_support(cv, lock, 0, true);
132}
133
134void
135_cv_wait_unlock(struct cv *cv, struct lock_object *lock)
136{
137        _cv_wait_support(cv, lock, 0, false);
138}
139
140int
141_cv_timedwait(struct cv *cv, struct lock_object *lock, int timo)
142{
143        if (timo <= 0) {
144                timo = 1;
145        }
146
147        return _cv_wait_support(cv, lock, timo, true);
148}
149
150void
151cv_signal(struct cv *cv)
152{
153        int rv = pthread_cond_signal(&cv->cv_id);
154
155        BSD_ASSERT_RV(rv);
156}
157
158void
159cv_broadcastpri(struct cv *cv, int pri)
160{
161        int rv = 0;
162
163        BSD_ASSERT(pri == 0);
164
165        rv = pthread_cond_broadcast(&cv->cv_id);
166        BSD_ASSERT_RV(rv);
167}
Note: See TracBrowser for help on using the repository browser.