Changeset 71cf3e9d in rtems for cpukit/libblock


Ignore:
Timestamp:
Feb 20, 2013, 12:30:43 PM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
75e5127
Parents:
57bcb88e
git-author:
Sebastian Huber <sebastian.huber@…> (02/20/13 12:30:43)
git-committer:
Sebastian Huber <sebastian.huber@…> (02/21/13 09:50:04)
Message:

libblock: Do resource allocation in one place

All resource allocations take place in rtems_bdbuf_init() now. After
rtems_bdbuf_init() no fatal errors can happen due to configuration
errors or resource limits. This makes it easier to detect
configuration errors for users.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libblock/src/bdbuf.c

    r57bcb88e r71cf3e9d  
    5959  rtems_disk_device    *dd;          /**< The device the transfer is for. */
    6060  bool                  syncing;     /**< The data is a sync'ing. */
    61   rtems_blkdev_request* write_req;   /**< The write request array. */
     61  rtems_blkdev_request  write_req;   /**< The write request. */
    6262} rtems_bdbuf_swapout_transfer;
    6363
     
    9494                                          * enabled. Set to false to kill the
    9595                                          * swap out task. It deletes itself. */
    96   rtems_chain_control swapout_workers;  /**< The work threads for the swapout
    97                                           * task. */
     96  rtems_chain_control swapout_free_workers; /**< The work threads for the swapout
     97                                             * task. */
    9898
    9999  rtems_bdbuf_buffer* bds;               /**< Pointer to table of buffer
     
    129129  rtems_bdbuf_waiters buffer_waiters;    /**< Wait for a buffer and no one is
    130130                                          * available. */
     131
     132  rtems_bdbuf_swapout_transfer *swapout_transfer;
     133  rtems_bdbuf_swapout_worker *swapout_workers;
    131134
    132135  size_t              group_count;       /**< The number of groups. */
     
    149152  RTEMS_BDBUF_FATAL_RA_WAKE_UP,
    150153  RTEMS_BDBUF_FATAL_RECYCLE,
    151   RTEMS_BDBUF_FATAL_SO_REQ_NOMEM,
    152   RTEMS_BDBUF_FATAL_SO_WK_NOMEM,
    153154  RTEMS_BDBUF_FATAL_SO_WAKE_1,
    154155  RTEMS_BDBUF_FATAL_SO_WAKE_2,
    155   RTEMS_BDBUF_FATAL_SO_WK_CREATE,
    156156  RTEMS_BDBUF_FATAL_STATE_0,
    157157  RTEMS_BDBUF_FATAL_STATE_2,
     
    12811281  rtems_task_priority priority,
    12821282  rtems_task_priority default_priority,
    1283   rtems_task_entry entry,
    1284   rtems_task_argument arg,
    12851283  rtems_id *id
    12861284)
     
    12991297                          id);
    13001298
    1301   if (sc == RTEMS_SUCCESSFUL)
    1302     sc = rtems_task_start (*id, entry, arg);
     1299  return sc;
     1300}
     1301
     1302static rtems_bdbuf_swapout_transfer*
     1303rtems_bdbuf_swapout_transfer_alloc (void)
     1304{
     1305  /*
     1306   * @note chrisj The rtems_blkdev_request and the array at the end is a hack.
     1307   * I am disappointment at finding code like this in RTEMS. The request should
     1308   * have been a rtems_chain_control. Simple, fast and less storage as the node
     1309   * is already part of the buffer structure.
     1310   */
     1311  size_t transfer_size = sizeof (rtems_bdbuf_swapout_transfer)
     1312    + (bdbuf_config.max_write_blocks * sizeof (rtems_blkdev_sg_buffer));
     1313  return calloc (1, transfer_size);
     1314}
     1315
     1316static void
     1317rtems_bdbuf_transfer_done (rtems_blkdev_request* req, rtems_status_code status);
     1318
     1319static void
     1320rtems_bdbuf_swapout_transfer_init (rtems_bdbuf_swapout_transfer* transfer,
     1321                                   rtems_id id)
     1322{
     1323  rtems_chain_initialize_empty (&transfer->bds);
     1324  transfer->dd = BDBUF_INVALID_DEV;
     1325  transfer->syncing = false;
     1326  transfer->write_req.req = RTEMS_BLKDEV_REQ_WRITE;
     1327  transfer->write_req.done = rtems_bdbuf_transfer_done;
     1328  transfer->write_req.io_task = id;
     1329}
     1330
     1331static size_t
     1332rtems_bdbuf_swapout_worker_size (void)
     1333{
     1334  return sizeof (rtems_bdbuf_swapout_worker)
     1335    + (bdbuf_config.max_write_blocks * sizeof (rtems_blkdev_sg_buffer));
     1336}
     1337
     1338static rtems_task
     1339rtems_bdbuf_swapout_worker_task (rtems_task_argument arg);
     1340
     1341static rtems_status_code
     1342rtems_bdbuf_swapout_workers_create (void)
     1343{
     1344  rtems_status_code  sc;
     1345  size_t             w;
     1346  size_t             worker_size;
     1347  char              *worker_current;
     1348
     1349  worker_size = rtems_bdbuf_swapout_worker_size ();
     1350  worker_current = calloc (1, bdbuf_config.swapout_workers * worker_size);
     1351  if (!worker_current)
     1352    sc = RTEMS_NO_MEMORY;
     1353
     1354  bdbuf_cache.swapout_workers = (rtems_bdbuf_swapout_worker *) worker_current;
     1355
     1356  for (w = 0;
     1357       sc == RTEMS_SUCCESSFUL && w < bdbuf_config.swapout_workers;
     1358       w++, worker_current += worker_size)
     1359  {
     1360    rtems_bdbuf_swapout_worker *worker = (rtems_bdbuf_swapout_worker *) worker_current;
     1361
     1362    sc = rtems_bdbuf_create_task (rtems_build_name('B', 'D', 'o', 'a' + w),
     1363                                  bdbuf_config.swapout_worker_priority,
     1364                                  RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT,
     1365                                  &worker->id);
     1366    if (sc == RTEMS_SUCCESSFUL)
     1367    {
     1368      rtems_bdbuf_swapout_transfer_init (&worker->transfer, worker->id);
     1369
     1370      rtems_chain_append_unprotected (&bdbuf_cache.swapout_free_workers, &worker->link);
     1371      worker->enabled = true;
     1372
     1373      sc = rtems_task_start (worker->id,
     1374                             rtems_bdbuf_swapout_worker_task,
     1375                             (rtems_task_argument) worker);
     1376    }
     1377  }
    13031378
    13041379  return sc;
     
    13581433  bdbuf_cache.sync_device = BDBUF_INVALID_DEV;
    13591434
    1360   rtems_chain_initialize_empty (&bdbuf_cache.swapout_workers);
     1435  rtems_chain_initialize_empty (&bdbuf_cache.swapout_free_workers);
    13611436  rtems_chain_initialize_empty (&bdbuf_cache.lru);
    13621437  rtems_chain_initialize_empty (&bdbuf_cache.modified);
     
    14701545
    14711546  /*
    1472    * Create and start swapout task. This task will create and manage the worker
    1473    * threads.
     1547   * Create and start swapout task.
    14741548   */
     1549
     1550  bdbuf_cache.swapout_transfer = rtems_bdbuf_swapout_transfer_alloc ();
     1551  if (!bdbuf_cache.swapout_transfer)
     1552    goto error;
     1553
    14751554  bdbuf_cache.swapout_enabled = true;
    14761555
     
    14781557                                bdbuf_config.swapout_priority,
    14791558                                RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT,
    1480                                 rtems_bdbuf_swapout_task,
    1481                                 0,
    14821559                                &bdbuf_cache.swapout);
    14831560  if (sc != RTEMS_SUCCESSFUL)
    14841561    goto error;
     1562
     1563  rtems_bdbuf_swapout_transfer_init (bdbuf_cache.swapout_transfer, bdbuf_cache.swapout);
     1564
     1565  sc = rtems_task_start (bdbuf_cache.swapout,
     1566                         rtems_bdbuf_swapout_task,
     1567                         (rtems_task_argument) bdbuf_cache.swapout_transfer);
     1568  if (sc != RTEMS_SUCCESSFUL)
     1569    goto error;
     1570
     1571  if (bdbuf_config.swapout_workers > 0)
     1572  {
     1573    sc = rtems_bdbuf_swapout_workers_create ();
     1574    if (sc != RTEMS_SUCCESSFUL)
     1575      goto error;
     1576  }
    14851577
    14861578  if (bdbuf_config.max_read_ahead_blocks > 0)
     
    14901582                                  bdbuf_config.read_ahead_priority,
    14911583                                  RTEMS_BDBUF_READ_AHEAD_TASK_PRIORITY_DEFAULT,
    1492                                   rtems_bdbuf_read_ahead_task,
    1493                                   0,
    14941584                                  &bdbuf_cache.read_ahead_task);
    14951585    if (sc != RTEMS_SUCCESSFUL)
    14961586      goto error;
     1587
     1588    sc = rtems_task_start (bdbuf_cache.read_ahead_task,
     1589                           rtems_bdbuf_read_ahead_task,
     1590                           0);
     1591    if (sc != RTEMS_SUCCESSFUL)
     1592      goto error;
    14971593  }
    14981594
     
    15081604  if (bdbuf_cache.swapout != 0)
    15091605    rtems_task_delete (bdbuf_cache.swapout);
     1606
     1607  if (bdbuf_cache.swapout_workers)
     1608  {
     1609    char   *worker_current = (char *) bdbuf_cache.swapout_workers;
     1610    size_t  worker_size = rtems_bdbuf_swapout_worker_size ();
     1611    size_t  w;
     1612
     1613    for (w = 0;
     1614         w < bdbuf_config.swapout_workers;
     1615         w++, worker_current += worker_size)
     1616    {
     1617      rtems_bdbuf_swapout_worker *worker = (rtems_bdbuf_swapout_worker *) worker_current;
     1618
     1619      if (worker->id != 0) {
     1620        rtems_task_delete (worker->id);
     1621      }
     1622    }
     1623  }
    15101624
    15111625  free (bdbuf_cache.buffers);
    15121626  free (bdbuf_cache.groups);
    15131627  free (bdbuf_cache.bds);
     1628  free (bdbuf_cache.swapout_transfer);
     1629  free (bdbuf_cache.swapout_workers);
    15141630
    15151631  rtems_semaphore_delete (bdbuf_cache.buffer_waiters.sema);
     
    23122428     * trouble waiting to happen.
    23132429     */
    2314     transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
    2315     transfer->write_req->bufnum = 0;
     2430    transfer->write_req.status = RTEMS_RESOURCE_IN_USE;
     2431    transfer->write_req.bufnum = 0;
    23162432
    23172433    while ((node = rtems_chain_get_unprotected(&transfer->bds)) != NULL)
     
    23292445      if (rtems_bdbuf_tracer)
    23302446        printf ("bdbuf:swapout write: bd:%" PRIu32 ", bufnum:%" PRIu32 " mode:%s\n",
    2331                 bd->block, transfer->write_req->bufnum,
     2447                bd->block, transfer->write_req.bufnum,
    23322448                need_continuous_blocks ? "MULTI" : "SCAT");
    23332449
    2334       if (need_continuous_blocks && transfer->write_req->bufnum &&
     2450      if (need_continuous_blocks && transfer->write_req.bufnum &&
    23352451          bd->block != last_block + media_blocks_per_block)
    23362452      {
     
    23412457      {
    23422458        rtems_blkdev_sg_buffer* buf;
    2343         buf = &transfer->write_req->bufs[transfer->write_req->bufnum];
    2344         transfer->write_req->bufnum++;
     2459        buf = &transfer->write_req.bufs[transfer->write_req.bufnum];
     2460        transfer->write_req.bufnum++;
    23452461        buf->user   = bd;
    23462462        buf->block  = bd->block;
     
    23562472
    23572473      if (rtems_chain_is_empty (&transfer->bds) ||
    2358           (transfer->write_req->bufnum >= bdbuf_config.max_write_blocks))
     2474          (transfer->write_req.bufnum >= bdbuf_config.max_write_blocks))
    23592475        write = true;
    23602476
    23612477      if (write)
    23622478      {
    2363         rtems_bdbuf_execute_transfer_request (dd, transfer->write_req, false);
    2364 
    2365         transfer->write_req->status = RTEMS_RESOURCE_IN_USE;
    2366         transfer->write_req->bufnum = 0;
     2479        rtems_bdbuf_execute_transfer_request (dd, &transfer->write_req, false);
     2480
     2481        transfer->write_req.status = RTEMS_RESOURCE_IN_USE;
     2482        transfer->write_req.bufnum = 0;
    23672483      }
    23682484    }
     
    25422658  {
    25432659    worker = (rtems_bdbuf_swapout_worker*)
    2544       rtems_chain_get_unprotected (&bdbuf_cache.swapout_workers);
     2660      rtems_chain_get_unprotected (&bdbuf_cache.swapout_free_workers);
    25452661    if (worker)
    25462662      transfer = &worker->transfer;
     
    26222738
    26232739/**
    2624  * Allocate the write request and initialise it for good measure.
    2625  *
    2626  * @return rtems_blkdev_request* The write reference memory.
    2627  */
    2628 static rtems_blkdev_request*
    2629 rtems_bdbuf_swapout_writereq_alloc (void)
    2630 {
    2631   /*
    2632    * @note chrisj The rtems_blkdev_request and the array at the end is a hack.
    2633    * I am disappointment at finding code like this in RTEMS. The request should
    2634    * have been a rtems_chain_control. Simple, fast and less storage as the node
    2635    * is already part of the buffer structure.
    2636    */
    2637   rtems_blkdev_request* write_req =
    2638     malloc (sizeof (rtems_blkdev_request) +
    2639             (bdbuf_config.max_write_blocks * sizeof (rtems_blkdev_sg_buffer)));
    2640 
    2641   if (!write_req)
    2642     rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_SO_REQ_NOMEM);
    2643 
    2644   write_req->req = RTEMS_BLKDEV_REQ_WRITE;
    2645   write_req->done = rtems_bdbuf_transfer_done;
    2646   write_req->io_task = rtems_task_self ();
    2647 
    2648   return write_req;
    2649 }
    2650 
    2651 /**
    26522740 * The swapout worker thread body.
    26532741 *
     
    26712759    worker->transfer.dd = BDBUF_INVALID_DEV;
    26722760
    2673     rtems_chain_append_unprotected (&bdbuf_cache.swapout_workers, &worker->link);
     2761    rtems_chain_append_unprotected (&bdbuf_cache.swapout_free_workers, &worker->link);
    26742762
    26752763    rtems_bdbuf_unlock_cache ();
    26762764  }
    26772765
    2678   free (worker->transfer.write_req);
    26792766  free (worker);
    26802767
     
    26832770
    26842771/**
    2685  * Open the swapout worker threads.
    2686  */
    2687 static void
    2688 rtems_bdbuf_swapout_workers_open (void)
    2689 {
    2690   rtems_status_code sc;
    2691   size_t            w;
     2772 * Close the swapout worker threads.
     2773 */
     2774static void
     2775rtems_bdbuf_swapout_workers_close (void)
     2776{
     2777  rtems_chain_node* node;
    26922778
    26932779  rtems_bdbuf_lock_cache ();
    26942780
    2695   for (w = 0; w < bdbuf_config.swapout_workers; w++)
    2696   {
    2697     rtems_bdbuf_swapout_worker* worker;
    2698 
    2699     worker = malloc (sizeof (rtems_bdbuf_swapout_worker));
    2700     if (!worker)
    2701       rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_SO_WK_NOMEM);
    2702 
    2703     rtems_chain_append_unprotected (&bdbuf_cache.swapout_workers, &worker->link);
    2704     worker->enabled = true;
    2705     worker->transfer.write_req = rtems_bdbuf_swapout_writereq_alloc ();
    2706 
    2707     rtems_chain_initialize_empty (&worker->transfer.bds);
    2708     worker->transfer.dd = BDBUF_INVALID_DEV;
    2709 
    2710     sc = rtems_bdbuf_create_task (rtems_build_name('B', 'D', 'o', 'a' + w),
    2711                                   bdbuf_config.swapout_worker_priority,
    2712                                   RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT,
    2713                                   rtems_bdbuf_swapout_worker_task,
    2714                                   (rtems_task_argument) worker,
    2715                                   &worker->id);
    2716     if (sc != RTEMS_SUCCESSFUL)
    2717       rtems_bdbuf_fatal (RTEMS_BDBUF_FATAL_SO_WK_CREATE);
    2718   }
    2719 
    2720   rtems_bdbuf_unlock_cache ();
    2721 }
    2722 
    2723 /**
    2724  * Close the swapout worker threads.
    2725  */
    2726 static void
    2727 rtems_bdbuf_swapout_workers_close (void)
    2728 {
    2729   rtems_chain_node* node;
    2730 
    2731   rtems_bdbuf_lock_cache ();
    2732 
    2733   node = rtems_chain_first (&bdbuf_cache.swapout_workers);
    2734   while (!rtems_chain_is_tail (&bdbuf_cache.swapout_workers, node))
     2781  node = rtems_chain_first (&bdbuf_cache.swapout_free_workers);
     2782  while (!rtems_chain_is_tail (&bdbuf_cache.swapout_free_workers, node))
    27352783  {
    27362784    rtems_bdbuf_swapout_worker* worker = (rtems_bdbuf_swapout_worker*) node;
     
    27532801rtems_bdbuf_swapout_task (rtems_task_argument arg)
    27542802{
    2755   rtems_bdbuf_swapout_transfer transfer;
    2756   uint32_t                     period_in_ticks;
    2757   const uint32_t               period_in_msecs = bdbuf_config.swapout_period;
    2758   uint32_t                     timer_delta;
    2759 
    2760   transfer.write_req = rtems_bdbuf_swapout_writereq_alloc ();
    2761   rtems_chain_initialize_empty (&transfer.bds);
    2762   transfer.dd = BDBUF_INVALID_DEV;
    2763   transfer.syncing = false;
     2803  rtems_bdbuf_swapout_transfer* transfer = (rtems_bdbuf_swapout_transfer *) arg;
     2804  uint32_t                      period_in_ticks;
     2805  const uint32_t                period_in_msecs = bdbuf_config.swapout_period;
     2806  uint32_t                      timer_delta;
    27642807
    27652808  /*
     
    27722815   */
    27732816  timer_delta = period_in_msecs;
    2774 
    2775   /*
    2776    * Create the worker threads.
    2777    */
    2778   rtems_bdbuf_swapout_workers_open ();
    27792817
    27802818  while (bdbuf_cache.swapout_enabled)
     
    28062844      if (rtems_bdbuf_swapout_processing (timer_delta,
    28072845                                          update_timers,
    2808                                           &transfer))
     2846                                          transfer))
    28092847      {
    28102848        transfered_buffers = true;
     
    28292867  rtems_bdbuf_swapout_workers_close ();
    28302868
    2831   free (transfer.write_req);
     2869  free (transfer);
    28322870
    28332871  rtems_task_delete (RTEMS_SELF);
Note: See TracChangeset for help on using the changeset viewer.