Пример #1
0
static bool
bdbuf_tests_create_task (bdbuf_task_control* tc,
                         rtems_task_priority priority,
                         rtems_task_entry    entry_point)
{
  rtems_status_code sc;

  bdbuf_test_printf ("creating task: %s: priority: %d: ",
                     tc->name, priority);

  sc = rtems_task_create (rtems_build_name (tc->name[0], tc->name[1],
                                            tc->name[2], tc->name[3]),
                          priority,
                          BDBUF_TEST_STACK_SIZE,
                          RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
                          RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR,
                          &tc->task);
  if (!bdbuf_test_print_sc (sc, true))
    return false;

  bdbuf_test_printf ("starting task: %s: ", tc->name);

  sc = rtems_task_start (tc->task, entry_point, (rtems_task_argument) tc);

  return bdbuf_test_print_sc (sc, true);
}
Пример #2
0
static void
bdbuf_tests_task_0_test_7 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;
  dev_t               device;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Clear any disk settings.
   */
  bdbuf_clear_disk_driver_watch (tc);
  bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP);

  device = rtems_filesystem_make_dev_t (tc->major, tc->minor);

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i);
    sc = rtems_bdbuf_get (device, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                       tc->name, i);
    bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
    passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd),
                                  true);
  }

  if (passed)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: ",
                       tc->name, i,
                       rtems_filesystem_dev_major_t (device),
                       rtems_filesystem_dev_minor_t (device));
    passed = bdbuf_test_print_sc (rtems_bdbuf_syncdev (device), true);
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #3
0
/**
 * Read the block 5 from the disk modify it then release it modified.
 */
static void
bdbuf_tests_task_0_test_3 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  rtems_bdbuf_buffer* bd;
  dev_t               device;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  device = rtems_filesystem_make_dev_t (tc->major, tc->minor);

  bdbuf_disk_lock (&bdbuf_disks[tc->minor]);
  bdbuf_disks[tc->minor].driver_action = BDBUF_DISK_NOOP;
  bdbuf_disk_unlock (&bdbuf_disks[tc->minor]);

  /*
   * Read the buffer and then release it.
   */
  bdbuf_test_printf ("%s: rtems_bdbuf_read[5]: ", tc->name);
  sc = rtems_bdbuf_read (device, 5, &bd);
  if ((passed = bdbuf_test_print_sc (sc, true)))
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[5]: ", tc->name);
    sc = rtems_bdbuf_release_modified (bd);
    passed = bdbuf_test_print_sc (sc, true);
  }

  /*
   * Read the buffer again and then just release. The buffer should
   * be maintained as modified.
   */
  bdbuf_test_printf ("%s: rtems_bdbuf_read[5]: ", tc->name);
  sc = rtems_bdbuf_read (device, 5, &bd);
  if ((passed = bdbuf_test_print_sc (sc, true)))
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release[5]: ", tc->name);
    sc = rtems_bdbuf_release (bd);
    passed = bdbuf_test_print_sc (sc, true);
  }

  /*
   * Set up a disk watch and wait for the write to happen.
   */
  bdbuf_set_disk_driver_watch (tc, 1);
  passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

  tc->passed = passed;
  tc->test = 0;
}
Пример #4
0
/**
 * Get the blocks 0 -> 4 and release them. Task 0 should be holding
 * each one.
 */
