Merge branch 'master' into readwrite

This commit is contained in:
Marian Ohligs 2012-10-04 17:24:39 +02:00
commit a457b0fc40
10 changed files with 417 additions and 55 deletions

View file

@ -28,7 +28,7 @@
#include "tests.h"
#ifdef START_KERNEL_JACOBI
#if (defined(START_KERNEL_JACOBI) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
#define MATRIX_SIZE 256
#define MAXVALUE 1337
@ -353,14 +353,17 @@ int jacobi(void* argv)
* check the result
* X[i] have to be 1
*/
int err=0;
for(i=0; i<MATRIX_SIZE; i++) {
double diff = X[i] - 1.0;
error = fabs(diff);
if (max < error)
max = error;
if (error > 0.01)
if (error > 0.01) {
kprintf("Result is on position %d wrong (%d/10000 != 1.0, error %d/10000)\n", i, (int) (10000.0*X[i]), (int) (10000.0*error));
err = 1;
}
}
kprintf("maximal error is %d/10000\n", (int) (10000.0*max));
@ -368,7 +371,7 @@ int jacobi(void* argv)
kprintf("number of iterations: %d\n", iterations);
kprintf("Calculation time: %llu ms (%llu ticks)\n", (stop-start)/(1000ULL*get_cpu_frequency()), stop-start);
return 0;
return err;
}
#endif

View file

@ -48,7 +48,7 @@
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
#if defined(START_NETIO) && defined(CONFIG_LWIP)
#if (defined(START_NETIO) || defined(START_CHIEFTEST)) && defined(CONFIG_LWIP)
#ifdef CONFIG_ROCKCREEK
#if USE_SOCKET_BYPASSING // for socket bypassing
#include <lwip/opt.h>

View file

