Changeset 670 for trunk/kernel/syscalls/sys_pipe.c
- Timestamp:
- Nov 19, 2020, 11:45:52 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_pipe.c
r506 r670 2 2 * sys_pipe.c - open a pipe communication channel 3 3 * 4 * Author Alain Greiner (2016,1017 )4 * Author Alain Greiner (2016,1017,2018,2019,2020) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 24 24 #include <hal_kernel_types.h> 25 25 #include <vfs.h> 26 #include <hal_uspace.h> 26 27 #include <process.h> 27 28 #include <thread.h> 28 29 #include <printk.h> 30 #include <pipe.h> 29 31 30 32 #include <syscalls.h> 31 33 32 //////////////////////////// //////////33 int sys_pipe ( uint32_t file_fd[2])34 //////////////////////////// 35 int sys_pipe ( fdid_t * fd ) 34 36 { 35 printk("\n[ERROR] in %d : not implemented yet\n", __FUNCTION__, file_fd ); 36 return ENOSYS; 37 } 37 vseg_t * vseg; 38 kmem_req_t req; 39 pipe_t * pipe; 40 vfs_file_t * file_0; 41 vfs_file_t * file_1; 42 fdid_t fdid_0; 43 fdid_t fdid_1; 44 error_t error; 45 46 thread_t * this = CURRENT_THREAD; 47 process_t * process = this->process; 48 49 #if DEBUG_SYS_PIPE || DEBUG_SYSCALLS_ERROR || CONFIG_INSTRUMENTATION_SYSCALLS 50 uint64_t tm_start = hal_get_cycles(); 51 #endif 52 53 #if DEBUG_SYS_PIPE 54 if( DEBUG_SYS_PIPE < tm_end ) 55 printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n", 56 __FUNCTION__, process->pid, this->trdid, pathname, (uint32_t)tm_end ); 57 #endif 58 59 // check user buffer is mapped 60 if( vmm_get_vseg( process , (intptr_t)fd , &vseg ) ) 61 { 62 63 #if DEBUG_SYSCALLS_ERROR 64 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 65 printk("\n[ERROR] in %s : thread[%x,%x] / output user buffer unmapped %x\n", 66 __FUNCTION__ , process->pid, this->trdid, (intptr_t)fd ); 67 #endif 68 this->errno = EINVAL; 69 return -1; 70 } 71 72 // 1. allocate memory in local cluster for pipe descriptor, 73 // remote buf_descriptor, and associated data buffer 74 pipe = pipe_create( local_cxy, 75 CONFIG_PIPE_BUF_SIZE ); 76 77 if( pipe == NULL ) 78 { 79 80 #if DEBUG_SYSCALLS_ERROR 81 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 82 printk("\n[ERROR] in %s : thread[%x,%x] / no memory for pipe\n", 83 __FUNCTION__ , process->pid, this->trdid ); 84 #endif 85 goto error_1; 86 } 87 88 // 2. allocate memory for fd[0] file descriptor in local cluster 89 // we don't use the vfs_file_create function because there is no inode. 90 req.type = KMEM_KCM; 91 req.order = bits_log2( sizeof(vfs_file_t) ); 92 req.flags = AF_ZERO; 93 file_0 = kmem_alloc( &req ); 94 95 if( file_0 == NULL ) 96 { 97 98 #if DEBUG_SYSCALLS_ERROR 99 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 100 printk("\n[ERROR] in %s : thread[%x,%x] / no memory for file descriptor\n", 101 __FUNCTION__, process->pid, this->trdid ); 102 #endif 103 goto error_2; 104 } 105 106 // 3. get fd[0] fdid value and register it in owner process fd_array[] 107 error = process_fd_register( process->owner_xp, 108 XPTR( local_cxy , file_0 ), 109 &fdid_0 ); 110 if ( error ) 111 { 112 113 #if DEBUG_SYSCALLS_ERROR 114 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 115 printk("\n[ERROR] in %s : thread[%x,%x] / cannot register file descriptor \n", 116 __FUNCTION__, process->pid, this->trdid ); 117 #endif 118 goto error_3; 119 } 120 121 // 4. allocate memory for fd[1] file descriptor in local cluster 122 req.type = KMEM_KCM; 123 req.order = bits_log2( sizeof(vfs_file_t) ); 124 req.flags = AF_ZERO; 125 file_1 = kmem_alloc( &req ); 126 127 if( file_1 == NULL ) 128 { 129 130 #if DEBUG_SYSCALLS_ERROR 131 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 132 printk("\n[ERROR] in %s : thread[%x,%x] / no memory for file descriptor\n", 133 __FUNCTION__, process->pid, this->trdid ); 134 #endif 135 goto error_4; 136 } 137 138 // 5. get fd[1] fdid value and register it in owner process fd_array[] 139 error = process_fd_register( process->owner_xp, 140 XPTR( local_cxy , file_1 ), 141 &fdid_1 ); 142 if ( error ) 143 { 144 145 #if DEBUG_SYSCALLS_ERROR 146 if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start ) 147 printk("\n[ERROR] in %s : thread[%x,%x] / cannot register file descriptor \n", 148 __FUNCTION__, process->pid, this->trdid ); 149 #endif 150 goto error_5; 151 } 152 153 // link the two file descriptors to the pipe 154 file_0->pipe = pipe; 155 file_1->pipe = pipe; 156 157 // copy fdid_0 & fdid_1 values to user buffer 158 hal_copy_to_uspace( &fd[0] , XPTR( local_cxy , &fdid_0 ) , sizeof(fdid_t) ); 159 hal_copy_to_uspace( &fd[1] , XPTR( local_cxy , &fdid_1 ) , sizeof(fdid_t) ); 160 161 #if (DEBUG_SYS_PIPE || CONFIG_INSTRUMENTATION_SYSCALLS) 162 uint64_t tm_end = hal_get_cycles(); 163 #endif 164 165 #if DEBUG_SYS_PIPE 166 if( DEBUG_SYS_PIPE < tm_end ) 167 printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n", 168 __FUNCTION__, this->process->pid, this->trdid, pathname, (uint32_t)tm_end ); 169 #endif 170 171 #if CONFIG_INSTRUMENTATION_SYSCALLS 172 hal_atomic_add( &syscalls_cumul_cost[SYS_PIPE] , tm_end - tm_start ); 173 hal_atomic_add( &syscalls_occurences[SYS_PIPE] , 1 ); 174 #endif 175 176 return 0; 177 178 error_5: // release memory allocated for fd[1] file descriptor 179 180 req.ptr = file_1; 181 kmem_free( &req ); 182 183 error_4: // release fdid_0 from fd_array[] 184 185 process_fd_remove( process->ref_xp , fdid_0 ); 186 187 error_3: // release memory allocated for fd[0] file descriptor 188 189 req.ptr = file_0; 190 kmem_free( &req ); 191 192 error_2: // release memory allocated for the pipe 193 194 pipe_destroy( XPTR( local_cxy , pipe ) ); 195 196 error_1: // set errno and return error 197 198 this->errno = ENOMEM; 199 return -1; 200 201 } // end sys_pipe()
Note: See TracChangeset
for help on using the changeset viewer.