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

Last change on this file since 625 was 624, checked in by alain, 6 years ago

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

File size: 6.5 KB
RevLine 
[1]1/*
[23]2 * sys_condvar.c - Access a POSIX condvar.
[1]3 *
[624]4 * Author    Alain Greiner  (2016,2017,2018,2019)
[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>
[624]26#include <hal_vmm.h>
[1]27#include <errno.h>
28#include <thread.h>
[23]29#include <printk.h>
[1]30#include <vmm.h>
[23]31#include <syscalls.h>
32#include <remote_condvar.h>
[440]33#include <remote_mutex.h>
[1]34
[566]35
36#if DEBUG_SYS_CONDVAR
37/////////////////////////////////////////////////////
38static char * sys_convar_op_str( uint32_t operation )
39{
40        if     ( operation == CONDVAR_INIT      ) return "INIT";
41        else if( operation == CONDVAR_WAIT      ) return "WAIT";
42        else if( operation == CONDVAR_SIGNAL    ) return "SIGNAL";
43        else if( operation == CONDVAR_BROADCAST ) return "BROADCAST";
44        else if( operation == CONDVAR_DESTROY   ) return "DESTROY";
45        else                                      return "undefined";
46}
47#endif
48
49//////////////////////////////////////
[23]50int sys_condvar( void         * condvar,
51                 uint32_t       operation,
52                 void         * mutex )
[1]53{
[566]54    vseg_t    * vseg;         // for condvar check
[440]55        error_t     error;
[1]56 
[440]57    thread_t  * this    = CURRENT_THREAD;
58    process_t * process = this->process;
[1]59
[566]60#if DEBUG_SYS_CONDVAR
61uint64_t    tm_start;
62uint64_t    tm_end;
63tm_start = hal_get_cycles();
64if( DEBUG_SYS_CONDVAR < tm_start )
65printk("\n[DBG] %s : thread %x in process %x enter for %s / cycle %d\n",
66__FUNCTION__, this->trdid, process->pid, sys_condvar_op_str( operation ), (uint32_t)tm_start );
67#endif
68
[23]69    // check condvar in user vspace
[440]70        error = vmm_get_vseg( process , (intptr_t)condvar , &vseg );
71
[23]72        if( error )
73    {
[440]74
75#if DEBUG_SYSCALLS_ERROR
76printk("\n[ERROR] in %s : unmapped condvar %x / thread %x / process %x\n",
77__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
[624]78hal_vmm_display( process , false );
[440]79#endif
[23]80        this->errno = error;
81        return -1;
82    }
[1]83
[23]84    // execute requested operation
85        switch( operation )
[1]86        {
[23]87        //////////////////
88        case CONDVAR_INIT:
89        {
90            error = remote_condvar_create( (intptr_t)condvar );
[1]91   
[23]92                    if( error )
93            {
[440]94
95#if DEBUG_SYSCALLS_ERROR
96printk("\n[ERROR] in %s : cannot create condvar %x / thread %x / process %x\n",
97__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
98#endif
[23]99                this->errno = error;
100                return -1;
101            }
102                    break;
103        }
104        //////////////////
105            case CONDVAR_WAIT:
106        {
107            // check mutex in user vspace
[440]108                error = vmm_get_vseg( process , (intptr_t)mutex , &vseg );
[23]109
110                if( error )
111            {
[440]112
113#if DEBUG_SYSCALLS_ERROR
114printk("\n[ERROR] in %s : unmapped mutex %x / thread %x / process %x\n",
115__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
116#endif
[23]117                this->errno = error;
118                return -1;
119            }
120
121            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
122
123            if( condvar_xp == XPTR_NULL )     // user error
124            {
[440]125
126#if DEBUG_SYSCALLS_ERROR
127printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
128__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
129#endif
[23]130                this->errno = EINVAL;
131                return -1;
132            }
[1]133   
[440]134            xptr_t mutex_xp = remote_mutex_from_ident( (intptr_t)mutex );
135
[23]136            if( mutex_xp == XPTR_NULL )     // user error
137            {
[440]138
139#if DEBUG_SYSCALLS_ERROR
140printk("\n[ERROR] in %s : mutex %x not registered / thread %x / process %x\n",
141__FUNCTION__ , (intptr_t)mutex , this->trdid , process->pid );
142#endif
[23]143                this->errno = EINVAL;
144                return -1;
145            }
[1]146
[23]147            remote_condvar_wait( condvar_xp , mutex_xp );
[1]148
[23]149            break;
150        }
151        ////////////////////
152            case CONDVAR_SIGNAL:
153        {
154            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]155
[23]156            if( condvar_xp == XPTR_NULL )     // user error
157            {
[440]158
159#if DEBUG_SYSCALLS_ERROR
160printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
161__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
162#endif
[23]163                this->errno = EINVAL;
164                return -1;
165            }
[1]166
[23]167            remote_condvar_signal( condvar_xp ); 
168           
169            break;
170        }
171        ///////////////////////
172            case CONDVAR_BROADCAST:
173        {
174            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]175
[23]176            if( condvar_xp == XPTR_NULL )     // user error
177            {
[440]178
179#if DEBUG_SYSCALLS_ERROR
180printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
181__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
182#endif
[23]183                this->errno = EINVAL;
184                return -1;
185            }
[1]186
[23]187            remote_condvar_broadcast( condvar_xp );
[1]188
[23]189            break;
190        }
191        /////////////////////
192            case CONDVAR_DESTROY:
193        {
194            xptr_t condvar_xp = remote_condvar_from_ident( (intptr_t)condvar );
[1]195
[23]196            if( condvar_xp == XPTR_NULL )     // user error
197            {
[440]198
199#if DEBUG_SYSCALLS_ERROR
200printk("\n[ERROR] in %s : condvar %x not registered / thread %x / process %x\n",
201__FUNCTION__ , (intptr_t)condvar , this->trdid , process->pid );
202#endif
[23]203                this->errno = EINVAL;
204                return -1;
205            }
[1]206
[23]207            remote_condvar_destroy( condvar_xp ); 
[1]208
[23]209            break;
210                }
211        /////////
[508]212        default: {
213            assert ( false, "illegal operation type <%x>\n", operation );
[23]214        }
215        }   // end switch
[1]216
[566]217    hal_fence();
218
219#if DEBUG_SYS_CONDVAR
220tm_start = hal_get_cycles();
221if( DEBUG_SYS_MUTEX < tm_start )
222printk("\n[DBG] %s : thread %x in process %x exit for %s / cycle %d\n",
223__FUNCTION__, this->trdid, process->pid, sys_condvar_op_str( operation ), (uint32_t)tm_start );
224#endif
225
[23]226        return 0;
[1]227
[23]228}  // enc sys_condvar()
229
Note: See TracBrowser for help on using the repository browser.