static void
bdbuf_tests_ranged_get_release (bdbuf_task_control* tc,
                                bool                wake_master,
                                int                 lower,
                                int                 upper)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  for (i = lower; (i < upper) && passed; i++)
  {
    dev_t device = rtems_filesystem_make_dev_t (tc->major, tc->minor);

    bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: blocking ...\n", tc->name, i);
    sc = rtems_bdbuf_get (device, i, &bd);
    bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: ", tc->name, i);
    if (!bdbuf_test_print_sc (sc, true))
    {
      passed = false;
      break;
    }

    bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: ", tc->name, i);
    sc = rtems_bdbuf_release (bd);
    if (!bdbuf_test_print_sc (sc, true))
    {
      passed = false;
      break;
    }

    /*
     * Wake the master to tell it we have finished.
     */
    if (wake_master)
      bdbuf_send_wait_event (tc->name, "wake master", tc->master);
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #5
0
/**
 * BDBuf disk device driver initialization.
 *
 * @param major Disk major device number.
 * @param minor Minor device number, not applicable.
 * @param arg Initialization argument, not applicable.
 */
static rtems_device_driver
bdbuf_disk_initialize (rtems_device_major_number major,
                       rtems_device_minor_number minor,
                       void*                     arg)
{
  rtems_status_code sc;

  bdbuf_test_printf ("disk io init: ");
  sc = rtems_disk_io_initialize ();
  if (!bdbuf_test_print_sc (sc, true))
    return sc;

  for (minor = 0; minor < BDBUF_DISKS; minor++)
  {
    char              name[sizeof (BDBUF_DISK_DEVICE_BASE_NAME) + 10];
    bdbuf_disk*       bdd = &bdbuf_disks[minor];
    rtems_status_code sc;

    snprintf (name, sizeof (name),
              BDBUF_DISK_DEVICE_BASE_NAME "%" PRIu32, minor);

    bdd->name = strdup (name);

    bdbuf_test_printf ("disk init: %s\n", bdd->name);
    bdbuf_test_printf ("disk lock: ");

    sc = rtems_semaphore_create (rtems_build_name ('B', 'D', 'D', 'K'), 1,
                                 RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE |
                                 RTEMS_INHERIT_PRIORITY, 0, &bdd->lock);
    if (!bdbuf_test_print_sc (sc, true))
      return RTEMS_IO_ERROR;

    bdd->block_size  = 512 * (minor + 1);
    bdd->block_count = BDBUF_SIZE * (minor + 1);

    sc = rtems_disk_create_phys(rtems_filesystem_make_dev_t (major, minor),
                                bdd->block_size, bdd->block_count,
                                bdbuf_disk_ioctl, bdd, name);
    if (sc != RTEMS_SUCCESSFUL)
    {
      bdbuf_test_printf ("disk init: create phys failed: ");
      bdbuf_test_print_sc (sc, true);
      return sc;
    }

  }
  return RTEMS_SUCCESSFUL;
}
Пример #6
0
/**
 * BDBuf disk device driver lock.
 */
static bool
bdbuf_disk_lock (bdbuf_disk* bdd)
{
  rtems_status_code sc;
  sc = rtems_semaphore_obtain (bdd->lock, RTEMS_WAIT, 0);
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("disk ioctl: lock failed: ");
    bdbuf_test_print_sc (sc, true);
    return false;
  }
  return true;
}
Пример #7
0
/**
 * BDBuf disk device driver unlock.
 */
static bool
bdbuf_disk_unlock (bdbuf_disk* bdd)
{
  rtems_status_code sc;
  sc = rtems_semaphore_release (bdd->lock);
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("disk ioctl: unlock failed: ");
    bdbuf_test_print_sc (sc, true);
    return false;
  }
  return true;
}
Пример #8
0
/**
 * BDBUF Sleep.
 */
static bool
bdbuf_sleep (unsigned long msecs)
{
  rtems_status_code sc;
  sc = rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (msecs * 1000));
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("sleep wake after failed: ");
    bdbuf_test_print_sc (sc, true);
    return false;
  }
  return true;
}
Пример #9
0
/**
 * Wait for the disk driver watch.
 */
static bool
bdbuf_disk_driver_watch_wait (bdbuf_task_control* tc, unsigned long msecs)
{
  bool              passed = true;
  rtems_status_code sc = bdbuf_watch (msecs);
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("%s: driver watch: driver wait: ", tc->name);
    passed = bdbuf_test_print_sc (sc, true);
  }
  bdbuf_clear_disk_driver_watch (tc);
  return passed;
}
Пример #10
0
/**
 * Get the block 0 buffer twice. The first time it is requested it
 * will be taken from the empty list and returned to the LRU list.
 * The second time it will be removed from the LRU list.
 */
static void
bdbuf_tests_task_0_test_1 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  for (i = 0; (i < 2) && passed; i++)
  {
    dev_t device = rtems_filesystem_make_dev_t (tc->major, tc->minor);

    bdbuf_test_printf ("%s: rtems_bdbuf_get[0]: ", tc->name);
    sc = rtems_bdbuf_get (device, 0, &bd);
    if (!bdbuf_test_print_sc (sc, true))
    {
      passed = false;
      break;
    }

    bdbuf_test_printf ("%s: rtems_bdbuf_release[0]: ", tc->name);
    sc = rtems_bdbuf_release (bd);
    if (!bdbuf_test_print_sc (sc, true))
    {
      passed = false;
      break;
    }
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #11
0
/**
 * BDBUf wait for the wait event.
 */
rtems_status_code
bdbuf_wait (const char* who, unsigned long timeout)
{
  rtems_status_code sc;
  rtems_event_set   out;
  sc = rtems_event_receive (RTEMS_EVENT_0,
                            RTEMS_WAIT | RTEMS_EVENT_ANY,
                            TOD_MICROSECONDS_TO_TICKS (timeout * 1000),
                            &out);
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("%s: wait: receive failed: ", who);
    bdbuf_test_print_sc (sc, true);
  }
  else if ((out & RTEMS_EVENT_0) == 0)
  {
    bdbuf_test_printf ("%s: wait: received wrong event: %08x", who, out);
  }
  return sc;
}
Пример #12
0
/**
 * BDBUf wait for the wait event.
 */
static rtems_status_code
bdbuf_watch (unsigned long timeout)
{
  rtems_status_code sc;
  rtems_event_set   out;
  sc = rtems_event_receive (RTEMS_EVENT_1,
                            RTEMS_WAIT | RTEMS_EVENT_ANY,
                            RTEMS_MICROSECONDS_TO_TICKS (timeout * 1000),
                            &out);
  if (sc != RTEMS_SUCCESSFUL)
  {
    bdbuf_test_printf ("watch: receive failed: ");
    bdbuf_test_print_sc (sc, true);
  }
  else if ((out & RTEMS_EVENT_1) == 0)
  {
    bdbuf_test_printf ("watch: received wrong event: %08x", out);
  }
  return sc;
}
Пример #13
0
/**
 * Get all the blocks in the pool and hold them. Wake the master to tell it was
 * have the buffers then wait for the master to tell us to release them.
 */
static void
bdbuf_tests_task_0_test_4 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  size_t              i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;
  size_t              num = bdbuf_test_buffer_count ();

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Clear any disk settings.
   */
  bdbuf_clear_disk_driver_watch (tc);
  bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP);

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < num) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i);
    sc = rtems_bdbuf_read (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  /*
   * Wake the master to tell it we have the buffers.
   */
  bdbuf_send_wait_event (tc->name, "wake master", tc->master);

  if (passed)
  {
    bdbuf_sleep (250);

    bdbuf_set_disk_driver_watch (tc, num / 2);

    /*
     * Release half the buffers, wait 500msecs then release the
     * remainder. This tests the swap out timer on each buffer.
     */
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[0]: unblocks task 1\n",
                       tc->name);
    bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
    sc = rtems_bdbuf_release_modified (bd);
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[0]: ", tc->name);
    passed = bdbuf_test_print_sc (sc, true);
    if (passed)
    {
      for (i = 1; (i < (num / 2)) && passed; i++)
      {
        bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: " \
                           "unblocks task 1\n", tc->name, i);
        bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
        sc = rtems_bdbuf_release_modified (bd);
        bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                           tc->name, i);
        passed = bdbuf_test_print_sc (sc, true);
        if (!passed)
          break;
      }

      if (passed)
      {
        passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

        if (passed)
        {
          bdbuf_sleep (500);

          bdbuf_set_disk_driver_watch (tc, num / 2);

          for (i = 0; (i < (num / 2)) && passed; i++)
          {
            bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                               tc->name, i + (num / 2));
            bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
            passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd),
                                          true);
            if (!passed)
              break;
          }

          passed = bdbuf_disk_driver_watch_wait (tc, BDBUF_SECONDS (5));

          if (passed)
          {
            if (!rtems_chain_is_empty (&buffers))
            {
              passed = false;
              bdbuf_test_printf ("%s: buffer chain not empty\n", tc->name);
            }
          }
        }
      }
    }
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #14
0
/**
 * Get the blocks 0 -> 4 and hold them. Wake the master to tell it was have the
 * buffers then wait for the master to tell us to release a single buffer.
 * Task 1 will be block waiting for each buffer. It is a higher priority.
 */
