Commit 8f86e95f authored by Michael Quigley's avatar Michael Quigley
Browse files

Started skeleton for dispatch loop tests using fipc. Thread3 setup and...

Started skeleton for dispatch loop tests using fipc. Thread3 setup and finishing thread2 setup is what's left for the test.
parent 34dd651f
Subproject commit 3a029e34bcd2a4a3d46a53c176a2e7d03ed4882f
Subproject commit 2cef3d068d3ed2da556d775f8571f5c2c6b67d63
......@@ -146,7 +146,7 @@ int thc_channel_group_init(struct thc_channel_group* channel_group)
EXPORT_SYMBOL(thc_channel_group_init);
int thc_channel_group_add(struct thc_channel_group* channel_group,
int thc_channel_group_item_add(struct thc_channel_group* channel_group,
struct thc_channel_group_item* item)
{
list_add_tail(&(item->list), &(channel_group->head));
......
......@@ -20,6 +20,6 @@ int thc_poll_recv(struct thc_channel_group_item* item,
int thc_channel_group_init(struct thc_channel_group* channel_group);
int thc_channel_group_add(struct thc_channel_group* channel_group,
int thc_channel_group_item_add(struct thc_channel_group* channel_group,
struct thc_channel_group_item* item);
#endif
......@@ -3,12 +3,14 @@ KDIR = /lib/modules/`uname -r`/build
export LIB_TEST_ASYNC_DIR
module:
make -C $(KDIR) M=$(LIB_TEST_ASYNC_DIR) modules
simple:
make -C $(KDIR) M=$(LIB_TEST_ASYNC_DIR)/simple modules
clean:
sudo rm -rf *.o
sudo rm -rf *.ko
sudo rm -rf *.symvers
sudo rm -rf *.order
sudo rm -rf *.mod.c
sudo rm -rf simple/*.o
sudo rm -rf simple/*.ko
sudo rm -rf simple/*.symvers
sudo rm -rf simple/*.order
sudo rm -rf simple/*.mod.c
.PHONY: simple clean
#include <libfipc.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <thc_ipc_types.h>
#include "../../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include "rpc.h"
#include "thread_fn_util.h"
#define THREAD1_CPU 1
#define THREAD2_CPU 2
#define THREAD3_CPU 3
#define CHANNEL_ORDER 2
MODULE_LICENSE("GPL");
//channel groups for threads 2 and 3
static struct thc_channel_group group2, group3;
static struct thc_channel_group_item item2to1, item2to3, item3;
static int setup_and_run_test(void)
{
int ret;
struct fipc_ring_channel *thread1_header, *thread_2_to_1_header;
struct fipc_ring_channel *thread_2_to_3_header, *thread3_header;
struct task_struct *thread1, *thread2, *thread3;
/*
* Initialize channel groups
*/
thc_channel_group_init(&group2);
thc_channel_group_init(&group3);
item2to1.channel = thread_2_to_1_header;
thc_channel_group_item_add(&group2, &item2to1);
item2to3.channel = thread_2_to_3_header;
thc_channel_group_item_add(&group2, &item2to3);
item3.channel = thread3_header;
thc_channel_group_item_add(&group3, &item3);
/*
* Initialize fipc
*/
ret = fipc_init();
if (ret) {
pr_err("Error init'ing libfipc, ret = %d\n", ret);
goto fail0;
}
/*
* Set up channel between thread 1 and 2
*/
ret = test_fipc_create_channel(CHANNEL_ORDER, &thread1_header,
&thread_2_to_1_header);
if (ret) {
pr_err("Error creating channel, ret = %d\n", ret);
goto fail1;
}
/*
* Set up channel between thread 2 and 3
*/
ret = test_fipc_create_channel(CHANNEL_ORDER, &thread3_header,
&thread_2_to_3_header);
if (ret) {
pr_err("Error creating channel, ret = %d\n", ret);
goto failN_i;
}
/*
* Set up threads
*/
thread1 = test_fipc_spawn_thread_with_channel(thread1_header,
thread1_fn,
THREAD1_CPU);
if (!thread1) {
pr_err("Error setting up caller thread\n");
goto fail2;
}
thread2 = test_fipc_spawn_thread_with_channel(&group2,
thread2_fn,
THREAD2_CPU);
if (!thread2) {
pr_err("Error setting up thread 2\n");
goto fail3;
}
thread3 = test_fipc_spawn_thread_with_channel(&group3,
thread3_fn,
THREAD3_CPU);
if (!thread3) {
pr_err("Error setting up thread 3\n");
goto fail4;
}
/*
* Wake them up; they will run until they exit.
*/
wake_up_process(thread1);
wake_up_process(thread2);
wake_up_process(thread3);
/* wait for a second so we don't prematurely kill caller/callee */
msleep(1000);
/*
* Wait for them to complete, so we can tear things down
*/
ret = test_fipc_wait_for_thread(thread1);
if (ret)
pr_err("Caller returned non-zero exit status %d\n", ret);
ret = test_fipc_wait_for_thread(thread2);
if (ret)
pr_err("Callee returned non-zero exit status %d\n", ret);
ret = test_fipc_wait_for_thread(thread3);
if (ret)
pr_err("Callee returned non-zero exit status %d\n", ret);
/*
* Tear things down
*/
test_fipc_free_channel(CHANNEL_ORDER, thread1_header, thread_2_to_1_header);
test_fipc_free_channel(CHANNEL_ORDER, thread_2_to_3_header, thread3_header);
fipc_fini();
return 0;
fail4:
test_fipc_release_thread(thread2);
test_fipc_free_channel(CHANNEL_ORDER, thread_2_to_3_header, thread3_header);
fail3:
test_fipc_release_thread(thread1);
fail2:
test_fipc_free_channel(CHANNEL_ORDER, thread1_header, thread_2_to_1_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);
#include "thc_dispatch_test.h"
#include <thc.h>
#include <thcinternal.h>
#include <libfipc.h>
#include <awe-mapper.h>
#include <linux/types.h>
#include <thc_ipc.h>
#include "thread_fn_util.h"
//max_recv_ct just for testing
int thc_dispatch_loop_test(struct thc_channel_group* rx_group, int max_recv_ct)
{
volatile void ** frame = (volatile void**)__builtin_frame_address(0);
volatile void *ret_addr = *(frame + 1);
int recv_ct = 0;
*(frame + 1) = NULL;
//NOTE:max_recv_ct is just for testing
DO_FINISH_(ipc_dispatch,{
int curr_ind = 0;
int* curr_ind_pt = &curr_ind;
struct thc_channel_group_item* curr_item;
struct ipc_message* curr_msg;
uint32_t do_finish_awe_id = awe_mapper_create_id();
while( recv_ct < max_recv_ct )
{
curr_ind = 0;
if( !thc_poll_recv_group(rx_group, &curr_item, &curr_msg) )
{
recv_ct++;
if( curr_item->dispatch_fn )
{
ASYNC_({
curr_item->dispatch_fn(curr_item->channel, curr_msg);
},ipc_dispatch);
}
else
{
printk(KERN_ERR "Channel %d function not allocated, message dropped\n", curr_ind_pt);
}
}
}
});
*(frame + 1) = ret_addr;
return 0;
}
EXPORT_SYMBOL(ipc_dispatch_loop);
#ifndef IPC_DISPATCH_H
#define IPC_DISPATCH_H
int ipc_dispatch_loop(struct ttd_ring_channel_group* rx_group, int max_recv_ct);
static inline void ipc_dispatch_print_sp(char* time)
{
unsigned long sp;
asm volatile("mov %%rsp, %0" : "=g"(sp) : :);
printk(KERN_ERR "%s sp: %lx\n", time, sp);
}
#endif
#include <thc.h>
#include <thc_ipc.h>
#include <libfipc.h>
#include <thcinternal.h>
#include "thc_dispatch_test.h"
#include "thread_fn_util.h"
#include <awe-mapper.h>
#include <linux/delay.h>
#define BATCH_INTERVAL 100
static struct fipc_ring_channel* channel;
static unsigned long add_nums_async(unsigned long lhs, unsigned long rhs, unsigned long msg_id, int fn_type)
{
struct fipc_message *msg;
struct fipc_message *response;
unsigned long result;
if( test_ipc_blocking_send_start(channel, &msg) )
{
printk(KERN_ERR "Error getting send message for add_nums_async.\n");
}
set_fn_type(msg, fn_type);
fipc_set_reg0(lhs);
fipc_set_reg1(rhs);
THC_MSG_ID(msg) = msg_id;
THC_MSG_TYPE(msg) = msg_type_request;
send_and_get_response(channel, msg, &response);
fipc_recv_msg_end(channel, response);
result = fipc_get_reg0(response);
printk(KERN_ERR "result is %lu\n", result);
return result;
}
int thread1_fn(void* chan)
{
volatile void ** frame = (volatile void**)__builtin_frame_address(0);
volatile void *ret_addr = *(frame + 1);
int num_transactions = 0;
uint32_t id_num;
*(frame + 1) = NULL;
channel = chan;
thc_init();
DO_FINISH_(thread1_fn,{
while (num_transactions < TRANSACTIONS) {
printk(KERN_ERR "num_transactions: %d\n", num_transactions);
ASYNC(
printk(KERN_ERR "id created\n");
id_num = awe_mapper_create_id();
printk(KERN_ERR "id returned\n");
num_transactions++;
add_nums_async(num_transactions, 1,(unsigned long) id_num, ADD_2_FN);
);
if( (num_transactions) % THD3_INTERVAL == 0 )
{
ASYNC(
printk(KERN_ERR "id created\n");
id_num = awe_mapper_create_id();
printk(KERN_ERR "id returned\n");
num_transactions++;
add_nums_async(num_transactions, 2,(unsigned long) id_num, ADD_10_FN);
);
}
ASYNC(
printk(KERN_ERR "id created\n");
id_num = awe_mapper_create_id();
printk(KERN_ERR "id returned\n");
num_transactions++;
add_nums_async(num_transactions, 3,(unsigned long) id_num, ADD_2_FN);
);
//msleep(20);
}
printk(KERN_ERR "done with transactions\n");
});
printk(KERN_ERR "lcd async exiting module and deleting ptstate");
thc_done();
*(frame + 1) = ret_addr;
return 1;
}
#include <thc.h>
#include <libfipc.h>
#include <thcinternal.h>
#include "thc_dispatch_test.h"
#include "thread_fn_util.h"
#include <awe-mapper.h>
#define THREAD2_FNS_LENGTH 2
static struct thc_channel_group* rx_group;
//Just returns a value back to thread 1
static int add_2_fn(struct fipc_ring_channel* chan, struct fipc_message* msg)
{
unsigned long result = fipc_get_reg0(msg) + fipc_get_reg1(msg);
struct fipc_message* out_msg;
if( test_ipc_blocking_send_start(chan, &out_msg) )
{
printk(KERN_ERR "Error getting send message for add_2_fn.\n");
}
fipc_recv_msg_end(chan, msg);
fipc_set_reg0(out_msg,result);
set_fn_type(out_msg, ADD_2_FN);
THC_MSG_TYPE(out_msg) = msg_type_response;
THC_MSG_ID(out_msg) = THC_MSG_ID(msg);
if( fipc_send_msg_end(chan, out_msg) )
{
printk(KERN_ERR "Error sending message for add_2_fn.\n");
}
return 0;
}
//Receives a value from thread1, then passes it to thread 3 and returns that result to thread 1
static int add_10_fn(struct fipc_ring_channel* thread1_chan, struct fipc_message* msg)
{
struct fipc_ring_channel * thread3_chan = rx_group->chans[1];
struct fipc_message* thread3_msg = get_send_slot(thread3_chan);
struct fipc_message* thread1_result;
unsigned long saved_msg_id = msg->msg_id;
unsigned long new_msg_id = awe_mapper_create_id();
transaction_complete(msg);
thread3_msg->fn_type = msg->fn_type;
thread3_msg->reg1 = msg->reg1;
thread3_msg->reg2 = msg->reg2;
thread3_msg->msg_id = new_msg_id;
thread3_msg->msg_type = msg_type_request;
send(thread3_chan,thread3_msg);
msg = async_recv(thread3_chan, new_msg_id);
transaction_complete(msg);
thread1_result = get_send_slot(thread1_chan);
thread1_result->fn_type = msg->fn_type;
thread1_result->reg1 = msg->reg1;
thread1_result->reg2 = msg->reg2;
thread1_result->msg_id = saved_msg_id;
thread1_result->msg_type = msg_type_response;
send(thread1_chan,thread1_result);
return 0;
}
static int thread1_dispatch_fn(struct fipc_ring_channel* chan, struct fipc_message* msg)
{
switch( get_fn_type(msg) )
{
case ADD_2_FN:
return add_2_fn(chan, msg);
case ADD_10_FN:
return add_10_fn(chan, msg);
default:
printk(KERN_ERR "FN: %lu is not a valid function type\n", msg->fn_type);
}
return 1;
}
int thread2_fn1(void* group)
{
thc_init();
rx_group = (struct thc_channel_group*)group;
rx_group->chans[0]->dispatch_fn = thread1_dispatch_fn;
ipc_dispatch_loop(rx_group, TRANSACTIONS);
thc_done();
return 1;
}
#include <thc.h>
#include <thcinternal.h>
#include <awe-mapper.h>
#include <libfipc.h>
#include "thread_fn_util.h"
static struct fipc_ring_channel* channel;
int thread3_fn(void* channel)
{
}
#include "thread_fn_util.h"
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;
printk(KERN_ERR "got result\n");
return 0;
fail2:
fail1:
return ret;
}
#ifndef THREAD_FN_UTIL
#define THREAD_FN_UTIL
#include <libfipc.h>
#define ADD_2_FN 1
#define ADD_10_FN 2
#define TRANSACTIONS 60
#define THD3_INTERVAL 10
int thread1_fn(void* data);
int thread2_fn(void* data);
int thread3_fn(void* data);
int send_and_get_response(
struct fipc_ring_channel *chan,
struct fipc_message *request,
struct fipc_message **response,
uint32_t msg_id);
#endif
/local/sda4/xcap-async-module/libasync/tests/simple/libasync_test.ko
/local/sda4/xcap-async-module/libasync/tests/simple/../../src/common/awe-mapper.o /local/sda4/xcap-async-module/libasync/tests/simple/../../src/common/thc.o /local/sda4/xcap-async-module/libasync/tests/simple/../../src/common/thc_ipc.o /local/sda4/xcap-async-module/libasync/tests/simple/../../src/common/thcsync.o /local/sda4/xcap-async-module/libasync/tests/simple/../../../fast-ipc-module/src/common/ipc.o /local/sda4/xcap-async-module/libasync/tests/simple/callee.o /local/sda4/xcap-async-module/libasync/tests/simple/caller.o /local/sda4/xcap-async-module/libasync/tests/simple/main.o
ASYNC_OBJS_DIR=../src/common
RPC_OBJS_DIR=../../fast-ipc-module/src/common
ASYNC_OBJS_DIR=../../src/common
RPC_OBJS_DIR=../../../fast-ipc-module/src/common
CFLAGS_ipc.o = -O2 -DPOLL -fno-ipa-cp -fno-ipa-sra
#CFLAGS_ring-channel.o = -I$(RPC_OBJS_DIR)../../IPC -I$(RING_CHAN_DIR) -fno-ipa-cp -fno-ipa-sra
EXTRA_CFLAGS=-DDEBUG_OUTPUT
......
......@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <libfipc.h>
#include "rpc.h"
#include "../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include "../../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include <thc_ipc.h>
/*
......
......@@ -12,7 +12,7 @@
#include <thc.h>
#include <thcinternal.h>
#include <awe-mapper.h>
#include "../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include "../../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
static inline int send_and_get_response(
struct fipc_ring_channel *chan,
......
......@@ -8,7 +8,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include "../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include "../../../fast-ipc-module/src/platform/kernel/tests/test_helpers.h"
#include "rpc.h"
#define CALLER_CPU 1
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment