@@ -7,18 +7,6 @@ vfs_node_t pipefs_root = NULL;
77int pipefs_id = 0 ;
88int pipefd_id = 0 ;
99
10- void wake_blocked_tasks (task_block_list_t * head ) {
11- task_block_list_t * current = head -> next ;
12- head -> next = NULL ;
13-
14- while (current ) {
15- task_block_list_t * next = current -> next ;
16- if (current -> thread ) { current -> thread -> status = START ; }
17- free (current );
18- current = next ;
19- }
20- }
21-
2210void pipefs_open (void * parent , const char * name , vfs_node_t node ) {
2311 (void )parent ;
2412 (void )name ;
@@ -33,124 +21,53 @@ size_t pipefs_read(void *file, void *addr, size_t offset, size_t size) {
3321 pipe_info_t * pipe = spec -> info ;
3422 if (!pipe ) return - EINVAL ;
3523
36- spin_lock (pipe -> lock );
37-
38- uint32_t available = (pipe -> write_ptr - pipe -> read_ptr ) % PIPE_BUFF ;
39- if (available == 0 ) {
40- fd_file_handle * fd = container_of (spec -> node , fd_file_handle , node );
41- if (fd -> flags & O_NONBLOCK ) {
42- spin_unlock (pipe -> lock );
43- return - EWOULDBLOCK ;
44- }
45-
46- if (pipe -> write_fds == 0 ) {
47- spin_unlock (pipe -> lock );
48- return 0 ;
49- }
50- close_interrupt ;
51- task_block_list_t * new_block = malloc (sizeof (task_block_list_t ));
52- new_block -> thread = get_current_task ();
53- new_block -> next = NULL ;
54-
55- task_block_list_t * browse = & pipe -> blocking_read ;
56- while (browse -> next )
57- browse = browse -> next ;
58- browse -> next = new_block ;
24+ while (pipe -> ptr == 0 ) {
25+ if (pipe -> write_fds == 0 ) { return 0 ; }
5926
60- spin_unlock (pipe -> lock );
61-
62- task_block (get_current_task (), WAIT , -1 );
27+ scheduler_yield ();
6328 }
64- spin_unlock (pipe -> lock );
65-
66- available = (pipe -> write_ptr - pipe -> read_ptr ) % PIPE_BUFF ;
6729
6830 // 实际读取量
69- uint32_t to_read = MIN (size , available );
31+ uint32_t to_read = MIN (size , pipe -> ptr );
7032
71- if (available == 0 ) {
72- spin_unlock (pipe -> lock );
73- return 0 ;
74- }
33+ if (to_read == 0 ) { return 0 ; }
7534
76- // 分两种情况拷贝数据
77- if (pipe -> read_ptr + to_read <= PIPE_BUFF ) {
78- memcpy (addr , & pipe -> buf [pipe -> read_ptr ], to_read );
79- } else {
80- uint32_t first_chunk = PIPE_BUFF - pipe -> read_ptr ;
81- memcpy (addr , & pipe -> buf [pipe -> read_ptr ], first_chunk );
82- memcpy (addr + first_chunk , pipe -> buf , to_read - first_chunk );
83- }
35+ spin_lock (pipe -> lock );
8436
85- // 更新读指针
86- pipe -> read_ptr = ( pipe -> read_ptr + to_read ) % PIPE_BUFF ;
37+ memcpy ( addr , pipe -> buf , to_read );
38+ memmove ( pipe -> buf , & pipe -> buf [ pipe -> ptr ], pipe -> ptr - to_read );
8739
88- wake_blocked_tasks ( & pipe -> blocking_write ) ;
40+ pipe -> ptr -= to_read ;
8941
9042 spin_unlock (pipe -> lock );
9143
9244 return to_read ;
9345}
9446
9547size_t pipe_write_inner (void * file , const void * addr , size_t size ) {
96- if (size > PIPE_BUFF ) size = PIPE_BUFF ;
97-
9848 pipe_specific_t * spec = (pipe_specific_t * )file ;
9949 pipe_info_t * pipe = spec -> info ;
10050
101- spin_lock (pipe -> lock );
102-
103- uint32_t free_space = PIPE_BUFF - ((pipe -> write_ptr - pipe -> read_ptr ) % PIPE_BUFF );
104- if (free_space < size ) {
105- if (pipe -> read_fds == 0 ) {
106- spin_unlock (pipe -> lock );
107- return - EPIPE ;
108- }
109- task_block_list_t * new_block = malloc (sizeof (task_block_list_t ));
110- new_block -> thread = get_current_task ();
111- new_block -> next = NULL ;
112-
113- task_block_list_t * browse = & pipe -> blocking_write ;
114-
115- while (browse -> next )
116- browse = browse -> next ;
117- browse -> next = new_block ;
118-
119- spin_unlock (pipe -> lock );
120-
121- task_block (get_current_task (), WAIT , -1 );
122-
123- while (get_current_task ()-> status == WAIT ) {
124- open_interrupt ;
125- __asm__("pause" );
126- }
127- close_interrupt ;
51+ while ((PIPE_BUFF - pipe -> ptr ) < size ) {
52+ if (pipe -> read_fds == 0 ) { return - EPIPE ; }
53+ scheduler_yield ();
12854 }
12955
130- if (pipe -> write_ptr + size <= PIPE_BUFF ) {
131- memcpy (& pipe -> buf [pipe -> write_ptr ], addr , size );
132- } else {
133- uint32_t first_chunk = PIPE_BUFF - pipe -> write_ptr ;
134- memcpy (& pipe -> buf [pipe -> write_ptr ], addr , first_chunk );
135- memcpy (pipe -> buf , addr + first_chunk , size - first_chunk );
136- }
137-
138- pipe -> write_ptr = (pipe -> write_ptr + size ) % PIPE_BUFF ;
139-
140- wake_blocked_tasks (& pipe -> blocking_read );
141-
56+ spin_lock (pipe -> lock );
57+ memcpy (& pipe -> buf [pipe -> ptr ], addr , size );
58+ pipe -> ptr += size ;
14259 spin_unlock (pipe -> lock );
14360
14461 return size ;
14562}
14663
14764size_t pipefs_write (void * file , const void * addr , size_t offset , size_t size ) {
148- int ret = 0 ;
65+ size_t ret = 0 ;
14966 size_t chunks = size / PIPE_BUFF ;
15067 size_t remainder = size % PIPE_BUFF ;
15168 if (chunks )
15269 for (size_t i = 0 ; i < chunks ; i ++ ) {
153- int cycle = 0 ;
70+ size_t cycle = 0 ;
15471 while (cycle != PIPE_BUFF )
15572 cycle += pipe_write_inner (file , addr + i * PIPE_BUFF + cycle , PIPE_BUFF - cycle );
15673 ret += cycle ;
@@ -183,15 +100,17 @@ bool pipefs_close(void *current) {
183100 pipe -> read_fds -- ;
184101 }
185102
186- if (!pipe -> write_fds ) wake_blocked_tasks (& pipe -> blocking_read );
187- if (!pipe -> read_fds ) wake_blocked_tasks (& pipe -> blocking_write );
188-
189- if (pipe -> write_fds == 0 && pipe -> read_fds == 0 ) { free (pipe ); }
190- spin_unlock (pipe -> lock );
103+ list_delete (pipefs_root -> child , spec -> node );
104+ if ((spec -> write && pipe -> write_fds == 0 ) || pipe -> read_fds == 0 ) free (spec );
191105
192- free (spec );
106+ if (pipe -> write_fds == 0 && pipe -> read_fds == 0 ) {
107+ spin_unlock (pipe -> lock );
108+ free (pipe -> buf );
109+ free (pipe );
110+ return true;
111+ }
193112
194- list_delete ( pipefs_root -> child , spec -> node );
113+ spin_unlock ( pipe -> lock );
195114
196115 return true;
197116}
@@ -204,17 +123,13 @@ int pipefs_poll(void *file, size_t events) {
204123
205124 spin_lock (pipe -> lock );
206125 if (events & EPOLLIN ) {
207- if (!pipe -> write_fds )
208- out |= EPOLLHUP ;
209- else if (pipe -> write_ptr != pipe -> read_ptr )
210- out |= EPOLLIN ;
126+ if (!pipe -> write_fds ) out |= EPOLLHUP ;
127+ if (pipe -> assigned > 0 ) out |= EPOLLIN ;
211128 }
212129
213130 if (events & EPOLLOUT ) {
214- if (!pipe -> read_fds )
215- out |= EPOLLERR ;
216- else if (pipe -> assigned < PIPE_BUFF )
217- out |= EPOLLOUT ;
131+ if (!pipe -> read_fds ) out |= EPOLLHUP ;
132+ if (pipe -> assigned < PIPE_BUFF ) out |= EPOLLOUT ;
218133 }
219134 spin_unlock (pipe -> lock );
220135 return out ;
@@ -231,6 +146,13 @@ static int dummy() {
231146 return - ENOSYS ;
232147}
233148
149+ errno_t pipefs_stat (void * file , vfs_node_t node ) {
150+ pipe_specific_t * spec = (pipe_specific_t * )file ;
151+ pipe_info_t * pipe = spec -> info ;
152+ node -> size = pipe -> ptr ;
153+ return EOK ;
154+ }
155+
234156static struct vfs_callback pipefs_callbacks = {
235157 .mount = pipefs_mount ,
236158 .unmount = (vfs_unmount_t )empty ,
@@ -246,7 +168,7 @@ static struct vfs_callback pipefs_callbacks = {
246168 .delete = (vfs_del_t )empty ,
247169 .rename = (vfs_rename_t )empty ,
248170 .map = (vfs_mapfile_t )empty ,
249- .stat = ( vfs_stat_t ) empty ,
171+ .stat = pipefs_stat ,
250172 .ioctl = (vfs_ioctl_t )pipefs_ioctl ,
251173 .poll = pipefs_poll ,
252174 .dup = (vfs_dup_t )empty ,
0 commit comments