Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1286 vkos 1
/***************************************************************************************************
2
 *  Copyright (C) Vasiliy Kosenko (vkos), 2009                                                     *
3
 *  This program is free software: you can redistribute it and/or modify it under the terms of the *
4
 *  GNU General Public License as published by the Free Software Foundation, either version 3      *
5
 *  of the License, or (at your option) any later version.                                         *
6
 *                                                                                                 *
7
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;      *
8
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See  *
9
 *  the GNU General Public License for more details.                                               *
10
 *                                                                                                 *
11
 *  You should have received a copy of the GNU General Public License along with this program.     *
12
 *  If not, see .                                                    *
13
 ***************************************************************************************************/
14
 
15
#include 
16
#include 
17
#include 
18
#include 
19
#include 
20
 
21
/*
22
 * High level IPC functions
23
 */
24
 
25
IPCArea *ipc_area = NULL;
26
 
27
int IPCInit(void){
28
	ipc_area = malloc(IPC_BUFFER_SIZE);
29
	if (!ipc_area) {
30
		return IPC_NO_MEMORY;
31
	}
32
	return kolibri_IPC_init(ipc_area, IPC_BUFFER_SIZE);
33
}
34
 
35
int IPCSend(int tid, void *message, int length){
36
	int err_count = IPC_MAX_ERRORS;
37
	int err;
38
 
39
	while (--err_count) {
40
		if (!(err = kolibri_IPC_send(tid, message, length)) || err == IPC_NO_AREA || err == IPC_NO_TID) {
41
			return err;
42
		}
43
	}
44
	return err;
45
}
46
 
47
bool IPCCheck(void){
48
	return IPCCheckWait(0);
49
}
50
 
51
bool IPCCheckWait(int time){
52
	int result = false;
53
	int emask = kolibri_event_get_mask();
54
 
55
	kolibri_event_set_mask(KOLIBRI_EVENT_IPC_MASK);
56
 
57
	result = kolibri_event_wait(time);
58
 
59
	kolibri_event_set_mask(emask);
60
 
61
	return result;
62
}
63
 
64
Message *IPCGetNextMessage(void){
65
	return IPCWaitMessage(0);
66
}
67
 
68
Message *IPCWaitMessage(int time){
69
	if (IPCCheckWait(time)){
70
		Message *msg_ret, *msg = kolibri_IPC_get_next_message();
71
		msg_ret = malloc(sizeof(Message)+msg->length);
72
		if (!msg_ret) {
73
			return NULL;
74
		}
75
		IPCLock();
76
		memcpy(msg_ret, msg, sizeof(Message)+msg->length);
77
		ipc_area->size -= sizeof(Message)+msg->length;
78
		memcpy(msg, msg+sizeof(Message)+msg->length, ipc_area->size);
79
		IPCUnlock();
80
		return msg_ret;
81
	} else {
82
		return NULL;
83
	}
84
}
85
 
86
/*
87
 * Kolibri IPC functions & data
88
 */
89
 
90
kolibri_IPC_area_t *kolibri_ipc_area;
91
 
92
int kolibri_IPC_set_area(void *area, int size){
93
	int result;
94
 
95
	asm("int $0x40":"=a"(result):"a"(60),"b"(1),"c"(area),"d"(size));
96
 
97
	return result;
98
}
99
 
100
int kolibri_IPC_send(int tid, void *msg, int length){
101
	int result;
102
 
103
	asm("movl %5, %%esi\nint $0x40":"=a"(result):"a"(60),"b"(2),"c"(tid),"d"(msg),"g"(length));
104
 
105
	return result;
106
}
107
 
108
void kolibri_IPC_unlock(){
109
	kolibri_ipc_area->lock = 0;
110
}
111
 
112
void kolibri_IPC_lock(){
113
	kolibri_ipc_area->lock = 1;
114
}
115
 
116
int kolibri_IPC_init(void *area, int size){
117
	kolibri_ipc_area = (kolibri_IPC_area_t *)area;
118
	kolibri_ipc_area->size = 8;
119
 
120
	return kolibri_IPC_set_area(area, size);
121
}
122
 
123
kolibri_IPC_message_t *kolibri_IPC_get_next_message(){
124
	kolibri_IPC_lock();
125
	return (kolibri_IPC_message_t *)((char *)kolibri_ipc_area+sizeof(kolibri_IPC_area_t));
126
}
127
 
128
void IPCLock(void){
129
	kolibri_IPC_lock();
130
}
131
 
132
void IPCUnlock(void){
133
	kolibri_IPC_unlock();
134
}
135
 
136
// void kolibri_IPC_clear_buff(){
137
// 	kolibri_ipc_area->size = 8;
138
// 	kolibri_IPC_unlock();
139
// }