@ -46,7 +46,7 @@ int jacobi(void* arg);
void echo_init(void);
void netio_init(void);
#ifdef START_CONSUMER_PRODUCER
#if defined(START_CONSUMER_PRODUCER) || defined(START_CHIEFTEST)
static sem_t consuming, producing;
static mailbox_int32_t mbox;
static int val = 0;
@ -89,9 +89,28 @@ static int producer(void* arg)
return 0;
}
static int producer_consumer(void)
{
tid_t id1, id2, ret;
int result1, result2, result;
create_kernel_task(&id1, producer, NULL, NORMAL_PRIO);
create_kernel_task(&id2, consumer, NULL, NORMAL_PRIO);
ret = wait(&result);
if (ret == id1) result1 = result;
else result2 = result;
ret = wait(&result);
if (ret == id1) result1 = result;
else result2 = result;
return result1 || result2;
}
#endif
#if defined(START_FOO) || defined(START_JOIN_TEST)
#if defined(START_FOO) || defined(START_JOIN_TEST) || defined(START_CHIEFTEST)
static int foo(void* arg)
{
int i;
@ -108,7 +127,7 @@ static int foo(void* arg)
}
#endif
#ifdef START_MAIL_PING
#if (defined(START_MAIL_PING) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
static int mail_ping(void* arg) {
int i;
@ -132,7 +151,7 @@ static int mail_noise(void*arg) {
}
#endif
#ifdef START_SVM_TEST
#if (defined(START_SVM_TEST) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
/* N has to be multiple of UEs */
@ -173,6 +192,8 @@ static int svm_test(void *arg)
if (!my_ue) {
// allocate and initialize SVM region
A[0] = (int*) kmalloc(3*N*N*sizeof(int));
if (!A[0])
return 1; // Let the others hang in the barrier. People will notice that things went wrong.
memset((void*) A[0], 0x00, 3*N*N*sizeof(int));
// initialize matrices
@ -188,7 +209,7 @@ static int svm_test(void *arg)
GET_B(i,j) = i+j;
}
kputs("Start sequentiell calculation...\n");
kputs("Start sequential calculation...\n");
start = rdtsc();
start = rdtsc();
@ -203,7 +224,6 @@ static int svm_test(void *arg)
}
}
end = rdtsc();
kprintf("Calculation time (seq): %llu ms (%llu ticks)\n", (end-start)/(1000ULL*get_cpu_frequency()), end-start);
@ -222,6 +242,8 @@ static int svm_test(void *arg)
kputs("Use Strong Release consistency!\n");
A[0] = (int*) svm_malloc(3*N*N*sizeof(int), svm_flags);
if (!A[0])
return 1;
#if 1
if (!my_ue)
@ -281,9 +303,8 @@ static int svm_test(void *arg)
kputs("Check results...\n");
uint32_t err = 0; // Be paranoid for a test case. return != 0 if calculation was not correct.
if (!my_ue) {
uint32_t err = 0;
svm_invalidate();
for(i=0; (i<N) && (err < 32); i++) {
for(j=0; (j<N) && (err < 32); j++) {
@ -303,11 +324,11 @@ static int svm_test(void *arg)
svm_statistics();
return 0;
return err;
}
#endif
#ifdef START_SVM_BENCH
#if (defined(START_SVM_BENCH) || defined(START_CHIEFTEST)) && defined(CONFIG_ROCKCREEK)
static int svm_bench(void *arg)
{
volatile uint32_t* array = NULL;
@ -328,6 +349,8 @@ static int svm_bench(void *arg)
start = rdtsc();
start = rdtsc();
array = (volatile uint32_t*) svm_malloc(size, svm_flags);
if (!array)
return -1;
end = rdtsc();
if (BUILTIN_EXPECT(!array, 0)) {
@ -340,6 +363,7 @@ static int svm_bench(void *arg)
svm_barrier(svm_flags);
if (!RCCE_IAM) {
start = rdtsc();
// The pages are created by touching them for the first time.
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
array[i] = 0;
end = rdtsc();
@ -350,6 +374,9 @@ static int svm_bench(void *arg)
svm_barrier(svm_flags);
if (RCCE_IAM) {
start = rdtsc();
// Touching these pages from another core means moving them
// to another owner as well as mapping them in the other core's
// memory space.
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
array[i] = 1;
end = rdtsc();
@ -360,6 +387,8 @@ static int svm_bench(void *arg)
svm_barrier(svm_flags);
if (!RCCE_IAM) {
start = rdtsc();
// Touching the pages from the first core again only involves
// moving the pages without the need to map them again.
for(i=0; i<size/sizeof(uint32_t); i+=PAGE_SIZE/sizeof(uint32_t))
array[i] = 0;
end = rdtsc();
@ -380,9 +409,21 @@ static int svm_bench(void *arg)
return 0;
}
static int testcase_svm_bench(void)
{
if (RCCE_IAM > 1) {
int i;
for (i=0; i < 6; i++)
// Need as many barriers for the other cores as they occur in the benchmark.
svm_barrier(SVM_TYPE);
return 0;
}
return svm_bench(NULL);
}
#endif
#ifdef START_JOIN_TEST
#if defined(START_JOIN_TEST) || defined(START_CHIEFTEST)
static int join_test(void* arg)
{
tid_t id, ret;
@ -397,7 +438,7 @@ static int join_test(void* arg)
kprintf("Child %u finished: result = %d\n", id, result);
return 0;
return result != 42;
}
#endif
@ -453,6 +494,8 @@ static int measure_ctx_switch(void* arg)
for (i=0; i < REPS && stop == 0; i++) {
while(id == sid && stop == 0) {
t2 = rdtsc();
// Calling rdtsc that often it is better
// to serialize the calls in the pipeline.
cpuid(0,&a,&b,&c,&d);
}
@ -489,6 +532,99 @@ next_try:
}
#endif
#ifdef START_CHIEFTEST
struct testcase_t {
tid_t tid;
int retval;
char* userspace_argv[10];
entry_point_t kernelspace_ep;
char* testcase_name;
};
#define USERSPACE_TC(execpath, name) {0, 0, {execpath, NULL}, NULL, name}
#define KERNELSPACE_TC(execpointer, name) {0, 0, {NULL}, execpointer, name}
struct testcase_t testcases[] = {
USERSPACE_TC("/bin/jacobi", "Jacobi serial user space app"),
USERSPACE_TC("/bin/tests", "Tests user space app"),
USERSPACE_TC("/bin/hello", "Hello userspace app"),
KERNELSPACE_TC(producer_consumer, "Producer consumer kernel space test"),
KERNELSPACE_TC(join_test, "Join kernel space test"),
#ifdef CONFIG_ROCKCREEK
KERNELSPACE_TC(svm_test, "SVM Test kernel space test"),
KERNELSPACE_TC(testcase_svm_bench, "SVM Bench kernel space test"),
KERNELSPACE_TC(mail_ping, "Mail Ping kernel space test"),
// KERNELSPACE_TC(jacobi, "Jacobi kernel space test"),
KERNELSPACE_TC(netio_init, "NetIO kernel space test")
#endif
};
static int chiefmastertest(void)
{
int tests = sizeof(testcases) / sizeof(struct testcase_t);
int i;
int result;
tid_t id, ret;
struct testcase_t* current;
kprintf("Starting chief master test: %d test cases.\n", tests);
for (i = 0; i < tests; i++) {
current = &testcases[i];
#ifdef CONFIG_ROCKCREEK
RCCE_barrier(&RCCE_COMM_WORLD);
#endif
kprintf("Starting testcase: %s\n", current->testcase_name);
if (current->kernelspace_ep == NULL &&
current->userspace_argv[0] != NULL) {
create_user_task(&current->tid, current->userspace_argv[0],
current->userspace_argv);
} else if (current->kernelspace_ep != NULL &&
current->userspace_argv[0] == NULL) {
create_kernel_task(&current->tid, current->kernelspace_ep,
NULL, NORMAL_PRIO);
} else {
kprintf("Invalid test case struct #%d!\n", i);
continue;
}
do {
ret = wait(&result);
} while(ret != current->tid);
kprintf("Testcase %s returned %d %s\n", current->testcase_name, result, result ? ":(" : ":)");
current->retval = result;
}
kprintf("======================================================\n");
kprintf("Master Chief test case results:\n");
for (i = 0; i < tests; i++) {
current = &testcases[i];
kprintf("%s: ", current->testcase_name);
if (current->retval) {
pushfg(COL_RED);
kprintf("Bad :(");
} else {
pushfg(COL_GREEN);
kprintf("Pass :)");
}
popfg();
popbg();
kprintf("\n");
}
kprintf("======================================================\n");
return 0;
}
#endif // START_CHIEFTEST
int test_init(void)
{
#ifdef START_HELLO
@ -505,19 +641,23 @@ int test_init(void)
char* client_argv[] = {"/bin/client", "192.168.0.1", "6789", NULL};
#endif
#ifdef START_CHIEFTEST
create_kernel_task(NULL, chiefmastertest, NULL, NORMAL_PRIO);
#endif
#ifdef START_ECHO
echo_init();
#endif
#ifdef START_NETIO
netio_init();
#endif
#ifdef START_CONSUMER_PRODUCER
#if defined(START_CONSUMER_PRODUCER) || defined(START_CHIEFTEST)
sem_init(&producing, 1);
sem_init(&consuming, 0);
mailbox_int32_init(&mbox);
create_kernel_task(NULL, producer, NULL, NORMAL_PRIO);
create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO);
#endif
#ifdef START_CONSUMER_PRODUCER
create_kernel_task(NULL, producer_consumer, NULL, NORMAL_PRIO);
#endif
#ifdef START_MEASURE_CTX_SWITCH
create_kernel_task(NULL, measure_ctx_switch, (int)0, NORMAL_PRIO);

View file

@ -47,6 +47,8 @@
#define START_TESTS
//#define START_JACOBI
//#define START_CHIEFTEST
// does our demos require GFX support?
//#define CONFIG_GFX

View file

@ -0,0 +1,161 @@
/**
* @file benchmarks.dox
* @page benchmarks Benchmarks and Example Applications
*
*
* @section toc Table of Contents
* - @ref scc_ks
* - @ref general_ks
* - @ref general_us
*
* @section kernelspace Kernel Space Applications/Benchmarks
* Located in: `apps/`
*
* You can activate/deactivate the start of these applications after booting MetalSVM
* using the \c \#define flags in `apps/tests.h`.
* The configuration looks like (Just remove the comment prefix from the applications
* you would like to start):
* \code
...
//#define START_SVM_TEST
#define START_SVM_BENCH
//#define START_MAIL_PING
#define START_MAIL_NOISE
//#define START_KERNEL_LAPLACE
//#define START_KERNEL_JACOBI
...
* \endcode
*
* There are SCC-specific as well as generic kernel space applications and benchmarks.
* Most of these applications are located in `apps/tests.c`, unless otherwise noted:
*
* @subsection scc_ks SCC-specific
*
* - __SVM_TEST__: This application creates three matrices A, B and C in
* shared memory fields and calculates C = A * B.
*
* After calculation, it checks the result for correctness, compares execution
* time between serial calculation and shared memory parallelization and prints
* statistics about the different cores' access to shared pages.
*
* You can configure different SVM release consistency models: Set the
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
* The `GET_B(i, j)` macro can be configured to transpose the matrix rows and
* columns.
*
* - __SVM_BENCH__: A benchmark for two executing cores.
*
* At first some shared memory pages are allocated. The benchmark measures the
* time the SVM implementation needs for creating and moving these pages between
* the cores.
*
* You can configure different SVM release consistency models: Set the
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
*
* - __MAIL_PING__: MetalSVM provides a mailbox system using the iRCCE library as
* a foundation for communication between the SCC-cores. In this benchmark the
* latency of intercore-pings is measured: This involves sending a a PING-message,
* an intercore-interrupt, and waiting for the answer.
*
* - __MAIL_NOISE__: A high number of messages is sent from all cores to all cores to
* generate noise on the on-die mesh.
*
* Latency is measured, but this noise can also be used to check performance of
* other applications under influence of noise.
*
* - __KERNEL_LAPLACE__: This application iterates over a shared memory field with
* the laplace differential equation solver. Execution time will be measured.
*
* You can configure different SVM release consistency models: Set the
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
*
* Location: `apps/laplace.c`
*
* - __KERNEL_JACOBI__: A shared memory implementation of the jacobi matrix equation
* solver. This is an interesting SVM example application, because besides
* `svm_barrier()`, it also uses `svm_flush()` and `svm_invalidate()`.
*
* You can configure different SVM release consistency models: Set the
* \#define-constant `SVM_TYPE` to either `SVM_LAZYRELEASE` or `SVM_STRONG`.
*
* Location: `apps/jacobi.c`
*
* - __ECHO__: Starts a new system thread providing an echo service over network
* listening on port 7.
*
* Location: `apps/echo.c`
*
* - **NETIO**: Measures the network throughput between two cores on the on-die mesh
* for different packet sizes.
*
* This benchmark consists of 2 kernel space tasks.
*
* Task 1 is the TCP server listening on port 18767. It will be started on RCCE
* rank 2. As a reaction to commands from a client it will send/receive data and
* measure the bandwidth of the transmission.
*
* Task 2 is the TCP client started on RCCE rank 0. It connects to the server task
* and sends commands to send/receive data, doing the same performance measurements
* as the server task.
*
* If the kernel is not configured for the SCC (`CONFIG_ROCKCREEK`), only the
* server task will be started. The client has to be started manually from elsewhere
* in this case.
*
* A possibility to improve the performance is bypassing the socket interface.
* To do this, activate the \#define constant `USE_SOCKET_BYPASSING` in the same file
* to a value != 0.
*
* Location: `apps/netio.c`
*
* @subsection general_ks Generic
*
* - __CONSUMER_PRODUCER__: A typical producer-consumer scenario testing the
* semaphore mechanism. After some cycles of producing and consuming, messages are
* sent over the mailbox interface.
*
* - __FOO__: A primitive kernel task example printing 5 kernel messages every second.
* Can be started multiple times to test the scheduler.
*
* - __JOIN_TEST__: A task starts a new child task executing the `foo`-example and
* and quits after the child task has executed using the `wait()` function.
*
* - __PI__: Serial calculation of pi.
*
* - __MEASURE_CTX_SWITCH__: Measures the pure overhead ticks of a context switch
* between 2 kernel space tasks.
*
* Both tasks continuously write the current TSC count to a shared variable until
* they are preempted and print the tick count the last context switch took.
*
*
* @section general_us Generic User Space Applications
*
* Located in: `newlib/examples/`
*
* - __MMNIF_TEST__: Starts a Server task on the first RCCE rank and
* a client task on every other rank. The clients request an example string
* to print it afterwards, while the server keeps responding with this string.
*
*
* - __hello__: Prints all environment variables and command line parameters.
* Opens a test file, writes an example string to it, reads the same string
* out again and afterwards prints the first directory entry of the `/bin`
* directory.
*
* - __jacobi__: A usual jacobi matrix solver application. Measures its execution time.
*
* - __mshell__: The M(etalsvm)shell provides basic commands to navigate through
* the file system, print out files and start applications.
*
* - __rlogind__: Started after boot by default, the rlogin daemon listens to port 4711.
*
* It pipes stdin and stdout over network, making shell access over telnet possible.
*
* - __tests__: Initiates a fork, where the child task starts an instance of the
* `hello` application with custom environment variables and command line parameters.
* The parent process waits for the child process to exit.
*
*
*/

View file

@ -16,11 +16,10 @@
*
* \verbatim$ git clone git://git.lfbs.rwth-aachen.de/metalsvm.git \endverbatim
*
* If you are asked for a password you are not authorized to clone the repository. In this case you will need to get your public SSH key authorized.
*
* @section compiling Compiling MetalSVM
*
* To compile MetalSVM, you will need a proper Makefile and configuration. To use the example files, just do the following:
* To compile MetalSVM, you will need a proper Makefile and configuration.
* To use the example files, just do the following:
*
* \verbatim
$ cd MetalSVM
@ -28,8 +27,10 @@ $ cp Makefile.example Makefile
$ (cd include/metalsvm; cp config.h.example config.h) \endverbatim
*
* The standard configuration works on usual PC hardware configurations as well as in emulators.
* There are also preconfigured example configs for the Intel SCC: `Makefile.scc` and `config.h.scc`.
*
* Compiler settings can be edited in the Makefile, while the kernel configuration can be found in the just copied configuration file.
* Compiler settings can be edited in the Makefile, while the kernel configuration can be
* found in the configuration header file.
*
* @section runqemu Running MetalSVM in Qemu
*
@ -41,19 +42,12 @@ $ (cd include/metalsvm; cp config.h.example config.h) \endverbatim
*
* @section runscc Running MetalSVM on the Intel SCC
*
* -# Intel recommends to use their cross-compiler for generating code which is guaranteed to be SCC-compatible. Just set the environment variables with the following command:
* \verbatim$ . /opt/compilerSetupFiles/crosscompile.sh \endverbatim
* -# The Makefile needs to be adapted to actually use the cross compiler.
* Just uncomment two lines like seen here:
* \code
# Set your own cross compiler tool chain prefix here
CROSSCOMPREFIX=
# Uncomment both lines if compiling for the SCC!
CROSSCOMPREFIX=i386-unknown-linux-gnu-
STACKPROT=\endcode
* -# Another important change in the Makefile is disabling the "-fno-stack-protector" option. It occurs several times.
* -# The SCC requires a special configuration for the MetalSVM kernel:
* -# Although Intel provides a special older GCC version for compiling code for the Intel SCC,
* the MetalSVM project switched to the current standard GCC. You don't need to source
* the cross compiler script which might be installed on your MCPC.
* -# An important change in the Makefile is disabling the "-fno-stack-protector" option. It occurs several times. This has already been done for you if you use `Makefile.scc`.
* -# The SCC requires a special configuration for the MetalSVM kernel (Already been done
* if you use `config.h.scc`):
* \code
//#define CONFIG_PCI
//#define CONFIG_VGA
@ -78,6 +72,7 @@ STACKPROT=\endcode
* \verbatim
$ cd tools
$ make SCC \endverbatim
*
* -# The \c obj directory was just created, containing the MetalSVM kernel image. It can be loaded into the SCC's memory using \verbatim$ sccBoot -g obj \endverbatim
* -# The default configuration lets MetalSVM run only on core 0. Its reset pin needs to be released:
* \verbatim$ sccReset -r 0x00 \endverbatim
@ -90,9 +85,10 @@ $ make SCC \endverbatim
* -# Build the kernel like described above (items 1-7) and change to the \c tools directory.
* -# Now the file \c metalsvm.mt can be edited, depending on how many cores you want MetalSVM running.
* Just remove the cores which shall be unaffected. Having a slim \c metalsvm.tm accelerates the build procedure.
* -# The final image must be generated then with \code$ make SCC\endcode
* -# The final image must be generated then with \code$ make SCC CORENUM=48\endcode
* where `CORENUM` is set to the actual number of cores which shall work together later.
* -# A directory \c obj was created, containing the final MetalSVM Image. This image can now be loaded with the following command: \code$ sccBoot -g obj\endcode
* -# Everything has been placed in the cores' memory. To release the reset pins of the corresponding cores, type \code$ sccReset -r 0x00 0x01\endcode
* -# Everything has been placed in the cores' memory. To release the reset pins of the corresponding cores, type \code$ sccReset -r 0 1 2 3 ...\endcode
*
* @section msvmuart Enabling UART support
*

View file

@ -1,12 +1,14 @@
/**
* @file config.dox
* @page config The MetalSVM feature configuration file
* @page config MetalSVM feature configuration files
*
* @section conf MetalSVM's configuration file
* @section main_config MetalSVM's main configuration file
*
* MetalSVM's configuration parameters and some features can be configured/activated in the central configuration file located at \c include/metalsvm/config.h.
* MetalSVM's configuration parameters and some features can be configured/activated
* in the central configuration file located at \c include/metalsvm/config.h.
*
* The \c config.h is a usual C-header file and the configuration items are usual C preprocessor-definitions like the following:
* The `config.h` is a usual C header file and the configuration items are usual
* C preprocessor-definitions like the following:
* \code
#define CONFIGURATION_PARAMETER 123value /* A parameter with a value */
#define FEATURE_A /* An activated feature */
@ -14,5 +16,53 @@
*
* Just like the example suggests, features are deactivated by commenting them out.
*
* If you boot MetalSVM on the Intel SCC, you need to \b deactivate `CONFIG_PCI`,
* `CONFIG_VGA`, `CONFIG_KEYBOARD`, and `CONFIG_MULTIBOOT` and
* \b activate `CONFIG_ROCKCREEK`. Set `CACHE_LINE` to 32.\n
* Activate `CONFIG_UART` if you are going to use software-UART and deactivate it if
* not, to avoid unnecessary traffic.
*
* @section lwip_config LwIP configuration flags
*
* The networking subsystem, based on LwIP, can of course be influenced by various
* feature flags.
*
* MetalSVM overrides various standard settings in `lwip/src/include/lwipopts.h`.
*
* If you chose `CONFIG_ROCKCREEK`, this leads to deactivation of `LWIP_DHCP`.
*
* If you chose `CONFIG_TICKLESS`, `NO_SYS` will be activated and the following
* are deactivated: `LWIP_SOCKET`, `LWIP_NETCON`, `LWIP_NETIF_API`.
*
* Another interesting feature is `LWIP_CHECKSUM_ON_COPY`. Deactivating it leads
* to higher network throughput for on-die communication.
*
* See LwIP documentation for more specific information about the individual effects of
* manipulating the LwIP configuration flags/values.
*
* @section mmnif_config MMNIF configuration flags
* Several flags in the file `drivers/net/mmnif.c` file influence the memory
* mapped network interface's performance:
*
* - `USE_CACHE`: activates the cache for the memory mapped buffer region.
* This improves the performance.
* - `USE_MPB`: If activated, the buffer will be mapped onto the SCC's special MPB,
* which improves the performance drastically.
*
* @section svm_config SVM configuration flags
*
* Although the choice between different shared memory release consistency models
* is configured in the application code, there are 2 flags which influence the SVM
* implementation. These are located in `arch/x86/mm/svm.c`:
*
* - `USE_PERFCOUNTERS`: Performance counters will help evaluating the performance
* of the SVM implementation within the kernel. Deactivate to omit overhead.
*
* - `USE_RESP_MAIL`: Whenever a core requests access to a page it is not the owner
* of, it sends an interrupt to the owner. The requesting core will then wait for the mail
* indicating that it has become the new owner of the particular page, spinning on its mailbox.
* When `USE_RESP_MAIL` is activated, other interrupts will be deactivated until the response
* has arrived.
*
*
*/

View file

@ -108,7 +108,7 @@ static int foo(void* arg)
* \c make in the project directory.
*
* The initrd building scripts include every file within the \c newlib/examples/
* directory which is marked as \b execuable. Do not forget this if you use your
* directory which is marked as \b executable. Do not forget this if you use your
* own build scripts!
*
* After providing your own executable for the system within the initial ramdisk,

View file

@ -29,6 +29,8 @@
#define NR_OPEN 10
#define FS_INIT { [0 ... NR_OPEN-1] = {NULL, 0, 0} }
#define TESTSTR "hello in new file '/bin/test.txt'"
int main(int argc, char** argv)
{
int i, testfile;
@ -43,25 +45,31 @@ int main(int argc, char** argv)
teststr = malloc(sizeof(char)*100);
if (!teststr)
return EFAULT;
exit(1);
testfile = open("/bin/test.txt", O_CREAT | O_EXCL, "wr");
if (testfile < 1)
printf("error");
write(testfile, "hello in new file '/bin/test.txt'", 34);
if (testfile < 1) {
printf("error: Was not able to open /bin/test.txt\n");
exit(1);
}
write(testfile, TESTSTR, 34);
lseek(testfile, 0, SEEK_SET);
read(testfile, teststr, 100);
close(testfile);
printf("read from new file: %s\n", teststr);
if (strcmp(teststr, TESTSTR))
exit(1);
testdir = opendir("/bin/");
if (testdir < 1)
printf("error");
if (testdir < 1) {
printf("error: Was not able to open /bin directory");
exit(1);
}
testdirent = readdir(testdir);
printf("1. Dirent: %s", testdirent->d_name);
closedir(testdir);
printf("read from new file: %s\n", teststr);
return errno;
}

View file

@ -178,8 +178,10 @@ int main(int argc, char **argv)
if (max < error)
max = error;
if (error > 0.01f)
printf("Result is on position %d wrong (%f != 1.0)\n", i, X[i]);
if (error > 0.01f) {
printf("Result is on position %d wrong (%f != 1.0)\n", i, X[i]);
exit(1);
}
}
printf("maximal error is %f\n", max);