static void
bdbuf_tests_task_0_test_2 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: ", tc->name, i);
    sc = rtems_bdbuf_get (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  /*
   * Wake the master to tell it we have the buffers.
   */
  bdbuf_send_wait_event (tc->name, "wake master", tc->master);

  if (passed)
  {
    /*
     * For each buffer we hold wait until the master wakes us
     * and then return it. Task 2 will block waiting for this
     * buffer. It is a higher priority task.
     */
    for (i = 0; (i < 5) && passed; i++)
    {
      sc = bdbuf_wait (tc->name, BDBUF_SECONDS (5));
      if (sc != RTEMS_SUCCESSFUL)
      {
        bdbuf_test_printf ("%s: wait failed: ", tc->name);
        bdbuf_test_print_sc (sc, true);
        passed = false;
        break;
      }
      else
      {
        bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: unblocks task 1\n",
                           tc->name, i);
        bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
        sc = rtems_bdbuf_release (bd);
        bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: ", tc->name, i);
        if (!bdbuf_test_print_sc (sc, true))
        {
          passed = false;
          break;
        }
      }
    }
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #15
0
/**
 * BDBUf send wait event.
 */
static bool
bdbuf_send_watch_event (const char* task, const char* msg, rtems_id id)
{
  bdbuf_test_printf ("%s: %s: %08x: ", task, msg, id);
  return  bdbuf_test_print_sc (rtems_event_send (id, RTEMS_EVENT_1), true);
}
Пример #16
0
static void
bdbuf_tests_task_0_test_8 (bdbuf_task_control* tc)
{
  rtems_status_code   sc;
  bool                passed;
  int                 i;
  rtems_bdbuf_buffer* bd;
  rtems_chain_control buffers;
  rtems_chain_node*   node;
  rtems_chain_node*   pnode;

  /*
   * Set task control's passed to false to handle a timeout.
   */
  tc->passed = false;
  passed = true;

  /*
   * Clear any disk settings.
   */
  bdbuf_clear_disk_driver_watch (tc);
  bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP);

  /*
   * Get the blocks 0 -> 4 and hold them.
   */
  rtems_chain_initialize_empty (&buffers);

  for (i = 0; (i < 5) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i);
    sc = rtems_bdbuf_get (tc->dd, i, &bd);
    if (!bdbuf_test_print_sc (sc, true))
      passed = false;

    rtems_chain_append (&buffers, &bd->link);
  }

  node = rtems_chain_tail (&buffers);
  node = node->previous;

  bd = (rtems_bdbuf_buffer*) node;
  pnode = node->previous;
  rtems_chain_extract (node);
  node = pnode;
  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name);
  passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);

  bd = (rtems_bdbuf_buffer*) node;
  pnode = node->previous;
  rtems_chain_extract (node);
  node = pnode;
  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
  passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);

  for (i = 0; (i < 3) && passed; i++)
  {
    bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ",
                       tc->name, i);
    bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers);
    passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd),
                                  true);
  }

  if (passed)
  {
    /*
     * Check the block order.
     */
    bdbuf_set_disk_driver_action (tc, BDBUF_DISK_BLOCKS_INORDER);

    bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: checking order\n",
                       tc->name, i,
                       tc->major,
                       tc->minor);
    sc = rtems_bdbuf_syncdev (tc->dd);
    bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: ",
                       tc->name, i,
                       tc->major,
                       tc->minor);
    passed = bdbuf_test_print_sc (sc, true);
  }

  tc->passed = passed;
  tc->test = 0;
}
Пример #17
0
/**
 * Test the BD Buffering code.
 */
static void
bdbuf_tester (void)
{
  rtems_device_major_number major;
  bdbuf_task_control        tasks[BDBUF_TEST_TASKS];
  rtems_task_priority       old_priority;
  int                       t;
  bool                      passed = true;
  rtems_disk_device        *dd;

  /*
   * Change priority to a lower one.
   */
  bdbuf_test_printf ("lower priority to %d: ", BDBUF_TESTS_PRI_HIGH + 1);
  bdbuf_test_print_sc (rtems_task_set_priority (RTEMS_SELF,
                                                BDBUF_TESTS_PRI_HIGH + 1,
                                                &old_priority),
                       true);

  /*
   * This sets up the buffer pools.
   */
  if (!bdbuf_tests_setup_disk (&major, &dd))
  {
    bdbuf_test_printf ("disk set up failed\n");
    return;
  }

  /*
   * Make sure the swapout task has run. The user could block
   * the swapout task from running until later. This is not
   * tested.
   */
  bdbuf_sleep (100);

  /*
   * Start the test tasks used to test the threading parts
   * of the bdbuf code.
   */
  for (t = 0; t < BDBUF_TEST_TASKS; t++)
  {
    bdbuf_task_control_init (t, &tasks[t],
                             rtems_task_self (),
                             major,
                             dd);

    if (!bdbuf_tests_create_task (&tasks[t],
                                  BDBUF_TESTS_PRI_HIGH - t,
                                  bdbuf_test_tasks[t]))
    return;
  }

  /*
   * Let the test tasks run if they have not already done so.
   */
  bdbuf_sleep (100);

  /*
   * Perform each test.
   */
  for (t = 0; (t < BDBUF_TEST_NUM) && passed; t++)
  {
    bdbuf_test_printf ("test %d: %s\n", t + 1, bdbuf_tests[t].label);
    passed = bdbuf_tests[t].test (tasks);
    bdbuf_test_printf ("test %d: %s\n", t + 1, passed ? "passed" : "failed");
  }
}