Make ostest RR scheduler test use less memory from Freddie Chopin; Plus build fix from Darcy Gong

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5314 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-11-05 20:02:56 +00:00
parent 5d0999c859
commit 7961d6ce58
8 changed files with 119 additions and 100 deletions
+5
View File
@@ -407,3 +407,8 @@
and hardware address (from Darcy Gong). and hardware address (from Darcy Gong).
6.24 2012-xx-xx Gregory Nutt <gnutt@nuttx.org> 6.24 2012-xx-xx Gregory Nutt <gnutt@nuttx.org>
* apps/examples/ostest/roundrobin.c: Replace large tables with
algorithmic prime number generation. This allows the roundrobin
test to run on platforms with minimal SRAM (Freddie Chopin).
+11
View File
@@ -1087,6 +1087,17 @@ examples/ostest
Specifies the number of threads to create in the barrier Specifies the number of threads to create in the barrier
test. The default is 8 but a smaller number may be needed on test. The default is 8 but a smaller number may be needed on
systems without sufficient memory to start so many threads. systems without sufficient memory to start so many threads.
* CONFIG_EXAMPLES_OSTEST_RR_RANGE
During round-robin scheduling test two threads are created. Each of the threads
searches for prime numbers in the configurable range, doing that configurable
number of times.
This value specifies the end of search range and together with number of runs
allows to configure the length of this test - it should last at least a few
tens of seconds. Allowed values [1; 32767], default 10000
* CONFIG_EXAMPLES_OSTEST_RR_RUNS
During round-robin scheduling test two threads are created. Each of the threads
searches for prime numbers in the configurable range, doing that configurable
number of times.
examples/pashello examples/pashello
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
+1 -1
View File
@@ -117,4 +117,4 @@ $(SYMTAB_SRC): build
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean) clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp
@rm -rf $(ROMFS_DIR) @rm -rf $(ROMFS_DIR) $(DIRLIST_HDR)
+1 -1
View File
@@ -98,6 +98,6 @@ $(SYMTAB): build
clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean) clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean)
@rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB) @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB)
@rm -rf $(ROMFS_DIR) @rm -rf $(ROMFS_DIR) $(ROMFS_DIRLIST)
+29
View File
@@ -39,4 +39,33 @@ config EXAMPLES_OSTEST_NBARRIER_THREADS
is 8 but a smaller number may be needed on systems without sufficient memory is 8 but a smaller number may be needed on systems without sufficient memory
to start so many threads. to start so many threads.
config EXAMPLES_OSTEST_RR_RANGE
int "Round-robin test - end of search range"
default 10000
range 1 32767
depends on RR_INTERVAL > 0
---help---
During round-robin scheduling test two threads are created. Each of the threads
searches for prime numbers in the configurable range, doing that configurable
number of times.
This value specifies the end of search range and together with number of runs
allows to configure the length of this test - it should last at least a few
tens of seconds. Allowed values [1; 32767], default 10000
config EXAMPLES_OSTEST_RR_RUNS
int "Round-robin test - number of runs"
default 10
range 1 32767
depends on RR_INTERVAL > 0
---help---
During round-robin scheduling test two threads are created. Each of the threads
searches for prime numbers in the configurable range, doing that configurable
number of times.
This value specifies the number of times the thread searches the range for
prime numbers and together with end of search range allows to configure the
length of this test - it should last at least a few tens of seconds. Allowed
values [1; 32767], default 10
endif endif
+60 -86
View File
@@ -1,7 +1,7 @@
/******************************************************************************** /********************************************************************************
* examples/ostest/roundrobin.c * examples/ostest/roundrobin.c
* *
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "ostest.h" #include "ostest.h"
#if CONFIG_RR_INTERVAL > 0 #if CONFIG_RR_INTERVAL > 0
@@ -47,115 +48,87 @@
* Definitions * Definitions
********************************************************************************/ ********************************************************************************/
/* This number may need to be tuned for different processor speeds. Since these /* This numbers should be tuned for different processor speeds via .config file.
* arrays must be large to very correct SCHED_RR behavior, this test may require * With default values the test takes about 30s on Cortex-M3 @ 24MHz. With 32767
* too much memory on many targets. * range and 10 runs it takes ~320s. */
*/
/* #define CONFIG_NINTEGERS 32768 Takes forever on 60Mhz ARM7 */ #ifndef CONFIG_EXAMPLES_OSTEST_RR_RANGE
# define CONFIG_EXAMPLES_OSTEST_RR_RANGE 10000
# warning "CONFIG_EXAMPLES_OSTEST_RR_RANGE undefined, using default value = 10000"
#elif (CONFIG_EXAMPLES_OSTEST_RR_RANGE < 1) || (CONFIG_EXAMPLES_OSTEST_RR_RANGE > 32767)
# define CONFIG_EXAMPLES_OSTEST_RR_RANGE 10000
# warning "Invalid value of CONFIG_EXAMPLES_OSTEST_RR_RANGE, using default value = 10000"
#endif
#define CONFIG_NINTEGERS 2048 #ifndef CONFIG_EXAMPLES_OSTEST_RR_RUNS
# define CONFIG_EXAMPLES_OSTEST_RR_RUNS 10
/******************************************************************************** # warning "CONFIG_EXAMPLES_OSTEST_RR_RUNS undefined, using default value = 10"
* Private Data #elif (CONFIG_EXAMPLES_OSTEST_RR_RUNS < 1) || (CONFIG_EXAMPLES_OSTEST_RR_RUNS > 32767)
********************************************************************************/ # define CONFIG_EXAMPLES_OSTEST_RR_RUNS 10
# warning "Invalid value of CONFIG_EXAMPLES_OSTEST_RR_RUNS, using default value = 10"
static int prime1[CONFIG_NINTEGERS]; #endif
static int prime2[CONFIG_NINTEGERS];
/******************************************************************************** /********************************************************************************
* Private Functions * Private Functions
********************************************************************************/ ********************************************************************************/
/******************************************************************************** /********************************************************************************
* Name: dosieve * Name: get_primes
* *
* Description * Description
* This implements a "sieve of aristophanes" algorithm for finding prime number. * This function searches for prime numbers in the most primitive way possible.
* Credit for this belongs to someone, but I am not sure who anymore. Anyway,
* the only purpose here is that we need some algorithm that takes a long period
* of time to execute.
*
********************************************************************************/ ********************************************************************************/
static void dosieve(int *prime) static void get_primes(int *count, int *last)
{ {
int a,d; int number;
int i; int local_count = 0;
int j; *last = 0; // to make compiler happy
a = 2; for (number = 1; number < CONFIG_EXAMPLES_OSTEST_RR_RANGE; number++)
d = a;
for (i = 0; i < CONFIG_NINTEGERS; i++)
{ {
prime[i] = i+2; int div;
bool is_prime = true;
for (div = 2; div <= number / 2; div++)
if (number % div == 0)
{
is_prime = false;
break;
} }
for (i = 1; i < 10; i++) if (is_prime)
{ {
for (j = 0; j < CONFIG_NINTEGERS; j++) local_count++;
{ *last = number;
d = a + d;
if (d < CONFIG_NINTEGERS)
{
prime[d]=0;
}
}
a++;
d = a;
i++;
}
#if 0 /* We don't really care what the numbers are */ #if 0 /* We don't really care what the numbers are */
for (i = 0, j= 0; i < CONFIG_NINTEGERS; i++) printf(" Prime %d: %d\n", local_count, number);
{
if (prime[i] != 0)
{
printf(" Prime %d: %d\n", j, prime[i]);
j++;
}
}
#endif #endif
} }
/********************************************************************************
* Name: sieve1
********************************************************************************/
static void *sieve1(void *parameter)
{
int i;
printf("sieve1 started\n");
for (i = 0; i < 1000; i++)
{
dosieve(prime1);
} }
printf("sieve1 finished\n"); *count = local_count;
pthread_exit(NULL);
return NULL; /* To keep some compilers happy */
} }
/******************************************************************************** /********************************************************************************
* Name: sieve2 * Name: get_primes_thread
********************************************************************************/ ********************************************************************************/
static void *sieve2(void *parameter) static void *get_primes_thread(void *parameter)
{ {
int i; int id = (int)parameter;
int i, count, last;
printf("sieve2 started\n"); printf("get_primes_thread id=%d started, looking for primes < %d, doing %d run(s)\n",
id, CONFIG_EXAMPLES_OSTEST_RR_RANGE, CONFIG_EXAMPLES_OSTEST_RR_RUNS);
for (i = 0; i < 1000; i++) for (i = 0; i < CONFIG_EXAMPLES_OSTEST_RR_RUNS; i++)
{ {
dosieve(prime2); get_primes(&count, &last);
} }
printf("sieve2 finished\n"); printf("get_primes_thread id=%d finished, found %d primes, last one was %d\n",
id, count, last);
pthread_exit(NULL); pthread_exit(NULL);
return NULL; /* To keep some compilers happy */ return NULL; /* To keep some compilers happy */
@@ -171,14 +144,13 @@ static void *sieve2(void *parameter)
void rr_test(void) void rr_test(void)
{ {
pthread_t sieve1_thread; pthread_t get_primes1_thread;
pthread_t sieve2_thread; pthread_t get_primes2_thread;
struct sched_param sparam; struct sched_param sparam;
pthread_attr_t attr; pthread_attr_t attr;
pthread_addr_t result; pthread_addr_t result;
int status; int status;
printf("rr_test: Starting sieve1 thread \n");
status = pthread_attr_init(&attr); status = pthread_attr_init(&attr);
if (status != OK) if (status != OK)
{ {
@@ -203,29 +175,31 @@ void rr_test(void)
} }
else else
{ {
printf("rr_test: Set thread policty to SCHED_RR\n"); printf("rr_test: Set thread policy to SCHED_RR\n");
} }
status = pthread_create(&sieve1_thread, &attr, sieve1, NULL); printf("rr_test: Starting first get_primes_thread\n");
status = pthread_create(&get_primes1_thread, &attr, get_primes_thread, (void*)1);
if (status != 0) if (status != 0)
{ {
printf("rr_test: Error in thread 1 creation, status=%d\n", status); printf("rr_test: Error in thread 1 creation, status=%d\n", status);
} }
printf("rr_test: Starting sieve1 thread \n"); printf("rr_test: Starting second get_primes_thread\n");
status = pthread_create(&sieve2_thread, &attr, sieve2, NULL); status = pthread_create(&get_primes2_thread, &attr, get_primes_thread, (void*)2);
if (status != 0) if (status != 0)
{ {
printf("rr_test: Error in thread 2 creation, status=%d\n", status); printf("rr_test: Error in thread 2 creation, status=%d\n", status);
} }
printf("rr_test: Waiting for sieves to complete -- this should take awhile\n"); printf("rr_test: Waiting for threads to complete -- this should take awhile\n");
printf("rr_test: If RR scheduling is working, they should start and complete at\n"); printf("rr_test: If RR scheduling is working, they should start and complete at\n");
printf("rr_test: about the same time\n"); printf("rr_test: about the same time\n");
pthread_join(sieve2_thread, &result); pthread_join(get_primes2_thread, &result);
pthread_join(sieve1_thread, &result); pthread_join(get_primes1_thread, &result);
printf("rr_test: Done\n"); printf("rr_test: Done\n");
} }
+6 -6
View File
@@ -39,14 +39,14 @@ include $(APPDIR)/Make.defs
# relays Example # relays Example
ASRC = ASRCS =
CSRC = relays_main.c CSRCS = relays_main.c
AOBJ = $(ASRCS:.S=$(OBJEXT)) AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJ = $(CSRCS:.c=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT))
SRC = $(ASRCS) $(CSRCS) SRCS = $(ASRCS) $(CSRCS)
OBJ = $(AOBJS) $(COBJS) OBJS = $(AOBJS) $(COBJS)
ifeq ($(WINTOOL),y) ifeq ($(WINTOOL),y)
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"