Skip to contentSkip to conversation

Fio's initial RTEMS port

PATCH New [email protected] 3 participants 9 messages Jul 16, 2018 – Aug 1, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fio's initial RTEMS port

Following IOengines are currently working on RTEMS:
- psync, sync, vsync, filecreate, ftruncate, null

I've attached the patch in my following mail, please have a look.

Here's the corresponding ticket:https://devel.rtems.org/ticket/3429 Please note that i have also sent the patch to [email protected], for their review of rtems-specific part.

#1 lore raw

PATCH 1/1 Fio's initial RTEMS port

From: Udit kumar agarwal <[email protected]>

- Add rtems-specific config files.
- Constructors/Destructors being not supported by RTEMS, should be invoked as normal routines.
- Add documentation for RTEMS
- Update Makefile, os.h for RTEMS

---
 Makefile                  |  11 ++-
 README                    |  29 ++++++
 cgroup.c                  |   7 +-
 client.c                  |   7 +-
 configure                 |   2 +
 crc/xxhash.h              |  15 ++++
 engines/cpu.c             |  14 ++-
 engines/falloc.c          |   7 +-
 engines/filecreate.c      |  14 ++-
 engines/ftruncate.c       |  14 ++-
 engines/glusterfs_async.c |   7 +-
 engines/glusterfs_sync.c  |  14 ++-
 engines/mmap.c            |  14 ++-
 engines/net.c             |  14 ++-
 engines/null.c            |  14 ++-
 engines/sync.c            |  14 ++-
 fio.c                     |   3 +
 fio.h                     |  10 ++-
 fio_sem.c                 |   6 ++
 gettime.c                 |  14 ++-
 init.c                    |  26 +++++-
 ioengines.c               |   2 +
 lib/prio_tree.c           |   7 +-
 options.c                 |   6 +-
 os/os-rtems.h             |  70 +++++++++++++++
 os/os.h                   |   3 +
 os/rtems/rtems-fio-wrap.h |  54 +++++++++++
 os/rtems/rtems-init.c     | 225 ++++++++++++++++++++++++++++++++++++++++++++++
 oslib/inet_aton.c         |   3 +-
 profiles/act.c            |  14 ++-
 profiles/tiobench.c       |  14 ++-
 smalloc.c                 |  11 ++-
 stat.c                    |   6 ++
 t/arch.c                  |   2 +
 34 files changed, 638 insertions(+), 35 deletions(-)
 create mode 100644 os/os-rtems.h
 create mode 100644 os/rtems/rtems-fio-wrap.h
 create mode 100644 os/rtems/rtems-init.c
Makefile +10 -1
index 20d3ec1..e93f964 100644
@@ -194,11 +194,20 @@ ifneq (,$(findstring CYGWIN,$(CONFIG_TARGET_OS)))
   LIBS	 += -lpthread -lpsapi -lws2_32
   CFLAGS += -DPSAPI_VERSION=1 -Ios/windows/posix/include -Wno-format -static
 endif
+ifeq ($(CONFIG_TARGET_OS), RTEMS)
+  LDFLAGS += -B $(TOOL_PATH_PREFIX)/arm-rtems5/beagleboneblack/lib -specs bsp_specs -qrtems -Wl,--gc-sections
+  LIBS	  += -Wl,-Bstatic -L. -lbsd -Wl,-Bdynamic -lm -lz
+  CFLAGS  += -I $(TOOL_PATH_PREFIX)/arm-rtems5/beagleboneblack/lib/include -ffunction-sections -fdata-sections -g -mcpu=cortex-a8 -fno-strict-aliasing -ffreestanding -fno-common -w -DHAVE_RTEMS_SCORE_CPUOPTS_H=1 -DHAVE_RTEMS_H=1 -DHAVE_DLFCN_H=1 -DHAVE_RTEMS_PCI_H=1 -DHAVE_RTEMS_RTEMS_DEBUGGER_H=1
+endif
 
 OBJS := $(SOURCE:.c=.o)
 
 FIO_OBJS = $(OBJS) fio.o
 
+ifeq ($(CONFIG_TARGET_OS), RTEMS)
+  FIO_OBJS +=  os/rtems/rtems-init.o
+endif
+
 GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o gerror.o \
 			gclient.o gcompat.o cairo_text_helpers.o printing.o
 
@@ -462,7 +471,7 @@ t/time-test: $(T_TT_OBJS)
 	$(QUIET_LINK)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_TT_OBJS) $(LIBS)
 
 clean: FORCE
-	@rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio FIO-VERSION-FILE *.[do] lib/*.d oslib/*.[do] crc/*.d engines/*.[do] profiles/*.[do] t/*.[do] config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h
+	@rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio FIO-VERSION-FILE *.[do] lib/*.d oslib/*.[do] crc/*.d engines/*.[do] profiles/*.[do] t/*.[do] config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h os/rtems/*.[do]
 	@rm -rf  doc/output
 
 distclean: clean FORCE
README +29 -0
index 38022bb..cbca933 100644
@@ -192,6 +192,35 @@ https://github.com/mintty/mintty/issues/56 and
 https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs
 for details).
 
+RTEMS
+~~~~~~~
+
+For RTEMS Toolchain generation::
+
+Toolchain, required for cross-compiling fio for desired architecture
+(like arm in this example) can be generated by using RTEMS Source Builder(RSB).
+
+Please note that fio's build for RTEMS has been tested with RSB version 5(commit id:
+25f4db09c85a52fb1640a29f9bdc2de8c2768988), and it may not work with older versions.
+
+Moreover, For enabling POSIX support(required by fio), build the BSP using RTEMS v5 with
+--enable-posix option. After that, if needed(like for using SD card driver for BeagleBone Black)
+one may also need to build rtems-libbsd for the desired BSP.
+
+For Cross-compiling fio for RTEMS::
+
+Variable to be passed for toolchain path is TOOL_PATH_PREFIX, which in this case would be,
+
+ $ export TOOL_PATH_PREFIX=/home/uka_in/development/sandbox/5
+
+After setting up the variable, next step would be to configure and build fio as:
+
+ $ make clean
+ $ ./configure --cc=$TOOL_PATH_PREFIX/bin/arm-rtems5-gcc --disable-optimizations --extra-cflags=-O3
+ $ make CROSS_COMPILE=$TOOL_PATH_PREFIX/bin/arm-rtems5- V=1
+
+Refer to ticket #3429 https://devel.rtems.org/ticket/3429 for updates and
+drawbacks of current implementation.
 
 Documentation
 ~~~~~~~~~~~~~
cgroup.c +6 -1
index 77e31a4..0a3d372 100644
@@ -224,7 +224,12 @@ out:
 	sfree(mnt);
 }
 
-static void fio_init cgroup_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+cgroup_init(void)
 {
 	lock = fio_sem_init(FIO_SEM_UNLOCKED);
 	if (!lock)
client.c +6 -1
index 2a86ea9..cb4ef56 100644
@@ -86,7 +86,12 @@ static void fio_client_remove_hash(struct fio_client *client)
 		flist_del_init(&client->hash_list);
 }
 
-static void fio_init fio_client_hash_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_client_hash_init(void)
 {
 	int i;
 
configure +2 -0
index 9bdc7a1..53dd857 100755
@@ -262,6 +262,8 @@ elif check_define __sun__ ; then
   CFLAGS="$CFLAGS -D_REENTRANT"
 elif check_define _WIN32 ; then
   targetos='CYGWIN'
+elif check_define __rtems__ ; then
+  targetos='RTEMS'
 else
   targetos=`uname -s`
 fi
crc/xxhash.h +15 -0
index 8850d20..81bf51d 100644
@@ -107,9 +107,16 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 
+/* Unlike most desktop OS, In Newlib unsigned int and uint32_t are different */
+#ifndef __rtems__
 void*         XXH32_init   (unsigned int seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
 unsigned int  XXH32_digest (void* state);
+#else /* __rtems__ */
+void*         XXH32_init   (uint32_t seed);
+XXH_errorcode XXH32_update (void* state, const void* input, int len);
+uint32_t  XXH32_digest (void* state);
+#endif /* __rtems__ */
 
 /*
 These functions calculate the xxhash of an input provided in several small packets,
@@ -135,7 +142,11 @@ Memory will be freed by XXH32_digest().
 
 
 int           XXH32_sizeofState(void);
+#ifndef __rtems__
 XXH_errorcode XXH32_resetState(void* state, unsigned int seed);
+#else /* __rtems__ */
+XXH_errorcode XXH32_resetState(void* state, uint32_t seed);
+#endif /* __rtems__ */
 
 #define       XXH32_SIZEOFSTATE 48
 typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
@@ -151,7 +162,11 @@ use the structure XXH32_stateSpace_t, which will ensure that memory space is lar
 */
 
 
+#ifndef __rtems__
 unsigned int XXH32_intermediateDigest (void* state);
+#else /* __rtems__ */
+uint32_t XXH32_intermediateDigest (void* state);
+#endif /* __rtems__ */
 /*
 This function does the same as XXH32_digest(), generating a 32-bit hash,
 but preserve memory context.
engines/cpu.c +12 -2
index 0987250..9838af1 100644
@@ -112,12 +112,22 @@ static struct ioengine_ops ioengine = {
 	.option_struct_size	= sizeof(struct cpu_options),
 };
 
-static void fio_init fio_cpuio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_cpuio_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_cpuio_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_cpuio_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/falloc.c +6 -1
index 6382569..446638c 100644
@@ -101,7 +101,12 @@ static struct ioengine_ops ioengine = {
 	.flags		= FIO_SYNCIO
 };
 
-static void fio_init fio_syncio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_syncio_register(void)
 {
 	register_ioengine(&ioengine);
 }
engines/filecreate.c +12 -2
index 39a2950..35dc5d7 100644
@@ -107,12 +107,22 @@ static struct ioengine_ops ioengine = {
 				FIO_NOSTATS | FIO_NOFILEHASH,
 };
 
-static void fio_init fio_filecreate_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_filecreate_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_filecreate_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_filecreate_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/ftruncate.c +12 -2
index c7ad038..ab616be 100644
@@ -41,12 +41,22 @@ static struct ioengine_ops ioengine = {
 	.flags		= FIO_SYNCIO | FIO_FAKEIO
 };
 
-static void fio_init fio_syncio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_syncio_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_syncio_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_syncio_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/glusterfs_async.c +6 -1
index 9e1c4bf..0f1083b 100644
@@ -177,7 +177,12 @@ static struct ioengine_ops ioengine = {
 	.flags = FIO_DISKLESSIO,
 };
 
-static void fio_init fio_gf_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_gf_register(void)
 {
 	register_ioengine(&ioengine);
 }
engines/glusterfs_sync.c +12 -2
index a10e0ed..b634ce8 100644
@@ -88,12 +88,22 @@ static struct ioengine_ops ioengine = {
 	.flags = FIO_SYNCIO | FIO_DISKLESSIO,
 };
 
-static void fio_init fio_gf_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_gf_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_gf_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_gf_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/mmap.c +12 -2
index 308b466..7ce6ebf 100644
@@ -277,12 +277,22 @@ static struct ioengine_ops ioengine = {
 	.flags		= FIO_SYNCIO | FIO_NOEXTEND,
 };
 
-static void fio_init fio_mmapio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_mmapio_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_mmapio_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_mmapio_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/net.c +12 -2
index ca6fb34..5222601 100644
@@ -1451,7 +1451,12 @@ static int str_hostname_cb(void *data, const char *input)
 	return 0;
 }
 
-static void fio_init fio_netio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_netio_register(void)
 {
 	register_ioengine(&ioengine_rw);
 #ifdef CONFIG_LINUX_SPLICE
@@ -1459,7 +1464,12 @@ static void fio_init fio_netio_register(void)
 #endif
 }
 
-static void fio_exit fio_netio_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_netio_unregister(void)
 {
 	unregister_ioengine(&ioengine_rw);
 #ifdef CONFIG_LINUX_SPLICE
engines/null.c +12 -2
index 4cc0102..da10d69 100644
@@ -154,12 +154,22 @@ static struct ioengine_ops ioengine = {
 	.flags		= FIO_DISKLESSIO | FIO_FAKEIO,
 };
 
-static void fio_init fio_null_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_null_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_null_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_null_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/sync.c +12 -2
index b3e1c9d..4b98f4d 100644
@@ -466,7 +466,12 @@ static struct ioengine_ops ioengine_pvrw2 = {
 };
 #endif
 
-static void fio_init fio_syncio_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+fio_syncio_register(void)
 {
 	register_ioengine(&ioengine_rw);
 	register_ioengine(&ioengine_prw);
@@ -479,7 +484,12 @@ static void fio_init fio_syncio_register(void)
 #endif
 }
 
-static void fio_exit fio_syncio_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_syncio_unregister(void)
 {
 	unregister_ioengine(&ioengine_rw);
 	unregister_ioengine(&ioengine_prw);
fio.c +3 -0
index f19db1b..d4e0821 100644
@@ -65,3 +65,6 @@ done:
 	deinitialize_fio();
 	return ret;
 }
+#ifdef __rtems__
+#include <os/rtems/rtems-fio-wrap.h>
+#endif /* __rtems__ */
fio.h +9 -1
index 3ac552b..e382eb7 100644
@@ -785,7 +785,11 @@ static inline void td_flags_clear(struct thread_data *td, unsigned int *flags,
 	if (!td_async_processing(td))
 		*flags &= ~value;
 	else
+#ifndef __rtems__
 		__sync_fetch_and_and(flags, ~value);
+#else /* __rtems__ */
+		atomic_fetch_and_explicit(flags, ~value, memory_order_relaxed);
+#endif /* __rtems__ */
 }
 
 static inline void td_flags_set(struct thread_data *td, unsigned int *flags,
@@ -794,7 +798,11 @@ static inline void td_flags_set(struct thread_data *td, unsigned int *flags,
 	if (!td_async_processing(td))
 		*flags |= value;
 	else
-		__sync_fetch_and_or(flags, value);
+#ifndef __rtems__
+		__sync_fetch_and_or(flags, ~value);
+#else /*__rtems__ */
+		atomic_fetch_or_explicit(flags, ~value, memory_order_relaxed);
+#endif /* __rtems__ */
 }
 
 extern const char *fio_get_arch_string(int);
fio_sem.c +6 -0
index 3b48061..b5bc9c2 100644
@@ -56,9 +56,15 @@ struct fio_sem *fio_sem_init(int value)
 {
 	struct fio_sem *sem = NULL;
 
+#ifndef __rtems__
 	sem = (void *) mmap(NULL, sizeof(struct fio_sem),
 				PROT_READ | PROT_WRITE,
 				OS_MAP_ANON | MAP_SHARED, -1, 0);
+#else /* __rtems__ */
+	sem = (void *) mmap(NULL, sizeof(struct fio_sem),
+				PROT_READ | PROT_WRITE,
+				OS_MAP_ANON | MAP_PRIVATE, -1, 0);
+#endif /* __rtems__ */
 	if (sem == MAP_FAILED) {
 		perror("mmap semaphore");
 		return NULL;
gettime.c +12 -2
index c0f2638..03f11eb 100644
@@ -94,7 +94,12 @@ static void gtod_log_caller(void *caller)
 		inc_caller(caller);
 }
 
-static void fio_exit fio_dump_gtod(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+fio_dump_gtod(void)
 {
 	unsigned long total_calls = 0;
 	int i;
@@ -115,7 +120,12 @@ static void fio_exit fio_dump_gtod(void)
 	printf("Total %lu gettimeofday\n", total_calls);
 }
 
-static void fio_init gtod_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+gtod_init(void)
 {
 	int i;
 
init.c +23 -3
index af4cc6b..d69b644 100644
@@ -7,7 +7,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/ipc.h>
 #include <sys/types.h>
 #include <dlfcn.h>
 #ifdef CONFIG_VALGRIND_DEV
@@ -21,6 +20,10 @@
 #include <sys/shm.h>
 #endif
 
+#ifndef __rtems__
+#include <sys/ipc.h>
+#endif /* __rtems__ */
+
 #include "parse.h"
 #include "smalloc.h"
 #include "filehash.h"
@@ -31,7 +34,13 @@
 #include "filelock.h"
 #include "steadystate.h"
 
+/* RTEMS uses newlib's getopt_long_only_r() */
+#ifdef __rtems__
+#include <getopt.h>
+#else /* __rtems__ */
 #include "oslib/getopt.h"
+#endif /* __rtems__ */
+
 #include "oslib/strcasestr.h"
 
 #include "crc/test.h"
@@ -87,6 +96,10 @@ unsigned int *fio_warned = NULL;
 static char cmd_optstr[256];
 static bool did_arg;
 
+#ifdef __rtems__
+    struct getopt_data getopt_reent;
+#endif /* __rtems__ */
+
 #define FIO_CLIENT_FLAG		(1 << 16)
 
 /*
@@ -2435,13 +2448,20 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
 	void *cur_client = NULL;
 	int backend = 0;
 
+#ifdef __rtems__
+    memset(&getopt_reent, 0, sizeof(getopt_data));
+#endif /* __rtems__ */
 	/*
 	 * Reset optind handling, since we may call this multiple times
 	 * for the backend.
 	 */
 	optind = 1;
-
-	while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) {
+	while ((c =
+#ifdef __rtems__ /* Using Newlib's reentrant version of getopt */
+		getopt_long_only_r(argc, argv, ostr, l_opts, &lidx, &getopt_reent))!= -1) {
+#else /* __rtems__ */
+		getopt_long_only(argc, argv, ostr, l_opts, &lidx))!= -1) {
+#endif /* __rtems__ */
 		if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
 			parse_cmd_client(cur_client, argv[optind - 1]);
 			c &= ~FIO_CLIENT_FLAG;
ioengines.c +2 -0
index d579682..c051ed5 100644
@@ -185,6 +185,7 @@ struct ioengine_ops *load_ioengine(struct thread_data *td)
  */
 void free_ioengine(struct thread_data *td)
 {
+#ifndef __rtems__
 	dprint(FD_IO, "free ioengine %s\n", td->io_ops->name);
 
 	if (td->eo && td->io_ops->options) {
@@ -199,6 +200,7 @@ void free_ioengine(struct thread_data *td)
 	}
 
 	td->io_ops = NULL;
+#endif /* __rtems__ */
 }
 
 void close_ioengine(struct thread_data *td)
lib/prio_tree.c +6 -1
index d8e1b89..95b55a8 100644
@@ -53,7 +53,12 @@ static void get_index(const struct prio_tree_node *node,
 
 static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
 
-static void fio_init prio_tree_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+prio_tree_init(void)
 {
 	unsigned int i;
 
options.c +5 -1
index a174e2c..0abb5b1 100644
@@ -4744,7 +4744,7 @@ static char *bc_calc(char *str)
 	if ((!strchr(str, '+') && !strchr(str, '-') && !strchr(str, '*') &&
 	     !strchr(str, '/')) || strchr(str, '\''))
 		return str;
-
+#ifndef __rtems__
 	/*
 	 * Split option from value, we only need to calculate the value
 	 */
@@ -4782,6 +4782,10 @@ static char *bc_calc(char *str)
 	memcpy(buf, str, tmp - str);
 	free(str);
 	return strdup(buf);
+#else /* __rtems__ */
+	log_err("fio: performing math is not supported\n");
+	return NULL;
+#endif /* __rtems__ */
 }
 
 /*
os/os-rtems.h new file +70 -0

70 lines not on this page · raw message

os/os.h +3 -0
index becc410..bc230dc 100644
@@ -23,6 +23,7 @@ enum {
 	os_windows,
 	os_android,
 	os_dragonfly,
+	os_rtems,
 
 	os_nr,
 };
@@ -36,6 +37,8 @@ typedef enum {
 #include "os-android.h"
 #elif defined(__linux__)
 #include "os-linux.h"
+#elif defined (__rtems__)
+#include "os-rtems.h"
 #elif defined(__FreeBSD__)
 #include "os-freebsd.h"
 #elif defined(__OpenBSD__)
os/rtems/rtems-fio-wrap.h new file +54 -0

54 lines not on this page · raw message

os/rtems/rtems-init.c new file +225 -0

225 lines not on this page · raw message

oslib/inet_aton.c +2 -1
index 7ae7db7..5bbc05b 100644
@@ -1,6 +1,7 @@
 #include "inet_aton.h"
-
+#ifndef __rtems__
 int inet_aton(const char *cp, struct in_addr *inp)
 {
 	return inet_pton(AF_INET, cp, inp);
 }
+#endif
profiles/act.c +12 -2
index 5d3bd25..49a321f 100644
@@ -461,7 +461,12 @@ static struct profile_ops act_profile = {
 	.io_ops		= &act_io_ops,
 };
 
-static void fio_init act_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+act_register(void)
 {
 	act_run_data = calloc(1, sizeof(*act_run_data));
 	act_run_data->sem = fio_sem_init(FIO_SEM_UNLOCKED);
@@ -470,7 +475,12 @@ static void fio_init act_register(void)
 		log_err("fio: failed to register profile 'act'\n");
 }
 
-static void fio_exit act_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+act_unregister(void)
 {
 	while (org_idx && org_idx < opt_idx)
 		free((void *) act_opts[++org_idx]);
profiles/tiobench.c +12 -2
index f19a085..e36be66 100644
@@ -121,13 +121,23 @@ static struct profile_ops tiobench_profile = {
 	.opt_data	= &tiobench_options,
 };
 
-static void fio_init tiobench_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+tiobench_register(void)
 {
 	if (register_profile(&tiobench_profile))
 		log_err("fio: failed to register profile 'tiobench'\n");
 }
 
-static void fio_exit tiobench_unregister(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_exit
+#endif /* __rtems__ */
+tiobench_unregister(void)
 {
 	unregister_profile(&tiobench_profile);
 }
smalloc.c +10 -1
index a2ad25a..f42677a 100644
@@ -170,12 +170,17 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size)
 	pool->free_blocks = bitmap_blocks * SMALLOC_BPB;
 
 	mmap_flags = OS_MAP_ANON;
-#ifdef CONFIG_ESX
+#if defined(CONFIG_ESX)||defined(__rtems__)
 	mmap_flags |= MAP_PRIVATE;
 #else
 	mmap_flags |= MAP_SHARED;
 #endif
+
+#ifdef __rtems__
+	ptr = (void*)malloc(alloc_size);
+#else
 	ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE, mmap_flags, -1, 0);
+#endif
 
 	if (ptr == MAP_FAILED)
 		goto out_fail;
@@ -193,7 +198,11 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size)
 out_fail:
 	log_err("smalloc: failed adding pool\n");
 	if (pool->map)
+#ifdef __rtems__
+		free(pool->map);
+#else /* __rtems__ */
 		munmap(pool->map, pool->mmap_size);
+#endif /* __rtems__ */
 	return false;
 }
 
stat.c +6 -0
index a308eb8..093f216 100644
@@ -38,10 +38,16 @@ void update_rusage_stat(struct thread_data *td)
 					&td->ru_end.ru_utime);
 	ts->sys_time += mtime_since_tv(&td->ru_start.ru_stime,
 					&td->ru_end.ru_stime);
+#ifndef __rtems__ /* Virtual Memory not supported on RTEMS */
 	ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
 			- (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
 	ts->minf += td->ru_end.ru_minflt - td->ru_start.ru_minflt;
 	ts->majf += td->ru_end.ru_majflt - td->ru_start.ru_majflt;
+#else /* __rtems__ */
+	ts->ctx  = ((uint64_t) -1);
+	ts->minf = ((uint64_t) -1);
+	ts->majf = ((uint64_t) -1);
+#endif /* __rtems__ */
 
 	memcpy(&td->ru_start, &td->ru_end, sizeof(td->ru_end));
 }
t/arch.c +2 -0
index bd28a84..efee2db 100644
@@ -1,5 +1,7 @@
 #include "../arch/arch.h"
 
 unsigned long arch_flags = 0;
+#ifndef __rtems__
 bool tsc_reliable;
+#endif /* __rtems__ */
 int arch_random;
Signature · 1 line
1.9.1
#2 lore raw
Quoted 11 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of [email protected]
Sent: Monday, July 16, 2018 4:07 AM
To: [email protected]
Cc: Udit kumar agarwal <[email protected]>
Subject: [PATCH] Fio's initial RTEMS port

From: Udit kumar agarwal <[email protected]>

...

Quoted 14 lines
os/rtems/rtems-fio-wrap.h new file +8 -0
new file mode 100644
index 0000000..2c639cb
@@ -0,0 +1,54 @@
+/* RTEMS specific wrapper for explicitly calling constructors and
+ * destructors */
+
+void act_register(void);
+void tiobench_register(void);
+void fio_syncio_register(void);
+void fio_filecreate_register(void);
+void fio_null_register(void);

os/rtems/rtems-fio-wrap.h line 18

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+void prio_tree_init(void);
+void fio_syncio_register_ft(void);
+void fio_client_hash_init(void);
+void fio_syncio_unregister(void);
+void tiobench_unregister(void);
+void fio_filecreate_unregister(void);
+void fio_null_unregister(void);
+void act_unregister(void);
+void fio_syncio_unregister_ft(void);
+

This new wrapper for fio's main():

Quoted 18 lines
os/rtems/rtems-fio-wrap.h new file +18 -0
+static int
+mainwrapper(int argc, char *argv[])
+{
+	int err=0;
+
+	/* Constructors */
+	act_register();
+	tiobench_register();
+	fio_syncio_register();
+	fio_filecreate_register();
+	fio_null_register();
+	prio_tree_init();
+	fio_syncio_register_ft();
+	fio_client_hash_init();
+
+	err = main(argc, argv, (char *)NULL);
+
+	/* Destructors */

os/rtems/rtems-fio-wrap.h line 46

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+	fio_syncio_unregister();
+	tiobench_unregister();
+	fio_filecreate_unregister();
+	fio_null_unregister();
+	act_unregister();
+	fio_syncio_unregister_ft();
+
+	return err;
+}
+

and a bunch of these changes to the profile and engine source code exposing the register and unregister functions so the wrapper can call them:

os/rtems/rtems-fio-wrap.h

Quoted 7 lines
os/rtems/rtems-fio-wrap.h new file +6 -1
-static void fio_init act_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+act_register(void)

are a bit awkward.

fio's main() calls initialize_fio() which calls arch_init() and other functions, and add_job() initializes the profiles and engines needed by the job. Any reason that flow doesn't work in the RTEMS environment?

---
Robert Elliott, HPE Persistent Memory

#3 lore raw

Hi,

Quoted 83 lines · Robert (Persistent Memory)
Quoted 12 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of [email protected]
Sent: Monday, July 16, 2018 4:07 AM
To: [email protected]
Cc: Udit kumar agarwal <[email protected]>
Subject: [PATCH] Fio's initial RTEMS port

From: Udit kumar agarwal <[email protected]>

...

Quoted 14 lines
os/rtems/rtems-fio-wrap.h new file +8 -0
new file mode 100644
index 0000000..2c639cb
@@ -0,0 +1,54 @@
+/* RTEMS specific wrapper for explicitly calling constructors and
+ * destructors */
+
+void act_register(void);
+void tiobench_register(void);
+void fio_syncio_register(void);
+void fio_filecreate_register(void);
+void fio_null_register(void);

os/rtems/rtems-fio-wrap.h line 18

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+void prio_tree_init(void);
+void fio_syncio_register_ft(void);
+void fio_client_hash_init(void);
+void fio_syncio_unregister(void);
+void tiobench_unregister(void);
+void fio_filecreate_unregister(void);
+void fio_null_unregister(void);
+void act_unregister(void);
+void fio_syncio_unregister_ft(void);
+

This new wrapper for fio's main():

Quoted 18 lines
os/rtems/rtems-fio-wrap.h new file +18 -0
+static int
+mainwrapper(int argc, char *argv[])
+{
+     int err=0;
+
+     /* Constructors */
+     act_register();
+     tiobench_register();
+     fio_syncio_register();
+     fio_filecreate_register();
+     fio_null_register();
+     prio_tree_init();
+     fio_syncio_register_ft();
+     fio_client_hash_init();
+
+     err = main(argc, argv, (char *)NULL);
+
+     /* Destructors */

os/rtems/rtems-fio-wrap.h line 46

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+     fio_syncio_unregister();
+     tiobench_unregister();
+     fio_filecreate_unregister();
+     fio_null_unregister();
+     act_unregister();
+     fio_syncio_unregister_ft();
+
+     return err;
+}
+

and a bunch of these changes to the profile and engine source code exposing the register and unregister functions so the wrapper can call them:

os/rtems/rtems-fio-wrap.h

Quoted 7 lines
os/rtems/rtems-fio-wrap.h new file +6 -1
-static void fio_init act_register(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+act_register(void)

are a bit awkward.

Quoted 5 lines

fio's main() calls initialize_fio() which calls arch_init() and other functions, and add_job() initializes the profiles and engines needed by the job. Any reason that flow doesn't work in the RTEMS environment?

Actually, RTEMS is an RTOS for embedded systems and here every application has to be linked statically.
So, We have to manually call constructors before an application starts(as compiler wouldn't know where to put them). Application start is like boot up for us.

So, these changes includes calling up the constructors(functions with fio_init attribute) and destructors(the ones with fio_exit attr) like normal routines through the mainwrapper function. After that the regular flow of Fio routines works flawlessly.

Quoted 5 lines

---
Robert Elliott, HPE Persistent Memory

Signature · 3 lines
Regards,
Udit kumar agarwal
http://uditagarwal.in/
#4 lore raw
In reply to [email protected]
Quoted 5 lines · On 7/16/18 3:06 AM, [email protected] wrote:
cgroup.c +0 -0
index 77e31a4..0a3d372 100644

cgroup.c out: · line 232

Quoted 10 lines
cgroup.c +6 -1
@@ -224,7 +224,12 @@ out:
 	sfree(mnt);
 }
 
-static void fio_init cgroup_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+cgroup_init(void)

For all of these, just make the non-static for all platforms. I don't like having stuff like this all over the generic code. If need be, fio_init can be different for rtems.

Quoted 8 lines
crc/xxhash.h +0 -0
index 8850d20..81bf51d 100644
@@ -107,9 +107,16 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 

crc/xxhash.h XXH32() : · line 119

Quoted 10 lines
crc/xxhash.h +7 -0
+/* Unlike most desktop OS, In Newlib unsigned int and uint32_t are different */
+#ifndef __rtems__
 void*         XXH32_init   (unsigned int seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
 unsigned int  XXH32_digest (void* state);
+#else /* __rtems__ */
+void*         XXH32_init   (uint32_t seed);
+XXH_errorcode XXH32_update (void* state, const void* input, int len);
+uint32_t  XXH32_digest (void* state);
+#endif /* __rtems__ */

Same for this stuff, there's no need for this to be any different for rtems.

fio.c done: · line 70

Quoted 11 lines
fio.c +3 -0
index f19db1b..d4e0821 100644
@@ -65,3 +65,6 @@ done:
 	deinitialize_fio();
 	return ret;
 }
+#ifdef __rtems__
+#include <os/rtems/rtems-fio-wrap.h>
+#endif /* __rtems__ */

Put that in your OS header.

fio.h static inline void td_flags_clear(struct thread_data *td, unsigned int *flags, · line 792

Quoted 13 lines
fio.h +4 -0
index 3ac552b..e382eb7 100644
@@ -785,7 +785,11 @@ static inline void td_flags_clear(struct thread_data *td, unsigned int *flags,
 	if (!td_async_processing(td))
 		*flags &= ~value;
 	else
+#ifndef __rtems__
 		__sync_fetch_and_and(flags, ~value);
+#else /* __rtems__ */
+		atomic_fetch_and_explicit(flags, ~value, memory_order_relaxed);
+#endif /* __rtems__ */

Handle this in your OS header as well.

Quoted 7 lines
fio_sem.c +0 -0
index 3b48061..b5bc9c2 100644
@@ -56,9 +56,15 @@ struct fio_sem *fio_sem_init(int value)
 {
 	struct fio_sem *sem = NULL;

fio_sem.c struct fio_sem *fio_sem_init(int value) · line 67

Quoted 10 lines
fio_sem.c +6 -0
 
+#ifndef __rtems__
 	sem = (void *) mmap(NULL, sizeof(struct fio_sem),
 				PROT_READ | PROT_WRITE,
 				OS_MAP_ANON | MAP_SHARED, -1, 0);
+#else /* __rtems__ */
+	sem = (void *) mmap(NULL, sizeof(struct fio_sem),
+				PROT_READ | PROT_WRITE,
+				OS_MAP_ANON | MAP_PRIVATE, -1, 0);
+#endif /* __rtems__ */

Hmm?

General comment - everytime you feel the need to add an ifdef __rtems__ (or ifndef), you are going down the wrong path. Look at how the other OS types handle special cases and mimic that approach. Looks like your main difference is that you have to call initializers manually, which is a bit nasty. But differences in types etc should not be handled by having ifdefs in the generic code.

Signature · 1 line
Jens Axboe
#5 lore raw
Quoted 100 lines · Jens Axboe
Quoted 5 lines · On 7/16/18 3:06 AM, [email protected] wrote:
cgroup.c +0 -0
index 77e31a4..0a3d372 100644

cgroup.c out: · line 232

Quoted 10 lines
cgroup.c +6 -1
@@ -224,7 +224,12 @@ out:
      sfree(mnt);
 }
 
-static void fio_init cgroup_init(void)
+#ifdef __rtems__
+void
+#else /* __rtems__ */
+static void fio_init
+#endif /* __rtems__ */
+cgroup_init(void)

For all of these, just make the non-static for all platforms. I don't like having stuff like this all over the generic code. If need be, fio_init can be different for rtems.

Noted.

crc/xxhash.h XXH32() : · line 110

Quoted 9 lines
crc/xxhash.h +1 -0
index 8850d20..81bf51d 100644
@@ -107,9 +107,16 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 
+/* Unlike most desktop OS, In Newlib unsigned int and uint32_t are

different */

crc/xxhash.h XXH32() : · line 119

Quoted 9 lines
crc/xxhash.h +6 -0
+#ifndef __rtems__
 void*         XXH32_init   (unsigned int seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
 unsigned int  XXH32_digest (void* state);
+#else /* __rtems__ */
+void*         XXH32_init   (uint32_t seed);
+XXH_errorcode XXH32_update (void* state, const void* input, int len);
+uint32_t  XXH32_digest (void* state);
+#endif /* __rtems__ */

Same for this stuff, there's no need for this to be any different for rtems.

fio.c done: · line 70

Quoted 11 lines
fio.c +3 -0
index f19db1b..d4e0821 100644
@@ -65,3 +65,6 @@ done:
      deinitialize_fio();
      return ret;
 }
+#ifdef __rtems__
+#include <os/rtems/rtems-fio-wrap.h>
+#endif /* __rtems__ */

Put that in your OS header.

Ok

fio.h static inline void td_flags_clear(struct

Quoted 5 lines
fio.h +0 -0
index 3ac552b..e382eb7 100644
@@ -785,7 +785,11 @@ static inline void td_flags_clear(struct

thread_data *td, unsigned int *flags,

fio.h static inline void td_flags_clear(struct thread_data *td, unsigned int *flags,

Quoted 7 lines
fio.h +3 -0
      if (!td_async_processing(td))
              *flags &= ~value;
      else
+#ifndef __rtems__
              __sync_fetch_and_and(flags, ~value);
+#else /* __rtems__ */
+             atomic_fetch_and_explicit(flags, ~value,

memory_order_relaxed);

fio.h static inline void td_flags_clear(struct · line 792

Quoted 1 line
fio.h +1 -0
+#endif /* __rtems__ */

Handle this in your OS header as well.

Quoted 7 lines
fio_sem.c +0 -0
index 3b48061..b5bc9c2 100644
@@ -56,9 +56,15 @@ struct fio_sem *fio_sem_init(int value)
 {
      struct fio_sem *sem = NULL;

fio_sem.c struct fio_sem *fio_sem_init(int value) · line 67

Quoted 10 lines
fio_sem.c +6 -0
 
+#ifndef __rtems__
      sem = (void *) mmap(NULL, sizeof(struct fio_sem),
                              PROT_READ | PROT_WRITE,
                              OS_MAP_ANON | MAP_SHARED, -1, 0);
+#else /* __rtems__ */
+     sem = (void *) mmap(NULL, sizeof(struct fio_sem),
+                             PROT_READ | PROT_WRITE,
+                             OS_MAP_ANON | MAP_PRIVATE, -1, 0);
+#endif /* __rtems__ */

Hmm?

Quoted 8 lines

General comment - everytime you feel the need to add an ifdef __rtems__ (or ifndef), you are going down the wrong path. Look at how the other OS types handle special cases and mimic that approach. Looks like your main difference is that you have to call initializers manually, which is a bit nasty. But differences in types etc should not be handled by having ifdefs in the generic code.

Great! Thanks for your feedback. I was eagerly waiting for one. I'll make

the changes you told , probably by this weekend and will then resend the patch.

Quoted 4 lines

--
Jens Axboe

Signature · 3 lines
Regards,
Udit kumar agarwal
http://uditagarwal.in/
#6 lore raw

PATCH 1/1 Fio's initial RTEMS port

From: Udit kumar agarwal <[email protected]>

- Add rtems-specific config files.
- Constructors/Destructors being not supported by RTEMS, should be invoked as normal routines.
- Add documentation for RTEMS
- Update Makefile, os.h for RTEMS
- Make all constructors/destructors non-static
- Redefine fio_init for RTEMS
---
I have reworked the code, please have a look.

 Makefile                  |  11 ++-
 README                    |  29 ++++++
 cgroup.c                  |   4 +-
 client.c                  |   2 +-
 compiler/compiler.h       |   5 ++
 configure                 |   6 ++
 crc/xxhash.h              |   8 +-
 engines/cpu.c             |   4 +-
 engines/filecreate.c      |   4 +-
 engines/null.c            |   4 +-
 engines/sync.c            |   4 +-
 fio_sem.c                 |   2 +-
 init.c                    |  26 +++++-
 options.c                 |   6 +-
 os/os-rtems.h             |  74 +++++++++++++++
 os/os.h                   |   9 ++
 os/rtems/rtems-fio-wrap.h |  41 +++++++++
 os/rtems/rtems-init.c     | 224 ++++++++++++++++++++++++++++++++++++++++++++++
 smalloc.c                 |  13 +++
 stat.c                    |   6 ++
 20 files changed, 461 insertions(+), 21 deletions(-)
 create mode 100644 os/os-rtems.h
 create mode 100644 os/rtems/rtems-fio-wrap.h
 create mode 100644 os/rtems/rtems-init.c
Makefile +10 -1
index 20d3ec1..e93f964 100644
@@ -194,11 +194,20 @@ ifneq (,$(findstring CYGWIN,$(CONFIG_TARGET_OS)))
   LIBS	 += -lpthread -lpsapi -lws2_32
   CFLAGS += -DPSAPI_VERSION=1 -Ios/windows/posix/include -Wno-format -static
 endif
+ifeq ($(CONFIG_TARGET_OS), RTEMS)
+  LDFLAGS += -B $(TOOL_PATH_PREFIX)/arm-rtems5/beagleboneblack/lib -specs bsp_specs -qrtems -Wl,--gc-sections
+  LIBS	  += -Wl,-Bstatic -L. -lbsd -Wl,-Bdynamic -lm -lz
+  CFLAGS  += -I $(TOOL_PATH_PREFIX)/arm-rtems5/beagleboneblack/lib/include -ffunction-sections -fdata-sections -g -mcpu=cortex-a8 -fno-strict-aliasing -ffreestanding -fno-common -w -DHAVE_RTEMS_SCORE_CPUOPTS_H=1 -DHAVE_RTEMS_H=1 -DHAVE_DLFCN_H=1 -DHAVE_RTEMS_PCI_H=1 -DHAVE_RTEMS_RTEMS_DEBUGGER_H=1
+endif
 
 OBJS := $(SOURCE:.c=.o)
 
 FIO_OBJS = $(OBJS) fio.o
 
+ifeq ($(CONFIG_TARGET_OS), RTEMS)
+  FIO_OBJS +=  os/rtems/rtems-init.o
+endif
+
 GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o gerror.o \
 			gclient.o gcompat.o cairo_text_helpers.o printing.o
 
@@ -462,7 +471,7 @@ t/time-test: $(T_TT_OBJS)
 	$(QUIET_LINK)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_TT_OBJS) $(LIBS)
 
 clean: FORCE
-	@rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio FIO-VERSION-FILE *.[do] lib/*.d oslib/*.[do] crc/*.d engines/*.[do] profiles/*.[do] t/*.[do] config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h
+	@rm -f .depend $(FIO_OBJS) $(GFIO_OBJS) $(OBJS) $(T_OBJS) $(PROGS) $(T_PROGS) $(T_TEST_PROGS) core.* core gfio FIO-VERSION-FILE *.[do] lib/*.d oslib/*.[do] crc/*.d engines/*.[do] profiles/*.[do] t/*.[do] config-host.mak config-host.h y.tab.[ch] lex.yy.c exp/*.[do] lexer.h os/rtems/*.[do]
 	@rm -rf  doc/output
 
 distclean: clean FORCE
README +29 -0
index 38022bb..cbca933 100644
@@ -192,6 +192,35 @@ https://github.com/mintty/mintty/issues/56 and
 https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs
 for details).
 
+RTEMS
+~~~~~~~
+
+For RTEMS Toolchain generation::
+
+Toolchain, required for cross-compiling fio for desired architecture
+(like arm in this example) can be generated by using RTEMS Source Builder(RSB).
+
+Please note that fio's build for RTEMS has been tested with RSB version 5(commit id:
+25f4db09c85a52fb1640a29f9bdc2de8c2768988), and it may not work with older versions.
+
+Moreover, For enabling POSIX support(required by fio), build the BSP using RTEMS v5 with
+--enable-posix option. After that, if needed(like for using SD card driver for BeagleBone Black)
+one may also need to build rtems-libbsd for the desired BSP.
+
+For Cross-compiling fio for RTEMS::
+
+Variable to be passed for toolchain path is TOOL_PATH_PREFIX, which in this case would be,
+
+ $ export TOOL_PATH_PREFIX=/home/uka_in/development/sandbox/5
+
+After setting up the variable, next step would be to configure and build fio as:
+
+ $ make clean
+ $ ./configure --cc=$TOOL_PATH_PREFIX/bin/arm-rtems5-gcc --disable-optimizations --extra-cflags=-O3
+ $ make CROSS_COMPILE=$TOOL_PATH_PREFIX/bin/arm-rtems5- V=1
+
+Refer to ticket #3429 https://devel.rtems.org/ticket/3429 for updates and
+drawbacks of current implementation.
 
 Documentation
 ~~~~~~~~~~~~~
cgroup.c +2 -2
index 77e31a4..d7de428 100644
@@ -224,14 +224,14 @@ out:
 	sfree(mnt);
 }
 
-static void fio_init cgroup_init(void)
+void fio_init cgroup_init(void)
 {
 	lock = fio_sem_init(FIO_SEM_UNLOCKED);
 	if (!lock)
 		log_err("fio: failed to allocate cgroup lock\n");
 }
 
-static void fio_exit cgroup_exit(void)
+void fio_exit cgroup_exit(void)
 {
 	fio_sem_remove(lock);
 }
client.c +1 -1
index 2a86ea9..356f9c0 100644
@@ -86,7 +86,7 @@ static void fio_client_remove_hash(struct fio_client *client)
 		flist_del_init(&client->hash_list);
 }
 
-static void fio_init fio_client_hash_init(void)
+void fio_init fio_client_hash_init(void)
 {
 	int i;
 
compiler/compiler.h +5 -0
index dacb737..bb0abf1 100644
@@ -17,8 +17,13 @@
  * Mark unused variables passed to ops functions as unused, to silence gcc
  */
 #define fio_unused	__attribute__((__unused__))
+#ifndef CONFIG_NO_FIO_INIT
 #define fio_init	__attribute__((constructor))
 #define fio_exit	__attribute__((destructor))
+#else /* CONFIG_NO_FIO_INIT */
+#define fio_init
+#define fio_exit
+#endif /* CONFIG_NO_FIO_INIT */
 
 #define fio_unlikely(x)	__builtin_expect(!!(x), 0)
 
configure +6 -0
index 9bdc7a1..ad21020 100755
@@ -262,6 +262,8 @@ elif check_define __sun__ ; then
   CFLAGS="$CFLAGS -D_REENTRANT"
 elif check_define _WIN32 ; then
   targetos='CYGWIN'
+elif check_define __rtems__ ; then
+  targetos='RTEMS'
 else
   targetos=`uname -s`
 fi
@@ -362,6 +364,10 @@ CYGWIN*)
   tcp_nodelay="yes"
   ipv6="yes"
   ;;
+RTEMS)
+  inet_aton="yes"
+  output_sym "CONFIG_NO_FIO_INIT"
+  ;;
 esac
 
 # Now we know the target platform we can have another guess at the preferred
crc/xxhash.h +4 -4
index 8850d20..9019089 100644
@@ -107,9 +107,9 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 
-void*         XXH32_init   (unsigned int seed);
+void*         XXH32_init   (uint32_t seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
-unsigned int  XXH32_digest (void* state);
+uint32_t  XXH32_digest (void* state);
 
 /*
 These functions calculate the xxhash of an input provided in several small packets,
@@ -135,7 +135,7 @@ Memory will be freed by XXH32_digest().
 
 
 int           XXH32_sizeofState(void);
-XXH_errorcode XXH32_resetState(void* state, unsigned int seed);
+XXH_errorcode XXH32_resetState(void* state, uint32_t seed);
 
 #define       XXH32_SIZEOFSTATE 48
 typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
@@ -151,7 +151,7 @@ use the structure XXH32_stateSpace_t, which will ensure that memory space is lar
 */
 
 
-unsigned int XXH32_intermediateDigest (void* state);
+uint32_t XXH32_intermediateDigest (void* state);
 /*
 This function does the same as XXH32_digest(), generating a 32-bit hash,
 but preserve memory context.
engines/cpu.c +2 -2
index 0987250..baa4680 100644
@@ -112,12 +112,12 @@ static struct ioengine_ops ioengine = {
 	.option_struct_size	= sizeof(struct cpu_options),
 };
 
-static void fio_init fio_cpuio_register(void)
+void fio_init fio_cpuio_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_cpuio_unregister(void)
+void fio_exit fio_cpuio_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/filecreate.c +2 -2
index 39a2950..e24539c 100644
@@ -107,12 +107,12 @@ static struct ioengine_ops ioengine = {
 				FIO_NOSTATS | FIO_NOFILEHASH,
 };
 
-static void fio_init fio_filecreate_register(void)
+void fio_init fio_filecreate_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_filecreate_unregister(void)
+void fio_exit fio_filecreate_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/null.c +2 -2
index 4cc0102..f364118 100644
@@ -154,12 +154,12 @@ static struct ioengine_ops ioengine = {
 	.flags		= FIO_DISKLESSIO | FIO_FAKEIO,
 };
 
-static void fio_init fio_null_register(void)
+void fio_init fio_null_register(void)
 {
 	register_ioengine(&ioengine);
 }
 
-static void fio_exit fio_null_unregister(void)
+void fio_exit fio_null_unregister(void)
 {
 	unregister_ioengine(&ioengine);
 }
engines/sync.c +2 -2
index b3e1c9d..3a1e1bb 100644
@@ -466,7 +466,7 @@ static struct ioengine_ops ioengine_pvrw2 = {
 };
 #endif
 
-static void fio_init fio_syncio_register(void)
+void fio_init fio_syncio_register(void)
 {
 	register_ioengine(&ioengine_rw);
 	register_ioengine(&ioengine_prw);
@@ -479,7 +479,7 @@ static void fio_init fio_syncio_register(void)
 #endif
 }
 
-static void fio_exit fio_syncio_unregister(void)
+void fio_exit fio_syncio_unregister(void)
 {
 	unregister_ioengine(&ioengine_rw);
 	unregister_ioengine(&ioengine_prw);
fio_sem.c +1 -1
index 3b48061..bf0efb2 100644
@@ -58,7 +58,7 @@ struct fio_sem *fio_sem_init(int value)
 
 	sem = (void *) mmap(NULL, sizeof(struct fio_sem),
 				PROT_READ | PROT_WRITE,
-				OS_MAP_ANON | MAP_SHARED, -1, 0);
+				OS_MAP_ANON | FIO_MAP_TYPE, -1, 0);
 	if (sem == MAP_FAILED) {
 		perror("mmap semaphore");
 		return NULL;
init.c +23 -3
index af4cc6b..d69b644 100644
@@ -7,7 +7,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/ipc.h>
 #include <sys/types.h>
 #include <dlfcn.h>
 #ifdef CONFIG_VALGRIND_DEV
@@ -21,6 +20,10 @@
 #include <sys/shm.h>
 #endif
 
+#ifndef __rtems__
+#include <sys/ipc.h>
+#endif /* __rtems__ */
+
 #include "parse.h"
 #include "smalloc.h"
 #include "filehash.h"
@@ -31,7 +34,13 @@
 #include "filelock.h"
 #include "steadystate.h"
 
+/* RTEMS uses newlib's getopt_long_only_r() */
+#ifdef __rtems__
+#include <getopt.h>
+#else /* __rtems__ */
 #include "oslib/getopt.h"
+#endif /* __rtems__ */
+
 #include "oslib/strcasestr.h"
 
 #include "crc/test.h"
@@ -87,6 +96,10 @@ unsigned int *fio_warned = NULL;
 static char cmd_optstr[256];
 static bool did_arg;
 
+#ifdef __rtems__
+    struct getopt_data getopt_reent;
+#endif /* __rtems__ */
+
 #define FIO_CLIENT_FLAG		(1 << 16)
 
 /*
@@ -2435,13 +2448,20 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
 	void *cur_client = NULL;
 	int backend = 0;
 
+#ifdef __rtems__
+    memset(&getopt_reent, 0, sizeof(getopt_data));
+#endif /* __rtems__ */
 	/*
 	 * Reset optind handling, since we may call this multiple times
 	 * for the backend.
 	 */
 	optind = 1;
-
-	while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) {
+	while ((c =
+#ifdef __rtems__ /* Using Newlib's reentrant version of getopt */
+		getopt_long_only_r(argc, argv, ostr, l_opts, &lidx, &getopt_reent))!= -1) {
+#else /* __rtems__ */
+		getopt_long_only(argc, argv, ostr, l_opts, &lidx))!= -1) {
+#endif /* __rtems__ */
 		if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
 			parse_cmd_client(cur_client, argv[optind - 1]);
 			c &= ~FIO_CLIENT_FLAG;
options.c +5 -1
index a174e2c..91cb71f 100644
@@ -4744,7 +4744,7 @@ static char *bc_calc(char *str)
 	if ((!strchr(str, '+') && !strchr(str, '-') && !strchr(str, '*') &&
 	     !strchr(str, '/')) || strchr(str, '\''))
 		return str;
-
+#ifndef FIO_CONFIG_NO_MATH
 	/*
 	 * Split option from value, we only need to calculate the value
 	 */
@@ -4782,6 +4782,10 @@ static char *bc_calc(char *str)
 	memcpy(buf, str, tmp - str);
 	free(str);
 	return strdup(buf);
+#else /* FIO_CONFIG_NO_MATH */
+	log_err("fio: performing math is not supported by os\n");
+	return NULL;
+#endif /* FIO_CONFIG_NO_MATH */
 }
 
 /*
os/os-rtems.h new file +74 -0

74 lines not on this page · raw message

os/os.h +9 -0
index becc410..22bbb9b 100644
@@ -23,6 +23,7 @@ enum {
 	os_windows,
 	os_android,
 	os_dragonfly,
+	os_rtems,
 
 	os_nr,
 };
@@ -36,6 +37,8 @@ typedef enum {
 #include "os-android.h"
 #elif defined(__linux__)
 #include "os-linux.h"
+#elif defined (__rtems__)
+#include "os-rtems.h"
 #elif defined(__FreeBSD__)
 #include "os-freebsd.h"
 #elif defined(__OpenBSD__)
@@ -116,6 +119,12 @@ extern int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu);
 #define ioprio_set(which, who, prioclass, prio)	(0)
 #endif
 
+#ifdef FIO_NO_SHARED_MAP
+#define FIO_MAP_TYPE MAP_PRIVATE
+#else
+#define FIO_MAP_TYPE MAP_SHARED
+#endif
+
 #ifndef FIO_HAVE_ODIRECT
 #define OS_O_DIRECT			0
 #else
os/rtems/rtems-fio-wrap.h new file +41 -0

41 lines not on this page · raw message

os/rtems/rtems-init.c new file +224 -0

224 lines not on this page · raw message

smalloc.c +13 -0
index a2ad25a..5cad99c 100644
@@ -19,7 +19,11 @@
 #define SMALLOC_BPL	(SMALLOC_BPB * SMALLOC_BPI)
 
 #define INITIAL_SIZE	16*1024*1024	/* new pool size */
+#ifndef FIO_LESS_POOLS
 #define INITIAL_POOLS	8		/* maximum number of pools to setup */
+#else
+#define INITIAL_POOLS	4
+#endif
 
 #define MAX_POOLS	16
 
@@ -175,7 +179,12 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size)
 #else
 	mmap_flags |= MAP_SHARED;
 #endif
+
+#ifdef __rtems__
+	ptr = (void*)malloc(alloc_size);
+#else
 	ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE, mmap_flags, -1, 0);
+#endif
 
 	if (ptr == MAP_FAILED)
 		goto out_fail;
@@ -193,7 +202,11 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size)
 out_fail:
 	log_err("smalloc: failed adding pool\n");
 	if (pool->map)
+#ifdef __rtems__
+		free(pool->map);
+#else /* __rtems__ */
 		munmap(pool->map, pool->mmap_size);
+#endif /* __rtems__ */
 	return false;
 }
 
stat.c +6 -0
index a308eb8..d909406 100644
@@ -38,10 +38,16 @@ void update_rusage_stat(struct thread_data *td)
 					&td->ru_end.ru_utime);
 	ts->sys_time += mtime_since_tv(&td->ru_start.ru_stime,
 					&td->ru_end.ru_stime);
+#ifndef FIO_NO_VIRTUAL_MEMORY
 	ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
 			- (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
 	ts->minf += td->ru_end.ru_minflt - td->ru_start.ru_minflt;
 	ts->majf += td->ru_end.ru_majflt - td->ru_start.ru_majflt;
+#else /* FIO_NO_VIRTUAL_MEMORY */
+	ts->ctx  = ((uint64_t) -1);
+	ts->minf = ((uint64_t) -1);
+	ts->majf = ((uint64_t) -1);
+#endif /* FIO_NO_VIRTUAL_MEMORY */
 
 	memcpy(&td->ru_start, &td->ru_end, sizeof(td->ru_end));
 }
Signature · 1 line
1.9.1
#7 lore raw
Quoted 8 lines · On 7/30/18 4:52 AM, [email protected] wrote:
README +0 -0
index 38022bb..cbca933 100644
@@ -192,6 +192,35 @@ https://github.com/mintty/mintty/issues/56 and
 https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs
 for details).
 

README https://github.com/mintty/mintty/issues/56 and · line 204

Quoted 10 lines
README +10 -0
+RTEMS
+~~~~~~~
+
+For RTEMS Toolchain generation::
+
+Toolchain, required for cross-compiling fio for desired architecture
+(like arm in this example) can be generated by using RTEMS Source Builder(RSB).
+
+Please note that fio's build for RTEMS has been tested with RSB version 5(commit id:
+25f4db09c85a52fb1640a29f9bdc2de8c2768988), and it may not work with older versions.

Please break these at 80 chars, like the rest of the file.

client.c static void fio_client_remove_hash(struct fio_client *client) · line 91

Quoted 12 lines
client.c +1 -1
index 2a86ea9..356f9c0 100644
@@ -86,7 +86,7 @@ static void fio_client_remove_hash(struct fio_client *client)
 		flist_del_init(&client->hash_list);
 }
 
-static void fio_init fio_client_hash_init(void)
+void fio_init fio_client_hash_init(void)
 {
 	int i;

So an idea for these, since I think the manual init calls end up being very fragile. The problem is that the two are very far from each other. Why not require that all fio_init users also call fio_register_init_func() or something like that. On non-rtems, it would do nothing. On rtems, it'd register this function as a constructor and you could have an OS init func similarly to how we have an arch init. Destructors could be handled the same.

If we do it that way, you don't have a separate table somewhere for init functions. Nobody that adds a new init func will realize they need to update rtems, and they should not have to.

Quoted 5 lines
crc/xxhash.h +0 -0
index 8850d20..9019089 100644

crc/xxhash.h XXH32() : · line 114

Quoted 10 lines
crc/xxhash.h +2 -2
@@ -107,9 +107,9 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 
-void*         XXH32_init   (unsigned int seed);
+void*         XXH32_init   (uint32_t seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
-unsigned int  XXH32_digest (void* state);
+uint32_t  XXH32_digest (void* state);
 
 /*

You still haven't explained why you are making this change? If it's required, it should be a separate patch, it really has nothing to do with your port.

Quoted 27 lines
init.c +4 -1
index af4cc6b..d69b644 100644
@@ -7,7 +7,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/ipc.h>
 #include <sys/types.h>
 #include <dlfcn.h>
 #ifdef CONFIG_VALGRIND_DEV
@@ -21,6 +20,10 @@
 #include <sys/shm.h>
 #endif
 
+#ifndef __rtems__
+#include <sys/ipc.h>
+#endif /* __rtems__ */
+
 #include "parse.h"
 #include "smalloc.h"
 #include "filehash.h"
@@ -31,7 +34,13 @@
 #include "filelock.h"
 #include "steadystate.h"
 

init.c line 46

Quoted 10 lines
init.c +6 -0
+/* RTEMS uses newlib's getopt_long_only_r() */
+#ifdef __rtems__
+#include <getopt.h>
+#else /* __rtems__ */
 #include "oslib/getopt.h"
+#endif /* __rtems__ */
+
 #include "oslib/strcasestr.h"
 
 #include "crc/test.h"

This, and the above, should not be in the init.c function. See email on your first patch for clarification.

Quoted 24 lines
init.c +7 -1
@@ -87,6 +96,10 @@ unsigned int *fio_warned = NULL;
 static char cmd_optstr[256];
 static bool did_arg;
 
+#ifdef __rtems__
+    struct getopt_data getopt_reent;
+#endif /* __rtems__ */
+
 #define FIO_CLIENT_FLAG		(1 << 16)
 
 /*
@@ -2435,13 +2448,20 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
 	void *cur_client = NULL;
 	int backend = 0;
 
+#ifdef __rtems__
+    memset(&getopt_reent, 0, sizeof(getopt_data));
+#endif /* __rtems__ */
 	/*
 	 * Reset optind handling, since we may call this multiple times
 	 * for the backend.
 	 */
 	optind = 1;
-

init.c int parse_cmd_line(int argc, char *argv[], int client_type) · line 2467

Quoted 10 lines
init.c +6 -1
-	while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) != -1) {
+	while ((c =
+#ifdef __rtems__ /* Using Newlib's reentrant version of getopt */
+		getopt_long_only_r(argc, argv, ostr, l_opts, &lidx, &getopt_reent))!= -1) {
+#else /* __rtems__ */
+		getopt_long_only(argc, argv, ostr, l_opts, &lidx))!= -1) {
+#endif /* __rtems__ */
 		if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
 			parse_cmd_client(cur_client, argv[optind - 1]);
 			c &= ~FIO_CLIENT_FLAG;

Ditto for all of this. If you need to add ifdef rtems, then you are doing it wrong. Fio supports lots of OS and archs, think about why the code isn't already littered with ifdef this or that. If we had done it that way, it would be a fragile unmaintaineable mess by now.

os/os.h enum { · line 29

Quoted 12 lines
os/os.h +1 -0
index becc410..22bbb9b 100644
@@ -23,6 +23,7 @@ enum {
 	os_windows,
 	os_android,
 	os_dragonfly,
+	os_rtems,
 
 	os_nr,
 };

You need to update libfio.c:fio_os_strings[] as well.

Quoted 27 lines
os/rtems/rtems-fio-wrap.h new file +21 -0
new file mode 100644
index 0000000..54397c9
@@ -0,0 +1,41 @@
+#ifndef RTEMS_FIO_WRAP
+#define RTEMS_FIO_WRAP
+/* RTEMS specific wrapper for explicitly calling constructors and
+ * destructors */
+
+void fio_syncio_register(void);
+void fio_filecreate_register(void);
+void fio_null_register(void);
+void fio_syncio_unregister(void);
+void fio_filecreate_unregister(void);
+void fio_null_unregister(void);
+
+static int
+mainwrapper(int argc, char *argv[])
+{
+	int err=0;
+
+	/* Constructors */
+	fio_syncio_register();
+	fio_filecreate_register();
+	fio_null_register();

os/rtems/rtems-fio-wrap.h line 31

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+
+	err = main(argc, argv, NULL);
+
+	/* Destructors */
+	fio_syncio_unregister();
+	fio_filecreate_unregister();
+	fio_null_unregister();
+
+	return err;
+}

This seems totally random, just doing select init functions. This should also not be a main wrapper, please look into doing the init/destructor type setup I mentioned earlier.

Quoted 15 lines
os/rtems/rtems-init.c new file +10 -0
new file mode 100644
index 0000000..2cce2bb
+void
+Init(rtems_task_argument arg)
+{
+	rtems_status_code sc;
+
+	puts("\n*** FIO - Flexible I/O tester ***\n\n");
+
+	early_initialization();
+	rtems_bsd_initialize();
+

os/rtems/rtems-init.c line 131

Quoted 10 lines
os/rtems/rtems-init.c new file +10 -0
+	/* Let the callout timer allocate its resources */
+	sc = rtems_task_wake_after(2);
+	assert(sc == RTEMS_SUCCESSFUL);
+
+	sc = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME,
+		false, true, NULL);
+	assert(sc == RTEMS_SUCCESSFUL);
+
+	assert(0);
+}

assert(0)? Also, don't add your own header with puts. A port should be a straight port, nothing should change in output or otherwise.

smalloc.c line 26

Quoted 13 lines
smalloc.c +4 -0
index a2ad25a..5cad99c 100644
@@ -19,7 +19,11 @@
 #define SMALLOC_BPL	(SMALLOC_BPB * SMALLOC_BPI)
 
 #define INITIAL_SIZE	16*1024*1024	/* new pool size */
+#ifndef FIO_LESS_POOLS
 #define INITIAL_POOLS	8		/* maximum number of pools to setup */
+#else
+#define INITIAL_POOLS	4
+#endif

Why?

smalloc.c static bool add_pool(struct pool *pool, unsigned int alloc_size) · line 187

Quoted 10 lines
smalloc.c +5 -0
@@ -175,7 +179,12 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size)
 #else
 	mmap_flags |= MAP_SHARED;
 #endif
+
+#ifdef __rtems__
+	ptr = (void*)malloc(alloc_size);
+#else
 	ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE, mmap_flags, -1, 0);
+#endif

This needs a comment.

Quoted 8 lines
stat.c +0 -0
index a308eb8..d909406 100644
@@ -38,10 +38,16 @@ void update_rusage_stat(struct thread_data *td)
 					&td->ru_end.ru_utime);
 	ts->sys_time += mtime_since_tv(&td->ru_start.ru_stime,
 					&td->ru_end.ru_stime);

stat.c void update_rusage_stat(struct thread_data *td) · line 50

Quoted 10 lines
stat.c +6 -0
+#ifndef FIO_NO_VIRTUAL_MEMORY
 	ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
 			- (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
 	ts->minf += td->ru_end.ru_minflt - td->ru_start.ru_minflt;
 	ts->majf += td->ru_end.ru_majflt - td->ru_start.ru_majflt;
+#else /* FIO_NO_VIRTUAL_MEMORY */
+	ts->ctx  = ((uint64_t) -1);
+	ts->minf = ((uint64_t) -1);
+	ts->majf = ((uint64_t) -1);
+#endif /* FIO_NO_VIRTUAL_MEMORY */

Probably better to just set these to 0.

Signature · 1 line
Jens Axboe
#8 lore raw
Quoted 50 lines · Jens Axboe

README https://github.com/mintty/mintty/issues/56 and · line 192

Quoted 6 lines · On 7/30/18 4:52 AM, [email protected] wrote:
README +0 -0
index 38022bb..cbca933 100644
@@ -192,6 +192,35 @@ https://github.com/mintty/mintty/issues/56 and
 https://github.com/mintty/mintty/wiki/Tips#inputoutput-

interaction-with-alien-programs

README https://github.com/mintty/mintty/issues/56 and

Quoted 9 lines
README +7 -0
 for details).
 
+RTEMS
+~~~~~~~
+
+For RTEMS Toolchain generation::
+
+Toolchain, required for cross-compiling fio for desired architecture
+(like arm in this example) can be generated by using RTEMS Source

Builder(RSB).

README https://github.com/mintty/mintty/issues/56 and · line 203

Quoted 2 lines
README +2 -0
+
+Please note that fio's build for RTEMS has been tested with RSB version

5(commit id:

README https://github.com/mintty/mintty/issues/56 and · line 204

Quoted 1 line
README +1 -0
+25f4db09c85a52fb1640a29f9bdc2de8c2768988), and it may not work with

older versions.

Please break these at 80 chars, like the rest of the file.

Noted.

client.c static void fio_client_remove_hash(struct fio_client

Quoted 5 lines
client.c +0 -0
index 2a86ea9..356f9c0 100644
@@ -86,7 +86,7 @@ static void fio_client_remove_hash(struct fio_client

*client)

client.c static void fio_client_remove_hash(struct fio_client *client) · line 91

Quoted 7 lines
client.c +1 -1
              flist_del_init(&client->hash_list);
 }
 
-static void fio_init fio_client_hash_init(void)
+void fio_init fio_client_hash_init(void)
 {
      int i;

So an idea for these, since I think the manual init calls end up being very fragile. The problem is that the two are very far from each other. Why not require that all fio_init users also call fio_register_init_func() or something like that. On non-rtems, it would do nothing. On rtems, it'd register this function as a constructor and you could have an OS init func similarly to how we have an arch init. Destructors could be handled the same.

Quoted 5 lines

If we do it that way, you don't have a separate table somewhere for init functions. Nobody that adds a new init func will realize they need to update rtems, and they should not have to.

Yes. that sounds to be a good,cleaner approach. So, let me just check if

I understood it correctly:
We can have a fio_init_register_func() right in the beginning of main() which
on RTEMS will initialize all the ioengines (just like arch_init) and a fio_exit_register_func()
at the end of main() which will call all destructors. and the most appropriate place
for the definitions of these function would be, init.c?

Quoted 14 lines
crc/xxhash.h +0 -0
Quoted 13 lines

index 8850d20..9019089 100644

crc/xxhash.h +2 -2
@@ -107,9 +107,9 @@ XXH32() :
 // Advanced Hash Functions
 //****************************
 
-void*         XXH32_init   (unsigned int seed);
+void*         XXH32_init   (uint32_t seed);
 XXH_errorcode XXH32_update (void* state, const void* input, int len);
-unsigned int  XXH32_digest (void* state);
+uint32_t  XXH32_digest (void* state);
 
Quoted 6 lines

crc/xxhash.h XXH32() : · line 114

Quoted 1 line
crc/xxhash.h +0 -0
 /*

You still haven't explained why you are making this change? If it's required, it should be a separate patch, it really has nothing to do with your port.

during the declaration of, let's say XXH32_init(here
<https://github.com/axboe/fio/blob/master/crc/xxhash.h#L110>) parameter type is
'unsigned int' while during the definition(here
<https://github.com/axboe/fio/blob/master/crc/xxhash.c#L277>) it is 'uint32_t'. Now, on
most desktop os, they are are usually same, however on some embedded platforms, for example RTEMS which uses newlib as it's standard c library, they both are different(source file: here
<https://chromium.googlesource.com/native_client/nacl-newlib/+/a9ae3c60b36dea3d8a10e18b1b6db952d21268c2/newlib/libc/include/sys/types.h#27>
).

Yes, i can quickly submit a separate patch for this.

Quoted 85 lines
Quoted 28 lines
init.c +4 -1
index af4cc6b..d69b644 100644
@@ -7,7 +7,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/ipc.h>
 #include <sys/types.h>
 #include <dlfcn.h>
 #ifdef CONFIG_VALGRIND_DEV
@@ -21,6 +20,10 @@
 #include <sys/shm.h>
 #endif
 
+#ifndef __rtems__
+#include <sys/ipc.h>
+#endif /* __rtems__ */
+
 #include "parse.h"
 #include "smalloc.h"
 #include "filehash.h"
@@ -31,7 +34,13 @@
 #include "filelock.h"
 #include "steadystate.h"
 

init.c line 46

Quoted 10 lines
init.c +6 -0
+/* RTEMS uses newlib's getopt_long_only_r() */
+#ifdef __rtems__
+#include <getopt.h>
+#else /* __rtems__ */
 #include "oslib/getopt.h"
+#endif /* __rtems__ */
+
 #include "oslib/strcasestr.h"
 
 #include "crc/test.h"

This, and the above, should not be in the init.c function. See email on your first patch for clarification.

init.c int parse_cmd_line(int argc, char *argv[], int

Quoted 12 lines
init.c +4 -0
@@ -87,6 +96,10 @@ unsigned int *fio_warned = NULL;
 static char cmd_optstr[256];
 static bool did_arg;
 
+#ifdef __rtems__
+    struct getopt_data getopt_reent;
+#endif /* __rtems__ */
+
 #define FIO_CLIENT_FLAG              (1 << 16)
 
 /*
@@ -2435,13 +2448,20 @@ int parse_cmd_line(int argc, char *argv[], int

client_type)

init.c int parse_cmd_line(int argc, char *argv[], int client_type)

Quoted 13 lines
init.c +3 -2
      void *cur_client = NULL;
      int backend = 0;
 
+#ifdef __rtems__
+    memset(&getopt_reent, 0, sizeof(getopt_data));
+#endif /* __rtems__ */
      /*
       * Reset optind handling, since we may call this multiple times
       * for the backend.
       */
      optind = 1;
-
-     while ((c = getopt_long_only(argc, argv, ostr, l_opts, &lidx)) !=

-1) {

init.c int parse_cmd_line(int argc, char *argv[], int client_type)

Quoted 3 lines
init.c +3 -0
+     while ((c =
+#ifdef __rtems__ /* Using Newlib's reentrant version of getopt */
+             getopt_long_only_r(argc, argv, ostr, l_opts, &lidx,

&getopt_reent))!= -1) {

init.c int parse_cmd_line(int argc, char *argv[], int client_type) · line 2467

Quoted 6 lines
init.c +3 -0
+#else /* __rtems__ */
+             getopt_long_only(argc, argv, ostr, l_opts, &lidx))!= -1) {
+#endif /* __rtems__ */
              if ((c & FIO_CLIENT_FLAG) || client_flag_set(c)) {
                      parse_cmd_client(cur_client, argv[optind - 1]);
                      c &= ~FIO_CLIENT_FLAG;

Ditto for all of this. If you need to add ifdef rtems, then you are doing it wrong. Fio supports lots of OS and archs, think about why the code isn't already littered with ifdef this or that. If we had done it that way, it would be a fragile unmaintaineable mess by now.

Quoted 1 line

True, i'll further try to rectify this. Main issue i faced here was that

newlib supports
both getopt_long_only and getopt_long_only_r and we need to use the later one(since
it doesn't use global variables to pass info). I'll see if with some way around i can remove
that ifndef too.

Quoted 88 lines

os/os.h enum { · line 29

Quoted 12 lines
os/os.h +1 -0
index becc410..22bbb9b 100644
@@ -23,6 +23,7 @@ enum {
      os_windows,
      os_android,
      os_dragonfly,
+     os_rtems,
 
      os_nr,
 };

You need to update libfio.c:fio_os_strings[] as well.

Ok.

Quoted 27 lines
os/rtems/rtems-fio-wrap.h new file +21 -0
new file mode 100644
index 0000000..54397c9
@@ -0,0 +1,41 @@
+#ifndef RTEMS_FIO_WRAP
+#define RTEMS_FIO_WRAP
+/* RTEMS specific wrapper for explicitly calling constructors and
+ * destructors */
+
+void fio_syncio_register(void);
+void fio_filecreate_register(void);
+void fio_null_register(void);
+void fio_syncio_unregister(void);
+void fio_filecreate_unregister(void);
+void fio_null_unregister(void);
+
+static int
+mainwrapper(int argc, char *argv[])
+{
+     int err=0;
+
+     /* Constructors */
+     fio_syncio_register();
+     fio_filecreate_register();
+     fio_null_register();

os/rtems/rtems-fio-wrap.h line 31

Quoted 10 lines
os/rtems/rtems-fio-wrap.h new file +10 -0
+
+     err = main(argc, argv, NULL);
+
+     /* Destructors */
+     fio_syncio_unregister();
+     fio_filecreate_unregister();
+     fio_null_unregister();
+
+     return err;
+}

This seems totally random, just doing select init functions. This should also not be a main wrapper, please look into doing the init/destructor type setup I mentioned earlier.

Quoted 15 lines
os/rtems/rtems-init.c new file +10 -0
new file mode 100644
index 0000000..2cce2bb
+void
+Init(rtems_task_argument arg)
+{
+     rtems_status_code sc;
+
+     puts("\n*** FIO - Flexible I/O tester ***\n\n");
+
+     early_initialization();
+     rtems_bsd_initialize();
+

os/rtems/rtems-init.c line 131

Quoted 10 lines
os/rtems/rtems-init.c new file +10 -0
+     /* Let the callout timer allocate its resources */
+     sc = rtems_task_wake_after(2);
+     assert(sc == RTEMS_SUCCESSFUL);
+
+     sc = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME,
+             false, true, NULL);
+     assert(sc == RTEMS_SUCCESSFUL);
+
+     assert(0);
+}

assert(0)? Also, don't add your own header with puts. A port should be a straight port, nothing should change in output or otherwise.

Quoted 1 line

Actually, the rtems-init.c file is the configuration file for the RTOS and

this header will
appear during the boot-up.
Here's how fio is interfaced with RTEMS:
- After cross-compiling the fio sources with RTEMS toolchain, user will have to directly
load the generated fio binary using an appropriate bootloader(like
u-boot) on the target(like on beaglebone black).
- Then, RTEMS will bootup and the application specific header will appear(the one i have put above).
- RTEMS shell is then invoked (rtems_shell_init()), and user can enter the job config file and then invoke fio.
- In any case, rtems_shell_init() should not exit, and if it does we have assert(0) which will immediately stop the kernel.

Quoted 11 lines

smalloc.c line 23

Quoted 10 lines
smalloc.c +1 -0
index a2ad25a..5cad99c 100644
@@ -19,7 +19,11 @@
 #define SMALLOC_BPL  (SMALLOC_BPB * SMALLOC_BPI)
 
 #define INITIAL_SIZE 16*1024*1024    /* new pool size */
+#ifndef FIO_LESS_POOLS
 #define INITIAL_POOLS        8               /* maximum number of pools

to setup */

Quoted 7 lines

smalloc.c line 26

Quoted 3 lines
smalloc.c +3 -0
+#else
+#define INITIAL_POOLS        4
+#endif

Why?

Maybe because, sometimes, on low memory targets we just don't have enough

space to
allocate 8 pools of 16MB each. I understand the drawback of this setting(upper limit on the
number of jobs, like in my case it's 5 ) but probably i can live with that(until it doesn't start
influencing the statistics i want).

Quoted 11 lines
crc/xxhash.h +0 -0
@@ -175,7 +179,12 @@ static bool add_pool(struct pool *pool, unsigned int
 alloc_size)

smalloc.c static bool add_pool(struct pool *pool, unsigned int alloc_size)

Quoted 8 lines
smalloc.c +4 -0
 #else
      mmap_flags |= MAP_SHARED;
 #endif
+
+#ifdef __rtems__
+     ptr = (void*)malloc(alloc_size);
+#else
      ptr = mmap(NULL, alloc_size, PROT_READ|PROT_WRITE, mmap_flags, -1,

0);

Quoted 4 lines
Quoted 1 line

+#endif

This needs a comment.

I don't have a really good reason for doing this, but it's just that RTEMS mmap() implementation
is a bit buggy. sometimes, when asked to allocate a larger memory size it just silently fails. So,
instead, i though of using malloc() for better stability. Moreover, it doesn't support shared mapping too.

Quoted 27 lines
Quoted 8 lines
stat.c +0 -0
index a308eb8..d909406 100644
@@ -38,10 +38,16 @@ void update_rusage_stat(struct thread_data *td)
                                      &td->ru_end.ru_utime);
      ts->sys_time += mtime_since_tv(&td->ru_start.ru_stime,
                                      &td->ru_end.ru_stime);

stat.c void update_rusage_stat(struct thread_data *td) · line 50

Quoted 10 lines
stat.c +6 -0
+#ifndef FIO_NO_VIRTUAL_MEMORY
      ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
                      - (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
      ts->minf += td->ru_end.ru_minflt - td->ru_start.ru_minflt;
      ts->majf += td->ru_end.ru_majflt - td->ru_start.ru_majflt;
+#else /* FIO_NO_VIRTUAL_MEMORY */
+     ts->ctx  = ((uint64_t) -1);
+     ts->minf = ((uint64_t) -1);
+     ts->majf = ((uint64_t) -1);
+#endif /* FIO_NO_VIRTUAL_MEMORY */

Probably better to just set these to 0.

Ok

--
Jens Axboe

Signature · 3 lines
Regards,
Udit kumar agarwal
http://uditagarwal.in/