Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:32

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2016, 2018 Chris Johns <chrisj@rtems.org>.  All rights reserved.
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include "tmacros.h"
0033 
0034 #include <fcntl.h>
0035 #include <sys/types.h>
0036 #include <unistd.h>
0037 #include <stdlib.h>
0038 #include <stdio.h>
0039 
0040 #include <rtems/rtl/rtl.h>
0041 #include <rtems/rtl/rtl-obj-cache.h>
0042 #include <rtems/rtl/rtl-trace.h>
0043 
0044 #include "dl-cache.h"
0045 
0046 #define CACHE_SIZE         (2048)
0047 #define CACHE_SIZE_TOO_BIG (-1)
0048 #define CACHE_BUFFER_SIZE  (CACHE_SIZE * 4)
0049 
0050 static uint8_t* contents;
0051 
0052 static const char *const filename = "/dl-test";
0053 
0054 static void dl_cache_create_file(void)
0055 {
0056   uint16_t* p;
0057   int       fd;
0058   int       i;
0059   rtems_test_assert((contents = malloc(CACHE_BUFFER_SIZE)) != NULL);
0060   memset(contents, 0, CACHE_BUFFER_SIZE);
0061   p = (uint16_t*) contents;
0062   for (i = 0; i < (CACHE_BUFFER_SIZE / sizeof(uint16_t)); ++i)
0063     *p++ = i;
0064   rtems_test_assert((fd = open(filename,
0065                                O_WRONLY | O_TRUNC | O_CREAT,
0066                                S_IRUSR | S_IWUSR)) >= 0);
0067   rtems_test_assert(write(fd, contents, CACHE_BUFFER_SIZE) == CACHE_BUFFER_SIZE);
0068   rtems_test_assert(close(fd) >= 0);
0069 }
0070 
0071 static bool dl_cache_check(void* buffer, off_t offset, size_t length)
0072 {
0073   uint16_t* b;
0074   uint16_t* c;
0075   int       i;
0076   b = buffer;
0077   c = (uint16_t*) (contents + offset);
0078   printf("cache:   buffer: ");
0079   for (i = 0; i < 4; ++i)
0080     printf("%04x/%04x ", b[i], c[i]);
0081   printf("\n");
0082   return memcmp(buffer, contents + offset, length) == 0;
0083 }
0084 
0085 static off_t dl_cache_buffer_offset(rtems_rtl_obj_cache* cache, void* buffer)
0086 {
0087   return (off_t) (((uint8_t*) buffer) - ((uint8_t*) cache->buffer));
0088 }
0089 
0090 static void dl_init_rtl(void)
0091 {
0092   /*
0093    * Check the RTL object is created and can be locked and unlocked.
0094    */
0095   rtems_test_assert(rtems_rtl_data_unprotected () == NULL);
0096   rtems_test_assert(rtems_rtl_lock () != NULL);
0097   rtems_rtl_unlock ();
0098   rtems_test_assert(rtems_rtl_data_unprotected () != NULL);
0099   rtems_rtl_trace_set_mask(RTEMS_RTL_TRACE_ALL | RTEMS_RTL_TRACE_CACHE);
0100 }
0101 
0102 int dl_cache_test(void)
0103 {
0104   rtems_rtl_obj_cache cache;
0105   int                 fd;
0106   void*               buffer;
0107   off_t               offset_in;
0108   off_t               offset;
0109   size_t              length_in;
0110   size_t              length;
0111 
0112   /*
0113    * Make sure the RTL can initialise.
0114    */
0115   dl_init_rtl();
0116 
0117   /*
0118    * Create the file to test the cache with.
0119    */
0120   dl_cache_create_file();
0121 
0122   /*
0123    * Check the too big error is handled.
0124    */
0125   printf ("cache create with large size\n");
0126   rtems_test_assert(rtems_rtl_obj_cache_open(&cache,
0127                                              CACHE_SIZE_TOO_BIG) == false);
0128 
0129   /*
0130    * Create a cache.
0131    */
0132   printf ("cache create\n");
0133   rtems_test_assert(rtems_rtl_obj_cache_open(&cache,
0134                                              CACHE_SIZE) == true);
0135   rtems_test_assert(cache.fd == -1);
0136   rtems_test_assert(cache.file_size == 0);
0137   rtems_test_assert(cache.size == CACHE_SIZE);
0138   rtems_test_assert(cache.buffer != NULL);
0139 
0140   /*
0141    * Open the file to use with the cache tests.
0142    */
0143   printf ("cache file open\n");
0144   rtems_test_assert((fd = open(filename, O_RDONLY)) >= 0);
0145 
0146   buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 2;
0147   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0148   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0149                                              fd,
0150                                              offset_in,
0151                                              &buffer,
0152                                              &length) == true);
0153   offset = dl_cache_buffer_offset(&cache, buffer);
0154   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0155   rtems_test_assert(offset == offset_in);
0156   rtems_test_assert(length == length_in);
0157   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0158 
0159   buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE;
0160   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0161   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0162                                              fd,
0163                                              offset_in,
0164                                              &buffer,
0165                                              &length) == true);
0166   offset = dl_cache_buffer_offset(&cache, buffer);
0167   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0168   rtems_test_assert(offset == offset_in);
0169   rtems_test_assert(length == length_in);
0170   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0171 
0172   buffer = NULL; offset_in = CACHE_SIZE / 2; length_in = length = CACHE_SIZE / 2;
0173   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0174   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0175                                              fd,
0176                                              offset_in,
0177                                              &buffer,
0178                                              &length) == true);
0179   offset = dl_cache_buffer_offset(&cache, buffer);
0180   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0181   rtems_test_assert(offset == offset_in);
0182   rtems_test_assert(length == length_in);
0183   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0184 
0185   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - CACHE_SIZE; length_in = length = CACHE_SIZE;
0186   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0187   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0188                                              fd,
0189                                              offset_in,
0190                                              &buffer,
0191                                              &length) == true);
0192   offset = dl_cache_buffer_offset(&cache, buffer);
0193   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0194   rtems_test_assert(offset == 0);
0195   rtems_test_assert(length == length_in);
0196   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0197 
0198   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - (CACHE_SIZE / 2); length_in = length = CACHE_SIZE / 2;
0199   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0200   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0201                                              fd,
0202                                              offset_in,
0203                                              &buffer,
0204                                              &length) == true);
0205   offset = dl_cache_buffer_offset(&cache, buffer);
0206   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0207   rtems_test_assert(offset == (CACHE_SIZE / 2));
0208   rtems_test_assert(length == length_in);
0209   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0210 
0211   buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 4;
0212   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0213   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0214                                              fd,
0215                                              offset_in,
0216                                              &buffer,
0217                                              &length) == true);
0218   offset = dl_cache_buffer_offset(&cache, buffer);
0219   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0220   rtems_test_assert(offset == offset_in);
0221   rtems_test_assert(length == length_in);
0222   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0223 
0224   buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE / 8;
0225   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0226   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0227                                              fd,
0228                                              offset_in,
0229                                              &buffer,
0230                                              &length) == true);
0231   offset = dl_cache_buffer_offset(&cache, buffer);
0232   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0233   rtems_test_assert(offset == offset_in);
0234   rtems_test_assert(length == length_in);
0235   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0236 
0237   buffer = NULL; offset_in = 0; length_in = length = CACHE_SIZE;
0238   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0239   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0240                                              fd,
0241                                              offset_in,
0242                                              &buffer,
0243                                              &length) == true);
0244   offset = dl_cache_buffer_offset(&cache, buffer);
0245   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0246   rtems_test_assert(offset == offset_in);
0247   rtems_test_assert(length == length_in);
0248   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0249 
0250   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 16;
0251   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0252   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0253                                              fd,
0254                                              offset_in,
0255                                              &buffer,
0256                                              &length) == true);
0257   offset = dl_cache_buffer_offset(&cache, buffer);
0258   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0259   rtems_test_assert(length == length_in);
0260   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0261 
0262   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 40;
0263   printf("cache read: in: offset=%d length=%d\n", (int) offset_in, (int) length);
0264   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0265                                              fd,
0266                                              offset_in,
0267                                              &buffer,
0268                                              &length) == true);
0269   offset = dl_cache_buffer_offset(&cache, buffer);
0270   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0271   rtems_test_assert(length == length_in);
0272   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0273 
0274   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40; length_in = length = 80;
0275   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0276   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0277                                              fd,
0278                                              offset_in,
0279                                              &buffer,
0280                                              &length) == true);
0281   offset = dl_cache_buffer_offset(&cache, buffer);
0282   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0283   rtems_test_assert(length == 40);
0284   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0285 
0286   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - CACHE_SIZE + 80;
0287   length_in = length = 20;
0288   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0289   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0290                                              fd,
0291                                              offset_in,
0292                                              &buffer,
0293                                              &length) == true);
0294   offset = dl_cache_buffer_offset(&cache, buffer);
0295   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0296   rtems_test_assert(length == length_in);
0297   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0298 
0299   buffer = NULL; offset_in = CACHE_BUFFER_SIZE - 40;
0300   length_in = length = 40;
0301   printf("cache read:  in: offset=%d length=%d\n", (int) offset_in, (int) length);
0302   rtems_test_assert(rtems_rtl_obj_cache_read(&cache,
0303                                              fd,
0304                                              offset_in,
0305                                              &buffer,
0306                                              &length) == true);
0307   offset = dl_cache_buffer_offset(&cache, buffer);
0308   printf("cache read: out: offset=%d length=%d\n", (int) offset, (int) length);
0309   rtems_test_assert(length == length_in);
0310   rtems_test_assert(dl_cache_check(buffer, (int) offset_in, length) == true);
0311 
0312   rtems_rtl_obj_cache_close(&cache);
0313 
0314   return 0;
0315 }