Commit cf15758d authored by Michael Quigley's avatar Michael Quigley
Browse files

added ipc-groups

parent 5546caf5
......@@ -89,23 +89,12 @@ static int wait_for_rx_slot(struct ipc_message *imsg)
return 0;
}
struct task_struct * attach_channels_to_thread(struct ttd_ring_channel_group *chan_arr,
int CPU_PIN,
int (*threadfn)(void *data))
{
}
struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
static struct task_struct *attach_data_to_channel(void *chan_data,
int CPU_PIN,
int (*threadfn)(void *data)) {
struct cpumask cpu_core;
if (!chan)
if (!chan_data)
return NULL;
if (CPU_PIN > num_online_cpus()) {
......@@ -113,22 +102,41 @@ struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
return NULL;
}
chan->thread = kthread_create(threadfn, (void *)chan,
struct task_struct* thread = kthread_create(threadfn, chan_data,
"AsyncIPC.%u", CPU_PIN);
if (IS_ERR(chan->thread)) {
if (IS_ERR(thread)) {
pr_err("Error while creating kernel thread\n");
return NULL;
}
get_task_struct(chan->thread);
get_task_struct(thread);
cpumask_clear(&cpu_core);
cpumask_set_cpu(CPU_PIN , &cpu_core);
set_cpus_allowed_ptr(chan->thread, &cpu_core);
set_cpus_allowed_ptr(thread, &cpu_core);
return chan->thread;
return thread;
}
struct task_struct * attach_channels_to_thread(ttd_ring_channel_group_t *chan_group,
int CPU_PIN,
int (*threadfn)(void *data))
{
return attach_data_to_channel((void *)chan_group, CPU_PIN, threadfn);
}
EXPORT_SYMBOL(attach_channels_to_thread);
struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
int CPU_PIN,
int (*threadfn)(void *data)) {
return attach_data_to_channel((void *)chan, CPU_PIN, threadfn);
}
EXPORT_SYMBOL(attach_thread_to_channel);
......@@ -180,14 +188,17 @@ EXPORT_SYMBOL(create_channel);
void free_channel(struct ttd_ring_channel *channel)
{
ttd_ring_channel_free(channel);
put_task_struct(channel->thread);
kfree(channel);
}
EXPORT_SYMBOL(free_channel);
void free_thread(struct task_struct *thread)
{
put_task_struct(thread);
}
EXPORT_SYMBOL(free_thread);
void send(struct ttd_ring_channel *tx, struct ipc_message *trans)
{
......@@ -242,7 +253,6 @@ EXPORT_SYMBOL(poll_recv);
noinline struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned long msg_id)
{
struct ipc_message *recv_msg;
void* pts = current->ptstate;
while( true )
{
recv_msg = get_rx_rec(rx, sizeof(struct ipc_message));
......@@ -257,8 +267,8 @@ noinline struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned lo
{
//printk(KERN_ERR "MESSAGE ID RECEIVED IS: %lx\n", recv_msg->msg_id);
//printk(KERN_ERR "MESSAGE ID FOR CONTEXT IS: %lx\n", msg_id);
//printk(KERN_ERR "CALLING YIELD TO\n");
if( recv_msg->pts == pts )
printk(KERN_ERR "CALLING YIELD TO\n");
if( recv_msg->msg_type == msg_type_response )
{
THCYieldToId((uint32_t) recv_msg->msg_id, (uint32_t) msg_id);
}
......@@ -308,8 +318,8 @@ void transaction_complete(struct ipc_message *msg)
EXPORT_SYMBOL(transaction_complete);
int ipc_start_thread(struct ttd_ring_channel *chan)
int ipc_start_thread(struct task_struct* thread)
{
return wake_up_process(chan->thread);
return wake_up_process(thread);
}
EXPORT_SYMBOL(ipc_start_thread);
......@@ -16,6 +16,13 @@
/* TODO CONFIRM ALIGNMENT REQUIREMENTS FOR ULONG! */
typedef enum {
msg_type_unspecified,
msg_type_request,
msg_type_response,
} msg_type_t;
struct ipc_message{
int fn_type; /* looks like standard converts ENUM members to ints */
unsigned long reg1;
......@@ -24,7 +31,7 @@ struct ipc_message{
unsigned long reg4;
unsigned long reg5;
#ifdef USE_ASYNC
unsigned long pts;
unsigned long msg_type;
#else
unsigned long reg6;
#endif
......@@ -32,10 +39,15 @@ struct ipc_message{
volatile uint32_t msg_status;
}__attribute__((packed));
typedef struct ttd_ring_channel_group ttd_ring_channel_group_t;
struct ttd_ring_channel *create_channel(unsigned long size_pages);
struct task_struct *attach_thread_to_channel(struct ttd_ring_channel *chan,
int CPU_PIN,
int (*threadfn)(void *data));
struct task_struct *attach_channels_to_thread(ttd_ring_channel_group_t *chan_group,
int CPU_PIN,
int (*threadfn)(void *data));
void free_channel(struct ttd_ring_channel *channel);
void send(struct ttd_ring_channel *tx, struct ipc_message *trans);
struct ipc_message *recv(struct ttd_ring_channel *rx);
......@@ -43,7 +55,7 @@ bool poll_recv(struct ttd_ring_channel** rx_chans, int chans_num, int* curr_ind,
struct ipc_message *async_recv(struct ttd_ring_channel *rx, unsigned long msg_id);
struct ipc_message *get_send_slot(struct ttd_ring_channel *tx);
void transaction_complete(struct ipc_message *msg);
int ipc_start_thread(struct ttd_ring_channel *chan);
int ipc_start_thread(struct task_struct* thread);
void connect_channels(struct ttd_ring_channel *c1, struct ttd_ring_channel *t2);
#endif
......@@ -32,17 +32,17 @@ struct ttd_buf {
struct ttd_ring_channel {
struct ttd_buf tx;
struct ttd_buf rx;
struct task_struct *thread;
/* TODO NECESSARY? */
uint8_t padding[56]; /* pad the struct to cacheline size */
uint8_t padding[64]; /* pad the struct to cacheline size */
};
typedef struct ttd_ring_channel_group
struct ttd_ring_channel_group
{
struct ttd_ring_channel **chans;
int chans_length;
struct task_struct *thread;
} ttd_ring_channel_group_t;
};
static inline void ttd_ring_channel_init(struct ttd_ring_channel *ring_channel)
......
......@@ -47,16 +47,17 @@ static void setup_tests(void)
/* Create a thread for each channel to utilize, pin it to a core.
* Pass a function pointer to call on wakeup.
*/
if (attach_thread_to_channel(chan1, CHAN1_CPU, thread1_fn1) == NULL ||
attach_thread_to_channel(chan2, CHAN2_CPU, thread2_fn1) == NULL ) {
struct task_struct *thread1 = attach_thread_to_channel(chan1, CHAN1_CPU, thread1_fn1);
struct task_struct *thread2 = attach_thread_to_channel(chan2, CHAN2_CPU, thread2_fn1);
if ( thread1 == NULL || thread2 == NULL ) {
ttd_ring_channel_free(chan1);
ttd_ring_channel_free(chan2);
kfree(chan1);
kfree(chan2);
return;
}
ipc_start_thread(chan1);
ipc_start_thread(chan2);
ipc_start_thread(thread1);
ipc_start_thread(thread2);
}
static int __init async_dispatch_start(void)
......
......@@ -11,10 +11,10 @@ int ipc_dispatch_loop(ipc_local_fn_t* fns, int fns_length,struct ttd_ring_channe
{
volatile void ** frame = (volatile void**)__builtin_frame_address(0);
volatile void *ret_addr = *(frame + 1);
int recv_ct = 0;
*(frame + 1) = NULL;
//NOTE:recv_ct is just for testing
int recv_ct = 0;
DO_FINISH({
int curr_ind = 0;
int* curr_ind_pt = &curr_ind;
......@@ -30,7 +30,7 @@ int ipc_dispatch_loop(ipc_local_fn_t* fns, int fns_length,struct ttd_ring_channe
printk(KERN_ERR "poll_recv returned\n");
//check if curr_msg corresponds to existing awe in this thread
if( curr_msg->pts == current->ptstate )
if( curr_msg->msg_type == msg_type_response )
{
printk(KERN_ERR "yielding to\n");
THCYieldToId(curr_msg->msg_id, do_finish_awe_id);
......@@ -44,7 +44,7 @@ int ipc_dispatch_loop(ipc_local_fn_t* fns, int fns_length,struct ttd_ring_channe
printk(KERN_ERR "fn_type: %d\n", curr_msg->fn_type);
if( curr_msg->fn_type == fns[i].fn_type )
{
printk(KERN_ERR "calling fn: %lu\n", fns[i].fn_type);
printk(KERN_ERR "calling fn: %d\n", fns[i].fn_type);
fns[i].local_fn(rx_chans[*curr_ind_pt], curr_msg, NULL);
}
}
......
......@@ -12,11 +12,11 @@ static unsigned long add_2_nums_async(unsigned long lhs, unsigned long rhs, unsi
struct ipc_message *msg;
unsigned long result;
msg = get_send_slot(channel);
msg->fn_type = ADD_2_FN;
msg->reg1 = lhs;
msg->reg2 = rhs;
msg->msg_id = msg_id;
msg->pts = (unsigned long)current->ptstate;
msg->fn_type = ADD_2_FN;
msg->reg1 = lhs;
msg->reg2 = rhs;
msg->msg_id = msg_id;
msg->msg_type = msg_type_request;
send(channel,msg);
msg = async_recv(channel, msg_id);
result = msg->reg1;
......@@ -32,13 +32,13 @@ int thread1_fn1(void* chan)
{
volatile void ** frame = (volatile void**)__builtin_frame_address(0);
volatile void *ret_addr = *(frame + 1);
*(frame + 1) = NULL;
int num_transactions = 0;
uint32_t id_num;
*(frame + 1) = NULL;
channel = chan;
thc_init();
DO_FINISH(
uint32_t id_num;
while (num_transactions < TRANSACTIONS / 3) {
if((num_transactions * 3) % 10 == 0)
{
......
......@@ -11,10 +11,10 @@ int add_2_fn(struct ttd_ring_channel* chan, struct ipc_message* msg, void* param
{
unsigned long result = msg->reg1 + msg->reg2;
struct ipc_message* out_msg = get_send_slot(chan);
out_msg->reg1 = result;
out_msg->msg_id = msg->msg_id;
out_msg->fn_type = ADD_2_FN;
out_msg->pts = msg->pts;
out_msg->reg1 = result;
out_msg->msg_id = msg->msg_id;
out_msg->fn_type = ADD_2_FN;
out_msg->msg_type = msg_type_response;
send(chan, out_msg);
return 0;
......
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