source: trunk/kernel/kern/cond_var.c @ 513

Last change on this file since 513 was 1, checked in by alain, 8 years ago

First import

File size: 2.4 KB
Line 
1/*
2 * kern/cond_var.c - condition variables implementation
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <types.h>
24#include <errno.h>
25#include <thread.h>
26#include <kmem.h>
27#include <scheduler.h>
28#include <spinlock.h>
29#include <wait_queue.h>
30#include <kmagics.h>
31#include <semaphore.h>
32#include <cond_var.h>
33
34error_t cv_init(struct cv_s *cv)
35{ 
36        spinlock_init(&cv->lock, "CondVar Sync");
37        cv->signature = COND_VAR_ID;
38        wait_queue_init(&cv->wait_queue, "Condition Variable Sync");
39        return 0;
40}
41
42error_t cv_wait(struct cv_s *cv, struct semaphore_s *sem)
43{ 
44        int value;
45        register error_t err;
46        register struct thread_s *this;
47
48        this = current_thread;
49        (void)sem_getvalue(sem, &value);
50
51        if((sem->owner != this) || (value > 0))
52        {
53                if(sem->scope == SEM_SCOPE_SYS)
54                {
55                        printk(ERROR,"ERROR: cv_wait: TID %x, sem %x is not owned or not locked [ value %d ]\n",
56                               this, 
57                               sem, 
58                               value);
59                }
60                return EINVAL;
61        }
62
63        spinlock_lock(&cv->lock);
64
65        if((err=sem_post(sem)))
66        {
67                spinlock_unlock(&cv->lock);
68                return err;
69        }
70
71        wait_on(&cv->wait_queue, WAIT_LAST);
72
73        spinlock_unlock_nosched(&cv->lock);
74        sched_sleep(current_thread);
75
76        return sem_wait(sem);
77}
78
79error_t cv_signal(struct cv_s *cv)
80{
81        struct thread_s *thread;
82
83        spinlock_lock(&cv->lock);
84        thread = wakeup_one(&cv->wait_queue, WAIT_FIRST); 
85        spinlock_unlock(&cv->lock);
86        return 0;
87}
88
89error_t cv_broadcast(struct cv_s *cv)
90{
91        spinlock_lock(&cv->lock);
92        wakeup_all(&cv->wait_queue); 
93        spinlock_unlock(&cv->lock);
94        return 0;
95}
96
97error_t cv_destroy(struct cv_s *cv)
98{
99        register error_t err = 0;
100
101        spinlock_lock(&cv->lock);
102
103        if(!(wait_queue_isEmpty(&cv->wait_queue)))
104                err = EBUSY;
105   
106        spinlock_unlock(&cv->lock);
107 
108        return err;
109}
Note: See TracBrowser for help on using the repository browser.