Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************************************
  2.  *  Copyright (C) Vasiliy Kosenko (vkos), 2009                                                     *
  3.  *  Kobra is free software: you can redistribute it and/or modify it under the terms of the GNU    *
  4.  *  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.  *  Kobra is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without     *
  8.  *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  *
  9.  *  General Public License for more details.                                                       *
  10.  *                                                                                                 *
  11.  *  You should have received a copy of the GNU General Public License along with Kobra.            *
  12.  *  If not, see <http://www.gnu.org/licenses/>.                                                    *
  13.  ***************************************************************************************************/
  14.  
  15. /***************************************************************************************************
  16.  *  Kobra (Kolibri Bus for Reaching Applications) is daemon for advanced & easier applications     *
  17.  *  communication.                                                                                 *
  18.  ***************************************************************************************************/
  19.  
  20. #include "kobra.h"
  21. #include "heap.h"
  22. #include "malloc.h"
  23. #include "kolibri.h"
  24. #include "defs.h"
  25. #include "stdlib.h"
  26.  
  27. group_list_t *main_group_list;
  28. thread_list_t *main_thread_list;
  29.  
  30. kolibri_memarea_t main_memarea;
  31. Heap memarea_heap;
  32.  
  33. void *return_0(Heap *wheap, int nbytes){
  34.         return NULL;
  35. }
  36.  
  37. void *memarea_alloc(int nbytes){
  38.         return halMemAlloc(&memarea_heap, nbytes);
  39. }
  40.  
  41. void memarea_free(void *addr){
  42.         halMemFree(&memarea_heap, addr);
  43. }
  44.  
  45. void main(){
  46.         malloc_init();
  47.        
  48.         // Alloc memory for thread&group lists
  49.         main_memarea = kolibri_new_named_memory(KOBRA_MEMAREA_NAME, KOBRA_MEM_SIZE, KOLIBRI_ACCESS_READ|KOLIBRI_CREATE);
  50.         halMemHeapInit(&memarea_heap, &return_0, main_memarea.addr, KOBRA_MEM_SIZE);
  51.        
  52.         // Init main group list
  53.         create_group("main");
  54.         main_group_list->next = main_group_list->previos = main_group_list;
  55.         main_group_list->thread_list = main_thread_list = new_thread_list(kolibri_get_my_tid());
  56.         main_thread_list->next = main_thread_list->previos = main_thread_list;
  57.        
  58.         kolibri_IPC_init(malloc(0x1000), 0x1000);
  59.         kolibri_IPC_unlock();
  60.        
  61.         // Set event mask
  62.         kolibri_set_event_mask(KOLIBRI_IPC_EVENT_MASK);
  63.        
  64.         while (1) {
  65.                 if (kolibri_event_wait() != KOLIBRI_IPC_EVENT) {                // Just ignore this error
  66.                         continue;
  67.                 }
  68.                
  69.                 message_handle(kolibri_IPC_get_next_message());
  70.                 kolibri_IPC_clear_buff();
  71.         }
  72. }
  73.  
  74. void message_handle(kolibri_IPC_message_t *message){
  75.         char *msg = (char *)message+sizeof(kolibri_IPC_message_t);
  76.         char cmd = msg[0];
  77.         thread_list_t *thread = find_tid(main_group_list, message->tid);
  78.         group_list_t *group;
  79.         int i;
  80.        
  81.         if (cmd == KOBRA_CMD_REGISTER && !thread) {
  82.                 kobra_register(message->tid);
  83.         } else if (thread) {
  84.                 switch (cmd) {
  85.                         case KOBRA_CMD_JOIN:
  86.                                 if (message->length < 3 || msg[message->length-1] != '\0') {
  87.                                         // Here should be some error handler
  88.                                         return;
  89.                                 }
  90.                                
  91.                                 if (!(group = find_group(msg+1))){
  92.                                         group = create_group(msg+1);
  93.                                 }
  94.                                 add_to_group(group, message->tid);
  95.                                 break;
  96.                         case KOBRA_CMD_UNJOIN:
  97.                                 if (message->length < 3 || msg[message->length-1] != '\0') {
  98.                                         // Here should be some error handler
  99.                                         return;
  100.                                 }
  101.                                
  102.                                 if ((group = find_group(msg+1)) && (thread = find_tid(group, message->tid))) {
  103.                                         remove_from_group(group, thread);
  104.                                 }
  105.                                 break;
  106.                         case KOBRA_CMD_SEND:
  107.                                 if (message->length < 4) {
  108.                                         // Here should be some error handler
  109.                                         return;
  110.                                 }
  111.                                
  112.                                 // Check if group name is correct
  113.                                 for (i = 1; i < message->length-1 && msg[i]; ++i);
  114.                                 if (msg[i]) {
  115.                                         // Here should be some error handler
  116.                                         return;
  117.                                 }
  118.                                
  119.                                 group = find_group(msg+1);
  120.                                 if (!group) {
  121.                                         // Here should be some error handler
  122.                                         return;
  123.                                 }
  124.                                
  125.                                 send_group_message(group, message->tid, msg+i+1, message->length-i-1);
  126.                                 break;
  127.                         case KOBRA_CMD_GET_LIST_NAME:
  128.                                 // This is temporary realisation
  129.                                 kolibri_IPC_send(message->tid, KOBRA_MEMAREA_NAME, KOBRA_MEMAREA_NAME_LENGTH);
  130.                         default:
  131.                                 // Here should be some error handler
  132.                                 return;
  133.                 }
  134.         }
  135. }
  136.  
  137. thread_list_t *find_tid(group_list_t *group, int tid){
  138.         thread_list_t *thread_list = group->thread_list, *thread = thread_list;
  139.        
  140.         if (!thread_list) {
  141.                 return NULL;
  142.         }
  143.        
  144.         do {
  145.                 if (thread->tid == tid) {
  146.                         return thread;
  147.                 }
  148.                 thread = thread->next;
  149.         } while (thread != thread_list);
  150.        
  151.         return NULL;
  152. }
  153.  
  154. void kobra_register(int tid){
  155.         add_to_group(main_group_list, tid);
  156. }
  157.  
  158. void add_to_group(group_list_t *group, int tid){
  159.         thread_list_t *thread_list = group->thread_list, *thread_last;
  160.        
  161.         if (!thread_list) {
  162.                 thread_list = group->thread_list = new_thread_list(tid);
  163.                 thread_list->previos = thread_list->next = thread_list;
  164.         } else if (thread_list == (thread_last = thread_list->previos)) {
  165.                 thread_last = thread_list->next = thread_list->previos = new_thread_list(tid);
  166.                 thread_last->next = thread_last->previos = thread_list;
  167.         } else {
  168.                 thread_last->next = thread_list->previos = new_thread_list(tid);
  169.                 thread_last->next->next = thread_list;
  170.                 thread_last->next->previos = thread_last;
  171.         }
  172. }
  173.  
  174. void remove_from_group(group_list_t *group, thread_list_t *thread){
  175.         if (thread->next == thread) {
  176.                 remove_group(group);
  177.         } else {
  178.                 thread->next->previos = thread->previos;
  179.                 thread->previos->next = thread->next;
  180.                 if (group->thread_list == thread) {
  181.                         group->thread_list = thread->next;
  182.                 }
  183.         }
  184.        
  185.         memarea_free(thread);
  186. }
  187.  
  188. group_list_t *find_group(char *name){
  189.         group_list_t *group_list = main_group_list, *group = group_list;
  190.        
  191.         if (group_list) {
  192.                 do {
  193.                         if (!strcmp(group->name, name)) {
  194.                                 return group;
  195.                         }
  196.                         group = group->next;
  197.                 } while (group != group_list);
  198.         }
  199.        
  200.         return NULL;
  201. }
  202.  
  203. void send_group_message(group_list_t *group, int tid, char *message, int length){
  204.         thread_list_t *thread_list = group->thread_list, *thread = thread_list;
  205.         char *msg = malloc(length+sizeof(int));
  206.        
  207.         ((unsigned long *)msg)[0] = (unsigned long)tid;
  208.         memcpy(msg+4, message, length);
  209.        
  210.         do {
  211.                 kolibri_IPC_send(thread->tid, msg, length+sizeof(int));
  212.                 thread = thread->next;
  213.         } while (thread != thread_list);
  214. }
  215.  
  216. void remove_group(group_list_t *group){
  217.         if (group == main_group_list) {
  218.                 return;
  219.         }
  220.         group->next->previos = group->previos;
  221.         group->previos->next = group->next;
  222.         memarea_free(group);
  223. }
  224.  
  225. group_list_t *create_group(char *name){
  226.         group_list_t *group_list = main_group_list, *group_last;
  227.        
  228.         if (!group_list) {
  229.                 return main_group_list = new_group_list(name);
  230.         }
  231.        
  232.         group_last = group_list->previos;
  233.         if (group_list == group_last) {
  234.                 group_last = group_list->next = group_list->previos = new_group_list(name);
  235.                 group_last->next = group_last->previos = group_list;
  236.         } else {
  237.                 group_last->next = group_list->previos = new_group_list(name);
  238.                 group_last->next->next = group_list;
  239.                 group_last->next->previos = group_last;
  240.                 group_last = group_last->next;
  241.         }
  242.        
  243.         return group_last;
  244. }
  245.  
  246. group_list_t *new_group_list(char *name){
  247.         group_list_t *list = memarea_alloc(sizeof(group_list_t));
  248.         if (list) {
  249.                 list->name = malloc(strlen(name));
  250.                 strcpy(list->name, name);
  251.                 list->thread_list = NULL;
  252.         }
  253.         return list;
  254. }
  255.  
  256. thread_list_t *new_thread_list(int tid){
  257.         thread_list_t *list = memarea_alloc(sizeof(thread_list_t));
  258.         if (list) {
  259.                 list->tid = tid;
  260.         }
  261.         return list;
  262. }
  263.  
  264. asm(".align 16\n.globl end\nend:");
  265.