source: trunk/kernel/syscalls/sys_rwlock.c @ 1

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

First import

File size: 3.0 KB
RevLine 
[1]1/*
2 * kern/sys_rwlock.c - interface to access Read-Write locks service
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 <task.h>
28#include <vmm.h>
29#include <kmagics.h>
30#include <rwlock.h>
31
32
33static inline bool_t isBadLock(struct rwlock_s *rwlock)
34{ 
35        return vmm_check_object(rwlock, struct rwlock_s, RWLOCK_ID);
36}
37
38int sys_rwlock(struct rwlock_s **rwlock, uint_t operation)
39{
40        kmem_req_t req;
41        struct rwlock_s *irwlock;
42        error_t err;
43 
44        err = vmm_check_address("usr rwlock ptr", 
45                                current_task, 
46                                rwlock,
47                                sizeof(struct rwlock_s*));
48        if(err)
49                goto SYS_RWLOCK_END;
50
51        if((err = cpu_copy_from_uspace(&irwlock, rwlock, sizeof(struct rwlock_s *))))
52                goto SYS_RWLOCK_END;
53 
54        switch(operation)
55        {   
56        case RWLOCK_INIT:   
57                req.type  = KMEM_RWLOCK;
58                req.size  = sizeof(*irwlock);
59                req.flags = AF_USER;
60
61                if((irwlock = kmem_alloc(&req)) == NULL)
62                {
63                        err = ENOMEM;
64                        break;
65                }
66   
67                if((err = rwlock_init(irwlock)))
68                        break;
69   
70                if((err = cpu_copy_to_uspace(rwlock, &irwlock, sizeof(struct rwlock_s *))))
71                {
72                        req.ptr = irwlock;
73                        kmem_free(&req);
74                }
75                break;
76
77        case RWLOCK_WRLOCK:
78                if(isBadLock(irwlock))
79                        break;
80   
81                return rwlock_wrlock(irwlock);
82
83        case RWLOCK_RDLOCK:
84                if(isBadLock(irwlock))
85                        break;
86   
87                return rwlock_rdlock(irwlock);
88
89        case RWLOCK_TRYWRLOCK:
90                if(isBadLock(irwlock))
91                        break;
92   
93                return rwlock_trywrlock(irwlock);
94
95        case RWLOCK_TRYRDLOCK:
96                if(isBadLock(irwlock))
97                        break;
98   
99                return rwlock_tryrdlock(irwlock);
100
101        case RWLOCK_UNLOCK:
102                if(isBadLock(irwlock))
103                        break;
104   
105                if((err = rwlock_unlock(irwlock)))
106                        break;
107
108        case RWLOCK_DESTROY:
109                if(isBadLock(irwlock))
110                        break;
111   
112                if((err = rwlock_destroy(irwlock)))
113                        break;
114
115                req.type = KMEM_RWLOCK;
116                req.ptr  = irwlock;
117                kmem_free(&req);
118                return 0;
119
120        default:
121                err = EINVAL;
122        }
123
124SYS_RWLOCK_END:
125        current_thread->info.errno = err;
126        return err;
127}
128
129KMEM_OBJATTR_INIT(rwlock_kmem_init)
130{
131        attr->type   = KMEM_RWLOCK;
132        attr->name   = "KCM RWLOCK";
133        attr->size   = sizeof(struct rwlock_s);
134        attr->aligne = 0;
135        attr->min    = CONFIG_RWLOCK_MIN;
136        attr->max    = CONFIG_RWLOCK_MAX;
137        attr->ctor   = NULL;
138        attr->dtor   = NULL;
139 
140        return 0;
141}
Note: See TracBrowser for help on using the repository browser.