From c21c850ec746dc6a26a07a466e72eee354edc5a7 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 29 Jul 2008 03:15:09 +0000 Subject: 2008-07-29 Chris Johns * libblock/include/rtems/bdbuf.h, cpukit/libblock/src/bdbuf.c: Update the comments. --- cpukit/libblock/include/rtems/bdbuf.h | 380 +++++++++++++++++----------------- 1 file changed, 188 insertions(+), 192 deletions(-) (limited to 'cpukit/libblock/include/rtems/bdbuf.h') diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h index 991da1fdaa..33e6f496d6 100644 --- a/cpukit/libblock/include/rtems/bdbuf.h +++ b/cpukit/libblock/include/rtems/bdbuf.h @@ -1,13 +1,17 @@ /** * @file rtems/bdbuf.h * - * block device buffer management + * Block Device Buffer Management */ /* * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov * + * Copyright (C) 2008 Chris Johns + * Rewritten to remove score mutex access. Fixes many performance + * issues. + * * @(#) bdbuf.h,v 1.9 2005/02/02 00:06:18 joel Exp */ @@ -30,14 +34,14 @@ extern "C" { */ typedef enum { - RTEMS_BDBUF_STATE_EMPTY = 0, /* Not in use. */ - RTEMS_BDBUF_STATE_READ_AHEAD = 1, /* Holds read ahead data only */ - RTEMS_BDBUF_STATE_CACHED = 2, /* In the cache and available */ - RTEMS_BDBUF_STATE_ACCESS = 3, /* The user has the buffer */ - RTEMS_BDBUF_STATE_MODIFIED = 4, /* In the cache but modified */ - RTEMS_BDBUF_STATE_ACCESS_MODIFIED = 5, /* With the user but modified */ - RTEMS_BDBUF_STATE_SYNC = 6, /* Requested to be sync'ed */ - RTEMS_BDBUF_STATE_TRANSFER = 7 /* Being transferred to or from disk */ + RTEMS_BDBUF_STATE_EMPTY = 0, /*< Not in use. */ + RTEMS_BDBUF_STATE_READ_AHEAD = 1, /*< Holds read ahead data only */ + RTEMS_BDBUF_STATE_CACHED = 2, /*< In the cache and available */ + RTEMS_BDBUF_STATE_ACCESS = 3, /*< The user has the buffer */ + RTEMS_BDBUF_STATE_MODIFIED = 4, /*< In the cache but modified */ + RTEMS_BDBUF_STATE_ACCESS_MODIFIED = 5, /*< With the user but modified */ + RTEMS_BDBUF_STATE_SYNC = 6, /*< Requested to be sync'ed */ + RTEMS_BDBUF_STATE_TRANSFER = 7 /*< Being transferred to or from disk */ } rtems_bdbuf_buf_state; /** @@ -52,27 +56,27 @@ typedef struct rtems_bdbuf_buffer struct rtems_bdbuf_avl_node { - signed char cache; /* Cache */ - struct rtems_bdbuf_buffer* left; /* Left Child */ - struct rtems_bdbuf_buffer* right; /* Right Child */ - signed char bal; /* The balance of the sub-tree */ + signed char cache; /*< Cache */ + struct rtems_bdbuf_buffer* left; /*< Left Child */ + struct rtems_bdbuf_buffer* right; /*< Right Child */ + signed char bal; /*< The balance of the sub-tree */ } avl; - dev_t dev; /* device number */ - rtems_blkdev_bnum block; /* block number on the device */ + dev_t dev; /*< device number */ + rtems_blkdev_bnum block; /*< block number on the device */ - unsigned char* buffer; /* Pointer to the buffer memory area */ - int error; /* If not 0 indicate an error value (errno) + unsigned char* buffer; /*< Pointer to the buffer memory area */ + int error; /*< If not 0 indicate an error value (errno) * which can be used by user later */ - volatile rtems_bdbuf_buf_state state; /* State of the buffer. */ + volatile rtems_bdbuf_buf_state state; /*< State of the buffer. */ - volatile uint32_t waiters; /* The number of threads waiting on this + volatile uint32_t waiters; /*< The number of threads waiting on this * buffer. */ - rtems_bdpool_id pool; /* Identifier of buffer pool to which this buffer + rtems_bdpool_id pool; /*< Identifier of buffer pool to which this buffer belongs */ - volatile uint32_t hold_timer; /* Timer to indicate how long a buffer + volatile uint32_t hold_timer; /*< Timer to indicate how long a buffer * has been held in the cache modified. */ } rtems_bdbuf_buffer; @@ -82,38 +86,38 @@ typedef struct rtems_bdbuf_buffer */ typedef struct rtems_bdbuf_pool { - int blksize; /* The size of the blocks (in bytes) */ - int nblks; /* Number of blocks in this pool */ + int blksize; /*< The size of the blocks (in bytes) */ + int nblks; /*< Number of blocks in this pool */ - uint32_t flags; /* Configuration flags */ + uint32_t flags; /*< Configuration flags */ - rtems_id lock; /* The pool lock. Lock this data and + rtems_id lock; /*< The pool lock. Lock this data and * all BDs. */ - rtems_id sync_lock; /* Sync calls lock writes. */ - boolean sync_active; /* True if a sync is active. */ - rtems_id sync_requester; /* The sync requester. */ - dev_t sync_device; /* The device to sync */ + rtems_id sync_lock; /*< Sync calls lock writes. */ + boolean sync_active; /*< True if a sync is active. */ + rtems_id sync_requester; /*< The sync requester. */ + dev_t sync_device; /*< The device to sync */ - rtems_bdbuf_buffer* tree; /* Buffer descriptor lookup AVL tree + rtems_bdbuf_buffer* tree; /*< Buffer descriptor lookup AVL tree * root */ - rtems_chain_control ready; /* Free buffers list (or read-ahead) */ - rtems_chain_control lru; /* Last recently used list */ - rtems_chain_control modified; /* Modified buffers list */ - rtems_chain_control sync; /* Buffers to sync list */ + rtems_chain_control ready; /*< Free buffers list (or read-ahead) */ + rtems_chain_control lru; /*< Last recently used list */ + rtems_chain_control modified; /*< Modified buffers list */ + rtems_chain_control sync; /*< Buffers to sync list */ - rtems_id access; /* Obtain if waiting for a buffer in the + rtems_id access; /*< Obtain if waiting for a buffer in the * ACCESS state. */ - volatile uint32_t access_waiters; /* Count of access blockers. */ - rtems_id transfer; /* Obtain if waiting for a buffer in the + volatile uint32_t access_waiters; /*< Count of access blockers. */ + rtems_id transfer; /*< Obtain if waiting for a buffer in the * TRANSFER state. */ - volatile uint32_t transfer_waiters; /* Count of transfer blockers. */ - rtems_id waiting; /* Obtain if waiting for a buffer and the + volatile uint32_t transfer_waiters; /*< Count of transfer blockers. */ + rtems_id waiting; /*< Obtain if waiting for a buffer and the * none are available. */ - volatile uint32_t wait_waiters; /* Count of waiting blockers. */ + volatile uint32_t wait_waiters; /*< Count of waiting blockers. */ - rtems_bdbuf_buffer* bds; /* Pointer to table of buffer descriptors + rtems_bdbuf_buffer* bds; /*< Pointer to table of buffer descriptors * allocated for this buffer pool. */ - void* buffers; /* The buffer's memory. */ + void* buffers; /*< The buffer's memory. */ } rtems_bdbuf_pool; /** @@ -121,9 +125,9 @@ typedef struct rtems_bdbuf_pool * location) for buffering layer pool. */ typedef struct rtems_bdbuf_pool_config { - int size; /* Size of block */ - int num; /* Number of blocks of appropriate size */ - unsigned char* mem_area; /* Pointer to the blocks location or NULL, in this + int size; /*< Size of block */ + int num; /*< Number of blocks of appropriate size */ + unsigned char* mem_area; /*< Pointer to the blocks location or NULL, in this * case memory for blocks will be allocated by * Buffering Layer with the help of RTEMS partition * manager */ @@ -140,11 +144,11 @@ extern int rtems_bdbuf_pool_configuration_size; * structure. */ typedef struct rtems_bdbuf_config { - int max_read_ahead_blocks; /*<< Number of blocks to read ahead. */ - int max_write_blocks; /*<< Number of blocks to write at once. */ - rtems_task_priority swapout_priority; /*<< Priority of the swap out task. */ - uint32_t swapout_period; /*<< Period swapout checks buf timers. */ - uint32_t swap_block_hold; /*<< Period a buffer is held. */ + int max_read_ahead_blocks; /*< Number of blocks to read ahead. */ + int max_write_blocks; /*< Number of blocks to write at once. */ + rtems_task_priority swapout_priority; /*< Priority of the swap out task. */ + uint32_t swapout_period; /*< Period swapout checks buf timers. */ + uint32_t swap_block_hold; /*< Period a buffer is held. */ } rtems_bdbuf_config; /** @@ -163,183 +167,175 @@ extern rtems_bdbuf_config rtems_bdbuf_configuration; #define RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT 250 /* milli-seconds */ #define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT 1000 /* milli-seconds */ -/* rtems_bdbuf_init -- - * Prepare buffering layer to work - initialize buffer descritors - * and (if it is neccessary) buffers. Buffers will be allocated accoriding - * to the configuration table, each entry describes kind of block and - * amount requested. After initialization all blocks is placed into - * free elements lists. +/** + * Prepare buffering layer to work - initialize buffer descritors and (if it is + * neccessary) buffers. Buffers will be allocated accoriding to the + * configuration table, each entry describes the size of block and the size of + * the pool. After initialization all blocks is placed into the ready state. + * lists. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ rtems_status_code rtems_bdbuf_init (); -/* rtems_bdbuf_get -- - * Obtain block buffer. If specified block already cached (i.e. there's - * block in the _modified_, or _recently_used_), return address - * of appropriate buffer descriptor and increment reference counter to 1. - * If block is not cached, allocate new buffer and return it. Data - * shouldn't be read to the buffer from media; buffer may contains - * arbitrary data. This primitive may be blocked if there are no free - * buffer descriptors available and there are no unused non-modified - * (or synchronized with media) buffers available. +/** + * Get block buffer for data to be written into. The buffers is set to the + * access or modifed access state. If the buffer is in the cache and modified + * the state is access modified else the state is access. This buffer contents + * are not initialised if the buffer is not already in the cache. If the block + * is already resident in memory it is returned how-ever if not in memory the + * buffer is not read from disk. This call is used when writing the whole block + * on a disk rather than just changing a part of it. If there is no buffers + * available this call will block. A buffer obtained with this call will not be + * involved in a transfer request and will not be returned to another user + * until released. If the buffer is already with a user when this call is made + * the call is blocked until the buffer is returned. The highest priority + * waiter will obtain the buffer first. * - * PARAMETERS: - * device - device number (constructed of major and minor device number) - * block - linear media block number - * bd - address of variable to store pointer to the buffer descriptor + * The block number is the linear block number. This is relative to the start + * of the partition on the media. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @param device Device number (constructed of major and minor device number) + * @param block Linear media block number + * @param bd Reference to the buffer descriptor pointer. * - * SIDE EFFECTS: - * bufget_sema semaphore obtained by this primitive. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_get(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd); - -/* rtems_bdbuf_read -- - * (Similar to the rtems_bdbuf_get, except reading data from media) - * Obtain block buffer. If specified block already cached, return address - * of appropriate buffer and increment reference counter to 1. If block is - * not cached, allocate new buffer and read data to it from the media. - * This primitive may be blocked on waiting until data to be read from - * media, if there are no free buffer descriptors available and there are - * no unused non-modified (or synchronized with media) buffers available. - * - * PARAMETERS: - * device - device number (consists of major and minor device number) - * block - linear media block number - * bd - address of variable to store pointer to the buffer descriptor +rtems_status_code +rtems_bdbuf_get (dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd); + +/** + * Get the block buffer and if not already in the cache read from the disk. If + * specified block already cached return. The buffer is set to the access or + * modifed access state. If the buffer is in the cache and modified the state + * is access modified else the state is access. If block is already being read + * from disk for being written to disk this call blocks. If the buffer is + * waiting to be written it is removed from modified queue and returned to the + * user. If the buffer is not in the cache a new buffer is obtained and the + * data read from disk. The call may block until these operations complete. A + * buffer obtained with this call will not be involved in a transfer request + * and will not be returned to another user until released. If the buffer is + * already with a user when this call is made the call is blocked until the + * buffer is returned. The highest priority waiter will obtain the buffer + * first. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @param device Device number (constructed of major and minor device number) + * @param block Linear media block number + * @param bd Reference to the buffer descriptor pointer. * - * SIDE EFFECTS: - * bufget_sema and transfer_sema semaphores obtained by this primitive. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_read(dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd); - -/* rtems_bdbuf_release -- - * Release buffer allocated before. This primitive decrease the - * usage counter. If it is zero, further destiny of buffer depends on - * 'modified' status. If buffer was modified, it is placed to the end of - * mod list and flush task waken up. If buffer was not modified, - * it is placed to the end of lru list, and bufget_sema released, allowing - * to reuse this buffer. +rtems_status_code +rtems_bdbuf_read (dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd); + +/** + * Release the buffer obtained by a read call back to the cache. If the buffer + * was obtained by a get call and was not already in the cache the release + * modified call should be used. A buffer released with this call obtained by a + * get call may not be in sync with the contents on disk. If the buffer was in + * the cache and modified before this call it will be returned to the modified + * queue. The buffers is returned to the end of the LRU list. * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. + * @param bd Reference to the buffer descriptor. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) - * - * SIDE EFFECTS: - * flush_sema and bufget_sema semaphores may be released by this primitive. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_release(rtems_bdbuf_buffer* bd); - -/* rtems_bdbuf_release_modified -- - * Release buffer allocated before, assuming that it is _modified_ by - * it's owner. This primitive decrease usage counter for buffer, mark - * buffer descriptor as modified. If usage counter is 0, insert it at - * end of mod chain and release flush_sema semaphore to activate the - * flush task. - * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. +rtems_status_code +rtems_bdbuf_release (rtems_bdbuf_buffer* bd); + +/** + * Release the buffer allocated with a get or read call placing it on the + * modidied list. If the buffer was not released modified before the hold + * timer is set to the configuration value. If the buffer had been released + * modified before but not written to disk the hold timer is not updated. The + * buffer will be written to disk when the hold timer has expired, there are + * not more buffers available in the cache and a get or read buffer needs one + * or a sync call has been made. If the buffer is obtained with a get or read + * before the hold timer has expired the buffer will be returned to the user. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @param bd Reference to the buffer descriptor. * - * SIDE EFFECTS: - * flush_sema semaphore may be released by this primitive. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_release_modified(rtems_bdbuf_buffer* bd); - -/* rtems_bdbuf_sync -- - * Wait until specified buffer synchronized with disk. Invoked on exchanges - * critical for data consistency on the media. This primitive mark owned - * block as modified, decrease usage counter. If usage counter is 0, - * block inserted to the mod chain and flush_sema semaphore released. - * Finally, primitives blocked on transfer_sema semaphore. - * - * PARAMETERS: - * bd_buf - pointer to the bdbuf_buffer structure previously obtained using - * get/read primitive. +rtems_status_code +rtems_bdbuf_release_modified (rtems_bdbuf_buffer* bd); + +/** + * Release the buffer as modified and wait until it has been synchronized with + * the disk by writing it. This buffer will be the first to be transfer to disk + * and other buffers may also be written if the maximum number of blocks in a + * requests allows it. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @note This code does not lock the sync mutex and stop additions to the + * modified queue. + + * @param bd Reference to the buffer descriptor. * - * SIDE EFFECTS: - * Primitive may be blocked on transfer_sema semaphore. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_sync(rtems_bdbuf_buffer* bd); +rtems_status_code +rtems_bdbuf_sync (rtems_bdbuf_buffer* bd); -/* rtems_bdbuf_syncdev -- - * Synchronize with disk all buffers containing the blocks belonging to - * specified device. +/** + * Synchronize all modified buffers for this device with the disk and wait + * until the transfers have completed. The sync mutex for the pool is locked + * stopping the addition of any further modifed buffers. It is only the + * currently modified buffers that are written. * - * PARAMETERS: - * dev - block device number + * @note Nesting calls to sync multiple devices attached to a single pool will + * be handled sequentially. A nested call will be blocked until the first sync + * request has complete. This is only true for device using the same pool. * - * RETURNS: - * RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully - * or error code if error is occured) + * @param dev Block device number + * + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) */ - rtems_status_code - rtems_bdbuf_syncdev(dev_t dev); +rtems_status_code +rtems_bdbuf_syncdev (dev_t dev); -/* rtems_bdbuf_find_pool -- - * Find first appropriate buffer pool. This primitive returns the index - * of first buffer pool which block size is greater than or equal to - * specified size. +/** + * Find first appropriate buffer pool. This primitive returns the index of + * first buffer pool which block size is greater than or equal to specified + * size. * - * PARAMETERS: - * block_size - requested block size - * pool - placeholder for result + * @param block_size Requested block size + * @param pool The pool to use for the requested pool size. * - * RETURNS: - * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully, - * RTEMS_INVALID_SIZE if specified block size is invalid (not a power - * of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size - * is not configured. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) + * @retval RTEMS_INVALID_SIZE The specified block size is invalid (not a power + * of 2) + * @retval RTEMS_NOT_DEFINED The buffer pool for this or greater block size + * is not configured. */ - rtems_status_code - rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool); +rtems_status_code +rtems_bdbuf_find_pool (int block_size, rtems_bdpool_id *pool); -/* rtems_bdbuf_get_pool_info -- - * Obtain characteristics of buffer pool with specified number. +/** + * Obtain characteristics of buffer pool with specified number. * - * PARAMETERS: - * pool - buffer pool number - * block_size - block size for which buffer pool is configured returned - * there - * blocks - number of buffers in buffer pool returned there + * @param pool Buffer pool number + * @param block_size Block size for which buffer pool is configured returned + * there + * @param blocks Number of buffers in buffer pool. * * RETURNS: - * RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully, - * RTEMS_INVALID_NUMBER if appropriate buffer pool is not configured. + * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed + * successfully or error code if error is occured) + * @retval RTEMS_INVALID_SIZE The appropriate buffer pool is not configured. * - * NOTE: - * Buffer pools enumerated contiguously starting from 0. + * @note Buffer pools enumerated continuously starting from 0. */ - rtems_status_code - rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks); +rtems_status_code +rtems_bdbuf_get_pool_info (rtems_bdpool_id pool, int *block_size, int *blocks); #ifdef __cplusplus } -- cgit v1.2.3