2009-10-26 20:03:29 +03:00
|
|
|
/***************************************************************************************************
|
|
|
|
* Copyright (C) Vasiliy Kosenko (vkos), 2009 *
|
|
|
|
* This program is free software: you can redistribute it and/or modify it under the terms of the *
|
|
|
|
* GNU General Public License as published by the Free Software Foundation, either version 3 *
|
|
|
|
* of the License, or (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; *
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
|
|
|
|
* the GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License along with this program. *
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
***************************************************************************************************/
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
#include <ipc.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <kolibri.h>
|
|
|
|
#include <defs.h>
|
|
|
|
#include <stdlib.h>
|
2009-10-26 20:03:29 +03:00
|
|
|
|
|
|
|
/*
|
2009-11-25 21:23:48 +03:00
|
|
|
* High level IPC functions
|
2009-10-26 20:03:29 +03:00
|
|
|
*/
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
IPCArea *ipc_area = NULL;
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
int IPCInit(void){
|
|
|
|
ipc_area = malloc(IPC_BUFFER_SIZE);
|
|
|
|
if (!ipc_area) {
|
|
|
|
return IPC_NO_MEMORY;
|
|
|
|
}
|
|
|
|
return kolibri_IPC_init(ipc_area, IPC_BUFFER_SIZE);
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
int IPCSend(int tid, void *message, int length){
|
|
|
|
int err_count = IPC_MAX_ERRORS;
|
|
|
|
int err;
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
while (--err_count) {
|
|
|
|
if (!(err = kolibri_IPC_send(tid, message, length)) || err == IPC_NO_AREA || err == IPC_NO_TID) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err;
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
bool IPCCheck(void){
|
|
|
|
return IPCCheckWait(0);
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
bool IPCCheckWait(int time){
|
|
|
|
int result = false;
|
|
|
|
int emask = kolibri_event_get_mask();
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
kolibri_event_set_mask(KOLIBRI_EVENT_IPC_MASK);
|
|
|
|
|
|
|
|
result = kolibri_event_wait(time);
|
|
|
|
|
|
|
|
kolibri_event_set_mask(emask);
|
|
|
|
|
|
|
|
return result;
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
Message *IPCGetNextMessage(void){
|
|
|
|
return IPCWaitMessage(0);
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
Message *IPCWaitMessage(int time){
|
|
|
|
if (IPCCheckWait(time)){
|
|
|
|
Message *msg_ret, *msg = kolibri_IPC_get_next_message();
|
|
|
|
msg_ret = malloc(sizeof(Message)+msg->length);
|
|
|
|
if (!msg_ret) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
IPCLock();
|
|
|
|
memcpy(msg_ret, msg, sizeof(Message)+msg->length);
|
|
|
|
ipc_area->size -= sizeof(Message)+msg->length;
|
|
|
|
memcpy(msg, msg+sizeof(Message)+msg->length, ipc_area->size);
|
|
|
|
IPCUnlock();
|
|
|
|
return msg_ret;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-11-25 21:23:48 +03:00
|
|
|
* Kolibri IPC functions & data
|
2009-10-26 20:03:29 +03:00
|
|
|
*/
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
kolibri_IPC_area_t *kolibri_ipc_area;
|
|
|
|
|
|
|
|
int kolibri_IPC_set_area(void *area, int size){
|
|
|
|
int result;
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
asm("int $0x40":"=a"(result):"a"(60),"b"(1),"c"(area),"d"(size));
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
return result;
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
int kolibri_IPC_send(int tid, void *msg, int length){
|
|
|
|
int result;
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
asm("movl %5, %%esi\nint $0x40":"=a"(result):"a"(60),"b"(2),"c"(tid),"d"(msg),"g"(length));
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
return result;
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
void kolibri_IPC_unlock(){
|
|
|
|
kolibri_ipc_area->lock = 0;
|
|
|
|
}
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
void kolibri_IPC_lock(){
|
|
|
|
kolibri_ipc_area->lock = 1;
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
int kolibri_IPC_init(void *area, int size){
|
|
|
|
kolibri_ipc_area = (kolibri_IPC_area_t *)area;
|
|
|
|
kolibri_ipc_area->size = 8;
|
2009-10-26 20:03:29 +03:00
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
return kolibri_IPC_set_area(area, size);
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
kolibri_IPC_message_t *kolibri_IPC_get_next_message(){
|
|
|
|
kolibri_IPC_lock();
|
|
|
|
return (kolibri_IPC_message_t *)((char *)kolibri_ipc_area+sizeof(kolibri_IPC_area_t));
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
void IPCLock(void){
|
|
|
|
kolibri_IPC_lock();
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
|
|
|
|
2009-11-25 21:23:48 +03:00
|
|
|
void IPCUnlock(void){
|
|
|
|
kolibri_IPC_unlock();
|
2009-10-26 20:03:29 +03:00
|
|
|
}
|
2009-11-25 21:23:48 +03:00
|
|
|
|
|
|
|
// void kolibri_IPC_clear_buff(){
|
|
|
|
// kolibri_ipc_area->size = 8;
|
|
|
|
// kolibri_IPC_unlock();
|
|
|
|
// }
|