source: rtems/cpukit/libblock/include/rtems/bdbuf.h @ 4f971343

4.104.114.95
Last change on this file since 4f971343 was 4f971343, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/01/08 at 07:44:48

Convert to using "bool".

  • Property mode set to 100644
File size: 14.2 KB
RevLine 
[b80dd59d]1/**
2 * @file rtems/bdbuf.h
[e51bd96]3 *
[c21c850e]4 * Block Device Buffer Management
[b80dd59d]5 */
6 
7/*
[e51bd96]8 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
9 * Author: Victor V. Vengerov <vvv@oktet.ru>
10 *
[c21c850e]11 * Copyright (C) 2008 Chris Johns <chrisj@rtems.org>
12 *    Rewritten to remove score mutex access. Fixes many performance
13 *    issues.
14 *
[3d14a45]15 * @(#) bdbuf.h,v 1.9 2005/02/02 00:06:18 joel Exp
[e51bd96]16 */
17
[a6f5d89]18#ifndef _RTEMS_BDBUF_H
19#define _RTEMS_BDBUF_H
[e51bd96]20
21#include <rtems.h>
22#include <rtems/libio.h>
[ebbe119e]23#include <rtems/chain.h>
[e51bd96]24
25#include "rtems/blkdev.h"
26#include "rtems/diskdevs.h"
27
[4f971343]28#ifdef __cplusplus
29extern "C" {
30#endif
31
32
[3899a537]33/**
34 * State of a buffer in the cache.
[e51bd96]35 */
[3899a537]36typedef enum
37{
[c21c850e]38  RTEMS_BDBUF_STATE_EMPTY = 0,            /*< Not in use. */
39  RTEMS_BDBUF_STATE_READ_AHEAD = 1,       /*< Holds read ahead data only */
40  RTEMS_BDBUF_STATE_CACHED = 2,           /*< In the cache and available */
41  RTEMS_BDBUF_STATE_ACCESS = 3,           /*< The user has the buffer */
42  RTEMS_BDBUF_STATE_MODIFIED = 4,         /*< In the cache but modified */
43  RTEMS_BDBUF_STATE_ACCESS_MODIFIED = 5,  /*< With the user but modified */
44  RTEMS_BDBUF_STATE_SYNC = 6,             /*< Requested to be sync'ed */
45  RTEMS_BDBUF_STATE_TRANSFER = 7          /*< Being transferred to or from disk */
[3899a537]46} rtems_bdbuf_buf_state;
[e51bd96]47
[3899a537]48/**
49 * To manage buffers we using buffer descriptors (BD). A BD holds a buffer plus
50 * a range of other information related to managing the buffer in the cache. To
51 * speed-up buffer lookup descriptors are organized in AVL-Tree.  The fields
52 * 'dev' and 'block' are search keys.
[e51bd96]53 */
[3899a537]54typedef struct rtems_bdbuf_buffer
55{
56  rtems_chain_node link;       /* Link in the BD onto a number of lists. */
[e51bd96]57
[3899a537]58  struct rtems_bdbuf_avl_node
59  {
[c21c850e]60    signed char                cache;  /*< Cache */
61    struct rtems_bdbuf_buffer* left;   /*< Left Child */
62    struct rtems_bdbuf_buffer* right;  /*< Right Child */
63    signed char                bal;    /*< The balance of the sub-tree */
[3899a537]64  } avl;
[e51bd96]65
[c21c850e]66  dev_t             dev;        /*< device number */
67  rtems_blkdev_bnum block;      /*< block number on the device */
[e51bd96]68
[c21c850e]69  unsigned char*    buffer;     /*< Pointer to the buffer memory area */
70  int               error;      /*< If not 0 indicate an error value (errno)
[3899a537]71                                 * which can be used by user later */
[df6348bb]72
[c21c850e]73  volatile rtems_bdbuf_buf_state state;  /*< State of the buffer. */
[048dcd2b]74
[c21c850e]75  volatile uint32_t waiters;    /*< The number of threads waiting on this
[3899a537]76                                 * buffer. */
[c21c850e]77  rtems_bdpool_id pool;         /*< Identifier of buffer pool to which this buffer
[3899a537]78                                    belongs */
[e51bd96]79
[c21c850e]80  volatile uint32_t hold_timer; /*< Timer to indicate how long a buffer
[3899a537]81                                 * has been held in the cache modified. */
82} rtems_bdbuf_buffer;
[e51bd96]83
[3899a537]84/**
85 * The groups of the blocks with the same size are collected in a pool. Note
86 * that a several of the buffer's groups with the same size can exists.
87 */
88typedef struct rtems_bdbuf_pool
89{
[cec5c069]90  uint32_t            blksize;           /*< The size of the blocks (in bytes) */
91  uint32_t            nblks;             /*< Number of blocks in this pool */
[3899a537]92
[c21c850e]93  uint32_t            flags;             /*< Configuration flags */
[3899a537]94
[c21c850e]95  rtems_id            lock;              /*< The pool lock. Lock this data and
[3899a537]96                                          * all BDs. */
[c21c850e]97  rtems_id            sync_lock;         /*< Sync calls lock writes. */
[4f971343]98  bool                sync_active;       /*< True if a sync is active. */
[c21c850e]99  rtems_id            sync_requester;    /*< The sync requester. */
100  dev_t               sync_device;       /*< The device to sync */
[3899a537]101
[c21c850e]102  rtems_bdbuf_buffer* tree;             /*< Buffer descriptor lookup AVL tree
[3899a537]103                                         * root */
[c21c850e]104  rtems_chain_control ready;            /*< Free buffers list (or read-ahead) */
105  rtems_chain_control lru;              /*< Last recently used list */
106  rtems_chain_control modified;         /*< Modified buffers list */
107  rtems_chain_control sync;             /*< Buffers to sync list */
[3899a537]108
[c21c850e]109  rtems_id            access;           /*< Obtain if waiting for a buffer in the
[3899a537]110                                         * ACCESS state. */
[c21c850e]111  volatile uint32_t   access_waiters;   /*< Count of access blockers. */
112  rtems_id            transfer;         /*< Obtain if waiting for a buffer in the
[3899a537]113                                         * TRANSFER state. */
[c21c850e]114  volatile uint32_t   transfer_waiters; /*< Count of transfer blockers. */
115  rtems_id            waiting;          /*< Obtain if waiting for a buffer and the
[3899a537]116                                         * none are available. */
[c21c850e]117  volatile uint32_t   wait_waiters;     /*< Count of waiting blockers. */
[3899a537]118
[c21c850e]119  rtems_bdbuf_buffer* bds;              /*< Pointer to table of buffer descriptors
[3899a537]120                                         * allocated for this buffer pool. */
[c21c850e]121  void*               buffers;          /*< The buffer's memory. */
[3899a537]122} rtems_bdbuf_pool;
[e51bd96]123
[3899a537]124/**
125 * Configuration structure describes block configuration (size, amount, memory
126 * location) for buffering layer pool.
[3d14a45]127 */
[3899a537]128typedef struct rtems_bdbuf_pool_config {
[c21c850e]129  int            size;      /*< Size of block */
130  int            num;       /*< Number of blocks of appropriate size */
131  unsigned char* mem_area;  /*< Pointer to the blocks location or NULL, in this
[3899a537]132                             * case memory for blocks will be allocated by
133                             * Buffering Layer with the help of RTEMS partition
134                             * manager */
135} rtems_bdbuf_pool_config;
136
137/**
138 * External references provided by the user for each pool in the system.
[3d14a45]139 */
[3899a537]140extern rtems_bdbuf_pool_config rtems_bdbuf_pool_configuration[];
141extern int                     rtems_bdbuf_pool_configuration_size;
142
143/**
144 * Buffering configuration definition. See confdefs.h for support on using this
145 * structure.
[e51bd96]146 */
147typedef struct rtems_bdbuf_config {
[cec5c069]148  uint32_t            max_read_ahead_blocks; /*< Number of blocks to read ahead. */
149  uint32_t            max_write_blocks;      /*< Number of blocks to write at once. */
[c21c850e]150  rtems_task_priority swapout_priority;      /*< Priority of the swap out task. */
151  uint32_t            swapout_period;        /*< Period swapout checks buf timers. */
152  uint32_t            swap_block_hold;       /*< Period a buffer is held. */
[e51bd96]153} rtems_bdbuf_config;
154
[3899a537]155/**
156 * External referernce to the configuration. The configuration is provided by
157 * the user.
158 */
159extern rtems_bdbuf_config rtems_bdbuf_configuration;
[e51bd96]160
[3899a537]161/**
162 * The max_read_ahead_blocks value is altered if there are fewer buffers
163 * than this defined max. This stops thrashing in the cache.
164 */
165#define RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT    32
166#define RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT         16
167#define RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT    15
168#define RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT 250  /* milli-seconds */
169#define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT  1000 /* milli-seconds */
[c9b005a9]170
[c21c850e]171/**
172 * Prepare buffering layer to work - initialize buffer descritors and (if it is
173 * neccessary) buffers. Buffers will be allocated accoriding to the
174 * configuration table, each entry describes the size of block and the size of
175 * the pool. After initialization all blocks is placed into the ready state.
176 * lists.
[e51bd96]177 *
[c21c850e]178 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
179 *         successfully or error code if error is occured)
[e51bd96]180 */
181rtems_status_code
[a5fb40cf]182rtems_bdbuf_init (void);
[e51bd96]183
[c21c850e]184/**
185 * Get block buffer for data to be written into. The buffers is set to the
186 * access or modifed access state. If the buffer is in the cache and modified
187 * the state is access modified else the state is access. This buffer contents
188 * are not initialised if the buffer is not already in the cache. If the block
189 * is already resident in memory it is returned how-ever if not in memory the
190 * buffer is not read from disk. This call is used when writing the whole block
191 * on a disk rather than just changing a part of it. If there is no buffers
192 * available this call will block. A buffer obtained with this call will not be
193 * involved in a transfer request and will not be returned to another user
194 * until released. If the buffer is already with a user when this call is made
195 * the call is blocked until the buffer is returned. The highest priority
196 * waiter will obtain the buffer first.
[e51bd96]197 *
[c21c850e]198 * The block number is the linear block number. This is relative to the start
199 * of the partition on the media.
[e51bd96]200 *
[c21c850e]201 * @param device Device number (constructed of major and minor device number)
202 * @param block  Linear media block number
203 * @param bd     Reference to the buffer descriptor pointer.
[e51bd96]204 *
[c21c850e]205 * @return       RTEMS status code (RTEMS_SUCCESSFUL if operation completed
206 *               successfully or error code if error is occured)
[e51bd96]207 */
[c21c850e]208rtems_status_code
209rtems_bdbuf_get (dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
210
211/**
212 * Get the block buffer and if not already in the cache read from the disk. If
213 * specified block already cached return. The buffer is set to the access or
214 * modifed access state. If the buffer is in the cache and modified the state
215 * is access modified else the state is access. If block is already being read
216 * from disk for being written to disk this call blocks. If the buffer is
217 * waiting to be written it is removed from modified queue and returned to the
218 * user. If the buffer is not in the cache a new buffer is obtained and the
219 * data read from disk. The call may block until these operations complete. A
220 * buffer obtained with this call will not be involved in a transfer request
221 * and will not be returned to another user until released. If the buffer is
222 * already with a user when this call is made the call is blocked until the
223 * buffer is returned. The highest priority waiter will obtain the buffer
224 * first.
[e51bd96]225 *
[c21c850e]226 * @param device Device number (constructed of major and minor device number)
227 * @param block  Linear media block number
228 * @param bd     Reference to the buffer descriptor pointer.
[e51bd96]229 *
[c21c850e]230 * @return       RTEMS status code (RTEMS_SUCCESSFUL if operation completed
231 *               successfully or error code if error is occured)
[e51bd96]232 */
[c21c850e]233rtems_status_code
234rtems_bdbuf_read (dev_t device, rtems_blkdev_bnum block, rtems_bdbuf_buffer** bd);
235
236/**
237 * Release the buffer obtained by a read call back to the cache. If the buffer
238 * was obtained by a get call and was not already in the cache the release
239 * modified call should be used. A buffer released with this call obtained by a
240 * get call may not be in sync with the contents on disk. If the buffer was in
241 * the cache and modified before this call it will be returned to the modified
242 * queue. The buffers is returned to the end of the LRU list.
[e51bd96]243 *
[c21c850e]244 * @param bd Reference to the buffer descriptor.
[e51bd96]245 *
[c21c850e]246 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
247 *         successfully or error code if error is occured)
[e51bd96]248 */
[c21c850e]249rtems_status_code
250rtems_bdbuf_release (rtems_bdbuf_buffer* bd);
251
252/**
253 * Release the buffer allocated with a get or read call placing it on the
254 * modidied list.  If the buffer was not released modified before the hold
255 * timer is set to the configuration value. If the buffer had been released
256 * modified before but not written to disk the hold timer is not updated. The
257 * buffer will be written to disk when the hold timer has expired, there are
258 * not more buffers available in the cache and a get or read buffer needs one
259 * or a sync call has been made. If the buffer is obtained with a get or read
260 * before the hold timer has expired the buffer will be returned to the user.
[e51bd96]261 *
[c21c850e]262 * @param bd Reference to the buffer descriptor.
[e51bd96]263 *
[c21c850e]264 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
265 *         successfully or error code if error is occured)
[e51bd96]266 */
[c21c850e]267rtems_status_code
268rtems_bdbuf_release_modified (rtems_bdbuf_buffer* bd);
269
270/**
271 * Release the buffer as modified and wait until it has been synchronized with
272 * the disk by writing it. This buffer will be the first to be transfer to disk
273 * and other buffers may also be written if the maximum number of blocks in a
274 * requests allows it.
[e51bd96]275 *
[c21c850e]276 * @note This code does not lock the sync mutex and stop additions to the
277 *       modified queue.
278
279 * @param bd Reference to the buffer descriptor.
[e51bd96]280 *
[c21c850e]281 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
282 *         successfully or error code if error is occured)
[e51bd96]283 */
[c21c850e]284rtems_status_code
285rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
[e51bd96]286
[c21c850e]287/**
288 * Synchronize all modified buffers for this device with the disk and wait
289 * until the transfers have completed. The sync mutex for the pool is locked
290 * stopping the addition of any further modifed buffers. It is only the
291 * currently modified buffers that are written.
[e51bd96]292 *
[c21c850e]293 * @note Nesting calls to sync multiple devices attached to a single pool will
294 * be handled sequentially. A nested call will be blocked until the first sync
295 * request has complete. This is only true for device using the same pool.
[e51bd96]296 *
[c21c850e]297 * @param dev Block device number
298 *
299 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
300 *         successfully or error code if error is occured)
[e51bd96]301 */
[c21c850e]302rtems_status_code
303rtems_bdbuf_syncdev (dev_t dev);
[e51bd96]304
[c21c850e]305/**
306 * Find first appropriate buffer pool. This primitive returns the index of
307 * first buffer pool which block size is greater than or equal to specified
308 * size.
[e51bd96]309 *
[c21c850e]310 * @param block_size Requested block size
311 * @param pool The pool to use for the requested pool size.
[e51bd96]312 *
[c21c850e]313 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
314 *         successfully or error code if error is occured)
315 * @retval RTEMS_INVALID_SIZE The specified block size is invalid (not a power
316 *         of 2)
317 * @retval RTEMS_NOT_DEFINED The buffer pool for this or greater block size
318 *         is not configured.
[e51bd96]319 */
[c21c850e]320rtems_status_code
[cec5c069]321rtems_bdbuf_find_pool (uint32_t block_size, rtems_bdpool_id *pool);
[e51bd96]322
[c21c850e]323/**
324 * Obtain characteristics of buffer pool with specified number.
[e51bd96]325 *
[c21c850e]326 * @param pool Buffer pool number
327 * @param block_size Block size for which buffer pool is configured returned
328 *                   there
329 * @param blocks Number of buffers in buffer pool.
[e51bd96]330 *
331 * RETURNS:
[c21c850e]332 * @return RTEMS status code (RTEMS_SUCCESSFUL if operation completed
333 *         successfully or error code if error is occured)
334 * @retval RTEMS_INVALID_SIZE The appropriate buffer pool is not configured.
[e51bd96]335 *
[c21c850e]336 * @note Buffer pools enumerated continuously starting from 0.
[e51bd96]337 */
[c21c850e]338rtems_status_code
339rtems_bdbuf_get_pool_info (rtems_bdpool_id pool, int *block_size, int *blocks);
[e51bd96]340
341#ifdef __cplusplus
342}
343#endif
344
345#endif
Note: See TracBrowser for help on using the repository browser.