Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-async-module
Commits
e932e9fd
Commit
e932e9fd
authored
Mar 26, 2016
by
Michael Quigley
Browse files
Added code for timing Async IPC.
parent
8b94fe30
Changes
10
Hide whitespace changes
Inline
Side-by-side
configure.ac
View file @
e932e9fd
...
...
@@ -115,6 +115,7 @@ AC_CONFIG_FILES(
src/tests/dispatch/Kbuild
src/tests/ctx-switch/Kbuild
src/tests/async-msg-benchmarks/Kbuild
)
AC_OUTPUT
src/common/thc.c
View file @
e932e9fd
...
...
@@ -559,7 +559,7 @@ static void thc_end_rts(void) {
// number of stacks on our free list should equal the number
// allocated from the OS.
while
(
pts
->
free_stacks
!=
NULL
)
{
pts
->
free_stacks
=
pts
->
free_stacks
->
next
;
pts
->
free_stacks
=
pts
->
free_stacks
->
next
;
#ifndef NDEBUG
pts
->
stackMemoriesDeallocated
++
;
#endif
...
...
src/tests/Kbuild.in
View file @
e932e9fd
...
...
@@ -2,3 +2,5 @@
obj-m += simple/
obj-m += dispatch/
obj-m += ctx-switch/
obj-m += async-msg-benchmarks/
src/tests/Makefile.am
View file @
e932e9fd
...
...
@@ -4,3 +4,4 @@ install-tests:
cp
$(LIBASYNC_TESTS_KBUILD)
/simple/libasync_test_simple.ko
$(D)
cp
$(LIBASYNC_TESTS_KBUILD)
/dispatch/libfipc_test_dispatch_loop.ko
$(D)
cp
$(LIBASYNC_TESTS_KBUILD)
/ctx-switch/ctx_switch_test.ko
$(D)
cp
$(LIBASYNC_TESTS_KBUILD)
/async-msg-benchmarks/libasync_test_msgs.ko
$(D)
src/tests/async-msg-benchmarks/Kbuild.in
0 → 100644
View file @
e932e9fd
# @ASYNC_AUTOCONF_NOTICE@
# Magic line so we can do out-of-source build
src = @abs_top_srcdir@/src/tests/async-msg-benchmarks
obj-m = libasync_test_msgs.o
# Paths are relative to simple/ build dir
libasync_test_msgs-y += ../test_helpers.o main.o callee.o caller.o
# LIBASYNC_PATH and LIBFIPC_LIB are defined (and exported) in
# src/Makefile.am.
libasync_test_msgs-y += ../../$(LIBASYNC_PATH)
libasync_test_msgs-y += ../../$(LIBFIPC_LIB)
# Add -DCHECK_MESSAGES to check that message values contain what is expected
ccflags-y += $(CFLAGS) $(AM_CPPFLAGS) $(AM_CFLAGS)
src/tests/async-msg-benchmarks/callee.c
0 → 100644
View file @
e932e9fd
/*
* callee.c
*
* Code for the "callee side" of the channel
*
* Copyright: University of Utah
*/
#include <linux/kernel.h>
#include <libfipc.h>
#include "rpc.h"
#include "../test_helpers.h"
#include <thc_ipc.h>
/*
* We use "noinline" because we want the function call to actually
* happen.
*/
static
unsigned
long
noinline
null_invocation
(
void
)
{
return
9
;
}
static
unsigned
long
noinline
add_constant
(
unsigned
long
trans
)
{
return
trans
+
50
;
}
static
unsigned
long
noinline
add_nums
(
unsigned
long
trans
,
unsigned
long
res1
)
{
return
trans
+
res1
;
}
static
unsigned
long
noinline
add_3_nums
(
unsigned
long
trans
,
unsigned
long
res1
,
unsigned
long
res2
)
{
return
add_nums
(
trans
,
res1
)
+
res2
;
}
static
unsigned
long
noinline
add_4_nums
(
unsigned
long
trans
,
unsigned
long
res1
,
unsigned
long
res2
,
unsigned
long
res3
)
{
return
add_nums
(
trans
,
res1
)
+
add_nums
(
res2
,
res3
);
}
static
unsigned
long
noinline
add_5_nums
(
unsigned
long
trans
,
unsigned
long
res1
,
unsigned
long
res2
,
unsigned
long
res3
,
unsigned
long
res4
)
{
return
add_4_nums
(
trans
,
res1
,
res2
,
res3
)
+
res4
;
}
static
unsigned
long
noinline
add_6_nums
(
unsigned
long
trans
,
unsigned
long
res1
,
unsigned
long
res2
,
unsigned
long
res3
,
unsigned
long
res4
,
unsigned
long
res5
)
{
return
add_3_nums
(
trans
,
res1
,
res2
)
+
add_3_nums
(
res3
,
res4
,
res5
);
}
static
inline
int
send_response
(
struct
fipc_ring_channel
*
chnl
,
struct
fipc_message
*
recvd_msg
,
unsigned
long
val
,
enum
fn_type
type
)
{
int
ret
;
struct
fipc_message
*
response
;
/*
* Mark recvd msg slot as available
*/
ret
=
fipc_recv_msg_end
(
chnl
,
recvd_msg
);
if
(
ret
)
{
pr_err
(
"Error marking msg as recvd"
);
return
ret
;
}
/*
* Response
*/
ret
=
test_fipc_blocking_send_start
(
chnl
,
&
response
);
if
(
ret
)
{
pr_err
(
"Error getting send slot"
);
return
ret
;
}
THC_MSG_TYPE
(
response
)
=
msg_type_response
;
THC_MSG_ID
(
response
)
=
THC_MSG_ID
(
recvd_msg
);
set_fn_type
(
response
,
type
);
response
->
regs
[
0
]
=
val
;
ret
=
fipc_send_msg_end
(
chnl
,
response
);
if
(
ret
)
{
pr_err
(
"Error marking message as sent"
);
return
ret
;
}
return
0
;
}
int
callee
(
void
*
_callee_channel_header
)
{
int
ret
=
0
;
unsigned
long
temp_res
;
struct
fipc_ring_channel
*
chan
=
_callee_channel_header
;
struct
fipc_message
*
recvd_msg
;
unsigned
long
transaction_id
=
0
;
enum
fn_type
type
;
for
(
transaction_id
=
0
;
transaction_id
<
TRANSACTIONS
;
transaction_id
++
)
{
/*
* Try to receive a message
*/
ret
=
test_fipc_blocking_recv_start
(
chan
,
&
recvd_msg
);
if
(
ret
)
{
pr_err
(
"Error receiving message, ret = %d, exiting..."
,
ret
);
goto
out
;
}
/*
* Dispatch on message type
*/
type
=
get_fn_type
(
recvd_msg
);
switch
(
type
)
{
case
NULL_INVOCATION
:
temp_res
=
null_invocation
();
break
;
case
ADD_CONSTANT
:
temp_res
=
add_constant
(
fipc_get_reg0
(
recvd_msg
));
break
;
case
ADD_NUMS
:
temp_res
=
add_nums
(
fipc_get_reg0
(
recvd_msg
),
fipc_get_reg1
(
recvd_msg
));
break
;
case
ADD_3_NUMS
:
temp_res
=
add_3_nums
(
fipc_get_reg0
(
recvd_msg
),
fipc_get_reg1
(
recvd_msg
),
fipc_get_reg2
(
recvd_msg
));
break
;
case
ADD_4_NUMS
:
temp_res
=
add_4_nums
(
fipc_get_reg0
(
recvd_msg
),
fipc_get_reg1
(
recvd_msg
),
fipc_get_reg2
(
recvd_msg
),
fipc_get_reg3
(
recvd_msg
));
break
;
case
ADD_5_NUMS
:
temp_res
=
add_5_nums
(
fipc_get_reg0
(
recvd_msg
),
fipc_get_reg1
(
recvd_msg
),
fipc_get_reg2
(
recvd_msg
),
fipc_get_reg3
(
recvd_msg
),
fipc_get_reg4
(
recvd_msg
));
break
;
case
ADD_6_NUMS
:
temp_res
=
add_6_nums
(
fipc_get_reg0
(
recvd_msg
),
fipc_get_reg1
(
recvd_msg
),
fipc_get_reg2
(
recvd_msg
),
fipc_get_reg3
(
recvd_msg
),
fipc_get_reg4
(
recvd_msg
),
fipc_get_reg5
(
recvd_msg
));
break
;
default:
pr_err
(
"Bad function type %d, exiting...
\n
"
,
type
);
ret
=
-
EINVAL
;
goto
out
;
}
/*
* Send response back
*/
ret
=
send_response
(
chan
,
recvd_msg
,
temp_res
,
type
);
if
(
ret
)
{
pr_err
(
"Error sending response back, ret = %d, exiting..."
,
ret
);
goto
out
;
}
}
out:
return
ret
;
}
src/tests/async-msg-benchmarks/caller.c
0 → 100644
View file @
e932e9fd
/*
* caller.c
*
* The "caller side" of the channel
*
* Copyright: University of Utah
*/
#include <linux/random.h>
#include "rpc.h"
#include <thc_ipc.h>
#include <thc.h>
#include <thcinternal.h>
#include <awe_mapper.h>
#include "../test_helpers.h"
static
unsigned
long
msg_times
[
TRANSACTIONS
];
static
inline
int
send_and_get_response
(
struct
fipc_ring_channel
*
chan
,
struct
fipc_message
*
request
,
struct
fipc_message
**
response
,
uint32_t
msg_id
)
{
int
ret
;
struct
fipc_message
*
resp
;
/*
* Mark the request as sent
*/
ret
=
fipc_send_msg_end
(
chan
,
request
);
if
(
ret
)
{
pr_err
(
"failed to mark request as sent, ret = %d
\n
"
,
ret
);
goto
fail1
;
}
/*
* Try to get the response
*/
ret
=
thc_ipc_recv
(
chan
,
msg_id
,
&
resp
);
if
(
ret
)
{
pr_err
(
"failed to get a response, ret = %d
\n
"
,
ret
);
goto
fail2
;
}
*
response
=
resp
;
ret
=
fipc_recv_msg_end
(
chan
,
resp
);
if
(
ret
)
{
pr_err
(
"Error finishing receipt of response, ret = %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
fail2:
fail1:
return
ret
;
}
static
inline
int
finish_response_check_fn_type
(
struct
fipc_ring_channel
*
chnl
,
struct
fipc_message
*
response
,
enum
fn_type
expected_type
)
{
int
ret
;
enum
fn_type
actual_type
=
get_fn_type
(
response
);
ret
=
fipc_recv_msg_end
(
chnl
,
response
);
if
(
ret
)
{
pr_err
(
"Error finishing receipt of response, ret = %d
\n
"
,
ret
);
return
ret
;
}
else
if
(
actual_type
!=
expected_type
)
{
pr_err
(
"Unexpected fn type: actual = %d, expected = %d
\n
"
,
actual_type
,
expected_type
);
return
-
EINVAL
;
}
else
{
return
0
;
}
}
static
inline
int
finish_response_check_fn_type_and_reg0
(
struct
fipc_ring_channel
*
chnl
,
struct
fipc_message
*
response
,
enum
fn_type
expected_type
,
unsigned
long
expected_reg0
)
{
int
ret
;
enum
fn_type
actual_type
=
get_fn_type
(
response
);
unsigned
long
actual_reg0
=
fipc_get_reg0
(
response
);
if
(
actual_type
!=
expected_type
)
{
pr_err
(
"Unexpected fn type: actual = %d, expected = %d
\n
"
,
actual_type
,
expected_type
);
return
-
EINVAL
;
}
else
if
(
actual_reg0
!=
expected_reg0
)
{
pr_err
(
"Unexpected return value (reg0): actual = 0x%lx, expected = 0x%lx
\n
"
,
actual_reg0
,
expected_reg0
);
return
-
EINVAL
;
}
else
{
return
0
;
}
}
static
int
noinline
__used
async_add_nums
(
struct
fipc_ring_channel
*
chan
,
unsigned
long
trans
,
unsigned
long
res1
)
{
struct
fipc_message
*
request
;
struct
fipc_message
*
response
;
unsigned
long
start_time
,
stop_time
;
uint32_t
msg_id
;
int
ret
;
/*
* Set up request
*/
start_time
=
test_fipc_start_stopwatch
();
ret
=
test_fipc_blocking_send_start
(
chan
,
&
request
);
if
(
ret
)
{
pr_err
(
"Error getting send message, ret = %d
\n
"
,
ret
);
goto
fail
;
}
msg_id
=
awe_mapper_create_id
();
THC_MSG_TYPE
(
request
)
=
msg_type_request
;
THC_MSG_ID
(
request
)
=
msg_id
;
set_fn_type
(
request
,
ADD_NUMS
);
fipc_set_reg0
(
request
,
trans
);
fipc_set_reg1
(
request
,
res1
);
/*
* Send request, and get response
*/
ret
=
send_and_get_response
(
chan
,
request
,
&
response
,
msg_id
);
stop_time
=
test_fipc_stop_stopwatch
();
msg_times
[
trans
]
=
stop_time
-
start_time
;
if
(
ret
)
{
pr_err
(
"Error getting response, ret = %d
\n
"
,
ret
);
goto
fail
;
}
/*
* Maybe check message
*/
return
finish_response_check_fn_type_and_reg0
(
chan
,
response
,
ADD_NUMS
,
trans
+
res1
);
fail:
return
ret
;
}
int
caller
(
void
*
_caller_channel_header
)
{
struct
fipc_ring_channel
*
chan
=
_caller_channel_header
;
unsigned
long
transaction_id
=
0
;
int
ret
=
0
;
thc_init
();
preempt_disable
();
local_irq_disable
();
/*
* Add nums
*/
LCD_MAIN
({
DO_FINISH
({
while
(
transaction_id
<
TRANSACTIONS
)
{
ASYNC
({
ret
=
async_add_nums
(
chan
,
transaction_id
,
1000
);
if
(
ret
)
{
pr_err
(
"error doing null invocation, ret = %d
\n
"
,
ret
);
}
});
transaction_id
++
;
}
});
});
preempt_enable
();
local_irq_enable
();
thc_done
();
pr_err
(
"Complete
\n
"
);
printk
(
KERN_ERR
"Timing results of performing %d async message transactions:
\n
"
,
TRANSACTIONS
);
test_fipc_dump_time
(
msg_times
,
TRANSACTIONS
);
return
ret
;
}
src/tests/async-msg-benchmarks/main.c
0 → 100644
View file @
e932e9fd
/*
* main.c
*
* Contains init/exit for rpc test
*/
#include <libfipc.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include "../test_helpers.h"
#include "rpc.h"
#define CALLER_CPU 1
#define CALLEE_CPU 3
#define CHANNEL_ORDER 2
/* channel is 2^CHANNEL_ORDER pages */
MODULE_LICENSE
(
"GPL"
);
static
int
setup_and_run_test
(
void
)
{
int
ret
;
struct
fipc_ring_channel
*
caller_header
,
*
callee_header
;
struct
task_struct
*
caller_thread
,
*
callee_thread
;
/*
* Initialize fipc
*/
ret
=
fipc_init
();
if
(
ret
)
{
pr_err
(
"Error init'ing libfipc, ret = %d
\n
"
,
ret
);
goto
fail0
;
}
/*
* Set up channel
*/
ret
=
test_fipc_create_channel
(
CHANNEL_ORDER
,
&
caller_header
,
&
callee_header
);
if
(
ret
)
{
pr_err
(
"Error creating channel, ret = %d
\n
"
,
ret
);
goto
fail1
;
}
/*
* Set up threads
*/
caller_thread
=
test_fipc_spawn_thread_with_channel
(
caller_header
,
caller
,
CALLER_CPU
);
if
(
!
caller_thread
)
{
pr_err
(
"Error setting up caller thread
\n
"
);
goto
fail2
;
}
callee_thread
=
test_fipc_spawn_thread_with_channel
(
callee_header
,
callee
,
CALLEE_CPU
);
if
(
!
callee_thread
)
{
pr_err
(
"Error setting up callee thread
\n
"
);
goto
fail3
;
}
/*
* Wake them up; they will run until they exit.
*/
wake_up_process
(
caller_thread
);
wake_up_process
(
callee_thread
);
msleep
(
1000
);
/*
* Wait for them to complete, so we can tear things down
*/
ret
=
test_fipc_wait_for_thread
(
caller_thread
);
if
(
ret
)
pr_err
(
"Caller returned non-zero exit status %d
\n
"
,
ret
);
ret
=
test_fipc_wait_for_thread
(
callee_thread
);
if
(
ret
)
pr_err
(
"Callee returned non-zero exit status %d
\n
"
,
ret
);
/*
* Tear things down
*/
test_fipc_free_channel
(
CHANNEL_ORDER
,
caller_header
,
callee_header
);
fipc_fini
();
return
0
;
fail3:
test_fipc_release_thread
(
caller_thread
);
fail2:
test_fipc_free_channel
(
CHANNEL_ORDER
,
caller_header
,
callee_header
);
fail1:
fipc_fini
();
fail0:
return
ret
;
}
static
int
__init
rpc_init
(
void
)
{
int
ret
=
0
;
ret
=
setup_and_run_test
();
return
ret
;
}
static
void
__exit
rpc_rmmod
(
void
)
{
return
;
}
module_init
(
rpc_init
);
module_exit
(
rpc_rmmod
);
src/tests/async-msg-benchmarks/rpc.h
0 → 100644
View file @
e932e9fd
/*
* rpc.h
*
* Internal defs
*
* Copyright: University of Utah
*/
#ifndef LIBFIPC_RPC_TEST_H
#define LIBFIPC_RPC_TEST_H
#include <libfipc.h>
enum
fn_type
{
NULL_INVOCATION
,
ADD_CONSTANT
,
ADD_NUMS
,
ADD_3_NUMS
,
ADD_4_NUMS
,
ADD_5_NUMS
,
ADD_6_NUMS
};
/* must be divisible by 6... because I call 6 functions in the callee.c */
#define TRANSACTIONS 600
/* thread main functions */
int
callee
(
void
*
_callee_channel_header
);
int
caller
(
void
*
_caller_channel_header
);
static
inline
int
get_fn_type
(
struct
fipc_message
*
msg
)
{
return
fipc_get_flags
(
msg
);
}
static
inline
void
set_fn_type
(
struct
fipc_message
*
msg
,
enum
fn_type
type
)
{
fipc_set_flags
(
msg
,
type
);
}
#endif
/* LIBFIPC_RPC_TEST_H */
src/tests/ctx-switch/main.c
View file @
e932e9fd
...
...
@@ -26,7 +26,7 @@ static unsigned long ctx_switch_measurements[NUM_SWITCH_MEASUREMENTS];
static
int
test_fn
(
void
*
data
)
{
unsigned
long
start_time
,
end_time
,
elapsed_time
;
unsigned
long
start_time
,
end_time
;
uint32_t
msg_id
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment