Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2872 → Rev 2873

/branches/tracing/uspace/app/sctrace/ipc.c
5,12 → 5,68
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <libadt/hash_table.h>
 
#include "ipc_desc.h"
#include "ipc.h"
 
void ipc_m_print(ipcarg_t method)
typedef struct {
int server;
proto_t *proto;
} connection_t;
 
#define MAX_PHONE 64
connection_t connections[MAX_PHONE];
int have_conn[MAX_PHONE];
 
#define PCALL_TABLE_CHAINS 32
hash_table_t pending_calls;
 
hash_index_t pending_call_hash(unsigned long key[])
{
printf("pending_call_hash\n");
return key[0] % PCALL_TABLE_CHAINS;
}
 
int pending_call_compare(unsigned long key[], hash_count_t keys, link_t *item)
{
pending_call_t *hs;
 
printf("pending_call_remove_compare\n");
hs = hash_table_get_instance(item, pending_call_t, link);
 
return key[0] == hs->call_hash;
}
 
void pending_call_remove_callback(link_t *item)
{
printf("pending_call_remove_callback\n");
}
 
hash_table_operations_t pending_call_ops = {
.hash = pending_call_hash,
.compare = pending_call_compare,
.remove_callback = pending_call_remove_callback
};
 
static void connection_set(int phone, int server, proto_t *proto)
{
if (phone <0 || phone >= MAX_PHONE) return;
connections[phone].server = server;
connections[phone].proto = proto;
have_conn[phone] = 1;
}
 
static void connection_clear(int phone)
{
have_conn[phone] = 0;
connections[phone].server = 0;
connections[phone].proto = NULL;
}
 
static void ipc_m_print(ipcarg_t method)
{
ipc_m_desc_t *desc;
 
/* FIXME: too slow */
27,8 → 83,20
printf("%d", method);
}
 
void ipcp_init(void)
{
hash_table_create(&pending_calls, PCALL_TABLE_CHAINS, 1, &pending_call_ops);
}
 
void ipcp_cleanup(void)
{
hash_table_destroy(&pending_calls);
}
 
void ipc_parse_call_out(int phone, ipc_call_t *call, ipc_callid_t hash)
{
pending_call_t *pcall;
 
// printf("ipc_parse_call_out()\n");
printf("call id: 0x%x, phone: %d, method: ", hash, phone);
ipc_m_print(IPC_GET_METHOD(*call));
39,10 → 107,22
IPC_GET_ARG4(*call),
IPC_GET_ARG5(*call)
);
 
/* Store call in hash table for response matching */
 
pcall = malloc(sizeof(pending_call_t));
pcall->phone_hash = phone;
pcall->question = *call;
pcall->call_hash = hash;
 
hash_table_insert(&pending_calls, &pcall->call_hash, &pcall->link);
}
 
void ipc_parse_call_in(ipc_call_t *call, ipc_callid_t hash)
{
link_t *item;
pending_call_t *pcall;
 
// printf("ipc_parse_call_in()\n");
/* printf("phone: %d, method: ", call->in_phone_hash);
ipc_m_print(IPC_GET_METHOD(*call));
53,6 → 133,22
IPC_GET_ARG4(*call),
IPC_GET_ARG5(*call)
);*/
 
if ((hash & IPC_CALLID_ANSWERED) == 0) {
/* Not a response */
printf("Not a response\n");
return;
}
 
hash = hash & ~IPC_CALLID_ANSWERED;
 
item = hash_table_find(&pending_calls, &hash);
if (item == NULL) return; // No matching question found
pcall = hash_table_get_instance(item, pending_call_t, link);
 
printf("response matched to question\n");
hash_table_remove(&pending_calls, &hash, 1);
}
 
void ipc_parse_call_sync(int phone, ipc_call_t *call, ipc_call_t *answer)