source: trunk/kernel/syscalls/sys_condvar.c @ 517

Last change on this file since 517 was 508, checked in by viala@…, 6 years ago

[syscall] Use assert instead of printk+hal_core_sleep.

File size: 5.3 KB
RevLine 
[1]1/*
[23]2 * sys_condvar.c - Access a POSIX condvar.
[1]3 *
[440]4 * Author    Alain Greiner  (2016,2017,2018)
[1]5 *
[23]6 * Copyright (c) UPMC Sorbonne Universites
[1]7 *
[23]8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
[1]11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
[23]14 * ALMOS-MKH is distributed in the hope that it will be useful, but
[1]15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
[23]20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
[1]21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[457]24#include <hal_kernel_types.h>
[23]25#include <hal_special.h>
[1]26#include <errno.h>
27#include <thread.h>
[23]28#include <printk.h>
[1]29#include <vmm.h>
[23]30#include <syscalls.h>
31#include <remote_condvar.h>
[440]32#include <remote_mutex.h>
[1]33
[23]34////////////////////////////////////////
35int sys_condvar( void         * condvar,
36                 uint32_t       operation,
37                 void         * mutex )
[1]38{
[440]39        error_t     error;
40    vseg_t    * vseg;
[1]41 
[440]42    thread_t  * this    = CURRENT_THREAD;
43    process_t * process = this->process;
[1]44
[23]45    // check condvar in user vspace
[440]46        error = vmm_get_vseg( process , (intptr_t)condvar , &vseg );
47
[23]48        if( error )
49    {
[440]50
51#if DEBUG_SYSCALLS_ERROR
52printk("\n[ERROR] in %s : unmapped condvar %x / thread %x / process %x\n",
53__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
54vmm_display( process , false );
55#endif
[23]56        this->errno = error;
57        return -1;
58    }
[1]59
[23]60    // execute requested operation
61        switch( operation )
[1]62        {
[23]63        //////////////////
64        case CONDVAR_INIT:
65        {
66            error = remote_condvar_create( (intptr_t)condvar );
[1]67   
[23]68                    if( error )
69            {
[440]70
71#if DEBUG_SYSCALLS_ERROR
72printk("\n[ERROR] in %s : cannot create condvar %x / thread %x / process %x\n",
73__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
74#endif
[23]75                this->errno = error;
76                return -1;
77            }
78                    break;
79        }
80        //////////////////
81            case CONDVAR_WAIT:
82        {
83            // check mutex in user vspace
[440]84                error = vmm_get_vseg( process , (intptr_t)mutex , &vseg );
[23]85
86                if( error )
87            {
[440]88
89#if DEBUG_SYSCALLS_ERROR
90printk("\n[ERROR] in %s : unmapped mutex %x / thread %x / process %x\n",
91__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
92#endif
[23]93                this->errno = error;
94                return -1;
95            }
96
97            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
98
99            if( condvar_xp == XPTR_NULL )     // user error
100            {
[440]101
102#if DEBUG_SYSCALLS_ERROR
103printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
104__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
105#endif
[23]106                this->errno = EINVAL;
107                return -1;
108            }
[1]109   
[440]110            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)mutex );
111
[23]112            if( mutex_xp == XPTR_NULL )     // user error
113            {
[440]114
115#if DEBUG_SYSCALLS_ERROR
116printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
117__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
118#endif
[23]119                this->errno = EINVAL;
120                return -1;
121            }
[1]122
[23]123            remote_condvar_wait( condvar_xp , mutex_xp );
[1]124
[23]125            break;
126        }
127        ////////////////////
128            case CONDVAR_SIGNAL:
129        {
130            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]131
[23]132            if( condvar_xp == XPTR_NULL )     // user error
133            {
[440]134
135#if DEBUG_SYSCALLS_ERROR
136printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
137__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
138#endif
[23]139                this->errno = EINVAL;
140                return -1;
141            }
[1]142
[23]143            remote_condvar_signal( condvar_xp ); 
144           
145            break;
146        }
147        ///////////////////////
148            case CONDVAR_BROADCAST:
149        {
150            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]151
[23]152            if( condvar_xp == XPTR_NULL )     // user error
153            {
[440]154
155#if DEBUG_SYSCALLS_ERROR
156printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
157__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
158#endif
[23]159                this->errno = EINVAL;
160                return -1;
161            }
[1]162
[23]163            remote_condvar_broadcast( condvar_xp );
[1]164
[23]165            break;
166        }
167        /////////////////////
168            case CONDVAR_DESTROY:
169        {
170            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]171
[23]172            if( condvar_xp == XPTR_NULL )     // user error
173            {
[440]174
175#if DEBUG_SYSCALLS_ERROR
176printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
177__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
178#endif
[23]179                this->errno = EINVAL;
180                return -1;
181            }
[1]182
[23]183            remote_condvar_destroy( condvar_xp ); 
[1]184
[23]185            break;
186                }
187        /////////
[508]188        default: {
189            assert ( false, "illegal operation type <%x>\n", operation );
[23]190        }
191        }   // end switch
[1]192
[23]193        return 0;
[1]194
[23]195}  // enc sys_condvar()
196
Note: See TracBrowser for help on using the repository browser.