With the _rename_r mostly done and all the things falling in place, the next target was fifo_open routine under the libfs/. At first look, the routine looked too small to be so large in terms of code size and then realized that all the static routines invoked were inlined. Now, fifo_open was mostly fifo.c. This made it a big chunk.
Pipes / fifos are connectors used in a -ix system, which can be used by programs to convey data to other programs. A pipe has two (virtual) ends, write end - where a writer can fill in the data and a read end, from where a reader extracts data. From the implementation point of view, a pipe is a buffer, to which a reader / writer has exclusive access and modify the pipe by writing / reading.
About the routine:
Signature:
int fifo_open(
pipe_control_t **pipep,
rtems_libio_t *iop
);
This routine is called by open -> IMFS_fifo_open -> fifo_open
Open takes in a file name and the mode in which the pipe is to be opened. open creates an fd and provides the IMFS_fifo_open with the rtems_libio_t corresponding to the fd. IMFS_fifo_open extracts info from the rtems_libio_t and provides the (pipe_control_t **) and the (rtems_libio_t *) to fifo_open.
pipep - pipe control structure that is either already present or NULL.
iop - rtems_libio_t which is used to extract useful info like modes of the open
Purpose:
* open a fifo / pipe in the required mode
Misc:
* It is also called during a unnamed pipe creation - a posix pipe creation routine
Flow:
* Create a new pipe, if necessary
- If the pipe control structure does not exist, allocate a new pipe control stucture.
- A new pipe control structure requires
# pipe buffer
# Two barriers, one each for readers and writers
# A semaphore for the producer-consumer solution
* Check the mode in which the pipe is to be opened
* If read mode, wake up the possibly waiting writers
* If a non-blocking read mode is requested, return. Else wait at a barrier
* If write mode, wake up the possibly waiting readers
* If a non-blocking write mode is requested, its not possible and return with an error. Else, wait at a barrier until a reader wakes us up
* If the mode is a read-write mode, register the increase in number of readers/writers and return
Test cases:
With Pipes/fifos disabled in the configuration
* attempt opening a fifo
With Pipes/fifos enabled in the configuration, with a single task,
* Consume all barriers and semaphores, try opening fifo.
* Release a barrier, try opening fifo
* Release another barrier, try opening fifo
* Delete a semaphore, try opening fifo
* Consume all of the memory, try opening fifo
* open fifo in RD-WR mode
* open fifo in RDONLY, nonblock
* open fifo in WRONLY, nonblock
* open fifo several times, to get the wrap around a->z->a
With Pipes/fifos enabled in the configuration, with two tasks,
* open pipe in a read-only mode first, block the reader and then open the pipe in a write-only mode, which unblocks the reader
* open pipe in a write-only mode first, block the writer and then open the pipe in a read-only mode, which unblocks the writer
* write and read from the pipe to be sure about the fifo_open.
Changes to RTEMS, issues with routine:
* Without fifos enabled, fifo_opening was possible. New config item
CONFIGURE_FIFOS(PIPES)_ENABLED and
CONFIGURE_MAXIMUM_FIFOS (PIPES)
created as per which number of semaphore / barriers required are calculated. Fixed.
* when the fifo was opened in WRONLY | NONBLOCK mode, the pipe_release did not destroy the pipe. PR 1542 - Fixed.
* fifo_open returned EINTR where it was supposed to return ENOMEM. PR 1577 - Fixed.
* pipe_release did not delete the semaphore, since it was still in use. PR 1585 - Fixed.
Coverage result:
* fifo_open remains mostly covered, except for the following cases:
- Errors on barrier wait
- Errors on semaphore obtain
Challenges:
* Making my way through the code tree
* Understanding the working of a pipe / fifo
* Understanding task creation, deletion, blocking
Submitted patch:
PR on rtems-bugzilla - PR 1546
https://code.google.com/p/rtems-coverage-improvements-gsoc-2010/source/browse/#svn/trunk/fifo-open-patch
Learnings:
* How to better submit a test
* How to better submit a patch to the RTEMS
* Pipe / fifo related concepts
* Tasks, their creation, deletion, when do they block...
* Semaphore / barrier related concepts
* Get a ENOMEM by allocating most of heap
* How to hit the code, more hard :)
Next:
After this long stretch, thanks to the examinations at the university, next were the lot easier error reporting routines.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment