Subversion Repositories Kolibri OS

Rev

Rev 1238 | 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. #include <ipc.h>
  27.  
  28. group_list_t *main_group_list;
  29. thread_list_t *main_thread_list;
  30.  
  31. kolibri_memarea_t main_memarea;
  32. Heap memarea_heap;
  33.  
  34. void *return_0(Heap *wheap, int nbytes){
  35.         return NULL;
  36. }
  37.  
  38. void *memarea_alloc(int nbytes){
  39.         return halMemAlloc(&memarea_heap, nbytes);
  40. }
  41.  
  42. void memarea_free(void *addr){
  43.         halMemFree(&memarea_heap, addr);
  44. }
  45.  
  46. void main(){
  47.         malloc_init();
  48.        
  49.         // Alloc memory for thread&group lists
  50.         main_memarea = kolibri_new_named_memory(KOBRA_MEMAREA_NAME, KOBRA_MEM_SIZE, KOLIBRI_ACCESS_READ|KOLIBRI_CREATE);
  51.         halMemHeapInit(&memarea_heap, &return_0, main_memarea.addr, KOBRA_MEM_SIZE);
  52.        
  53.         // Init main group list
  54.         create_group("main");
  55.         main_group_list->next = main_group_list->previos = main_group_list;
  56.         main_group_list->thread_list = main_thread_list = new_thread_list(kolibri_get_my_tid());
  57.         main_thread_list->next = main_thread_list->previos = main_thread_list;
  58.        
  59.         IPCInit();
  60. //      kolibri_IPC_unlock();
  61.        
  62.         // Set event mask
  63. //      kolibri_event_set_mask(KOLIBRI_IPC_EVENT_MASK);
  64.        
  65.         while (1) {
  66.                 Message *msg = IPCWaitMessage(-1);
  67. //              if (kolibri_event_wait() != KOLIBRI_IPC_EVENT) {                // Just ignore this error
  68. //                      continue;
  69. //              }
  70.                 message_handle(msg);
  71.                 free(msg);
  72. //              kolibri_IPC_clear_buff();
  73.         }
  74. }
  75.  
  76. void message_handle(kolibri_IPC_message_t *message){
  77.         char *msg = (char *)message+sizeof(kolibri_IPC_message_t);
  78.         char cmd = msg[0];
  79.         thread_list_t *thread = find_tid(main_group_list, message->tid);
  80.         group_list_t *group;
  81.         int i;
  82.        
  83.         if (cmd == KOBRA_CMD_REGISTER && !thread) {
  84.                 kobra_register(message->tid);
  85.         } else if (thread) {
  86.                 switch (cmd) {
  87.                         case KOBRA_CMD_JOIN:
  88.                                 if (message->length < 3 || msg[message->length-1] != '\0') {
  89.                                         // Here should be some error handler
  90.                                         return;
  91.                                 }
  92.                                
  93.                                 if (!(group = find_group(msg+1))){
  94.                                         group = create_group(msg+1);
  95.                                 }
  96.                                 add_to_group(group, message->tid);
  97.                                 break;
  98.                         case KOBRA_CMD_UNJOIN:
  99.                                 if (message->length < 3 || msg[message->length-1] != '\0') {
  100.                                         // Here should be some error handler
  101.                                         return;
  102.                                 }
  103.                                
  104.                                 if ((group = find_group(msg+1)) && (thread = find_tid(group, message->tid))) {
  105.                                         remove_from_group(group, thread);
  106.                                 }
  107.                                 break;
  108.                         case KOBRA_CMD_SEND:
  109.                                 if (message->length < 4) {
  110.                                         // Here should be some error handler
  111.                                         return;
  112.                                 }
  113.                                
  114.                                 // Check if group name is correct
  115.                                 for (i = 1; i < message->length-1 && msg[i]; ++i);
  116.                                 if (msg[i]) {
  117.                                         // Here should be some error handler
  118.                                         return;
  119.                                 }
  120.                                
  121.                                 group = find_group(msg+1);
  122.                                 if (!group) {
  123.                                         // Here should be some error handler
  124.                                         return;
  125.                                 }
  126.                                
  127.                                 send_group_message(group, message->tid, msg+i+1, message->length-i-1);
  128.                                 break;
  129.                         case KOBRA_CMD_GET_LIST_NAME:
  130.                                 // This is temporary realisation
  131.                                 kolibri_IPC_send(message->tid, KOBRA_MEMAREA_NAME, KOBRA_MEMAREA_NAME_LENGTH);
  132.                         default:
  133.                                 // Here should be some error handler
  134.                                 return;
  135.                 }
  136.         }
  137. }
  138.  
  139. thread_list_t *find_tid(group_list_t *group, int tid){
  140.         thread_list_t *thread_list = group->thread_list, *thread = thread_list;
  141.        
  142.         if (!thread_list) {
  143.                 return NULL;
  144.         }
  145.        
  146.         do {
  147.                 if (thread->tid == tid) {
  148.                         return thread;
  149.                 }
  150.                 thread = thread->next;
  151.         } while (thread != thread_list);
  152.        
  153.         return NULL;
  154. }
  155.  
  156. void kobra_register(int tid){
  157.         add_to_group(main_group_list, tid);
  158. }
  159.  
  160. void add_to_group(group_list_t *group, int tid){
  161.         thread_list_t *thread_list = group->thread_list, *thread_last;
  162.        
  163.         if (!thread_list) {
  164.                 thread_list = group->thread_list = new_thread_list(tid);
  165.                 thread_list->previos = thread_list->next = thread_list;
  166.         } else if (thread_list == (thread_last = thread_list->previos)) {
  167.                 thread_last = thread_list->next = thread_list->previos = new_thread_list(tid);
  168.                 thread_last->next = thread_last->previos = thread_list;
  169.         } else {
  170.                 thread_last->next = thread_list->previos = new_thread_list(tid);
  171.                 thread_last->next->next = thread_list;
  172.                 thread_last->next->previos = thread_last;
  173.         }
  174. }
  175.  
  176. void remove_from_group(group_list_t *group, thread_list_t *thread){
  177.         if (thread->next == thread) {
  178.                 remove_group(group);
  179.         } else {
  180.                 thread->next->previos = thread->previos;
  181.                 thread->previos->next = thread->next;
  182.                 if (group->thread_list == thread) {
  183.                         group->thread_list = thread->next;
  184.                 }
  185.         }
  186.        
  187.         memarea_free(thread);
  188. }
  189.  
  190. group_list_t *find_group(char *name){
  191.         group_list_t *group_list = main_group_list, *group = group_list;
  192.        
  193.         if (group_list) {
  194.                 do {
  195.                         if (!strcmp(group->name, name)) {
  196.                                 return group;
  197.                         }
  198.                         group = group->next;
  199.                 } while (group != group_list);
  200.         }
  201.        
  202.         return NULL;
  203. }
  204.  
  205. void send_group_message(group_list_t *group, int tid, char *message, int length){
  206.         thread_list_t *thread_list = group->thread_list, *thread = thread_list;
  207.         char *msg = malloc(length+sizeof(int));
  208.        
  209.         ((unsigned long *)msg)[0] = (unsigned long)tid;
  210.         memcpy(msg+4, message, length);
  211.        
  212.         do {
  213.                 IPCSend(thread->tid, msg, length+sizeof(int));          // Here may be some errror handler
  214.                 thread = thread->next;
  215.         } while (thread != thread_list);
  216. }
  217.  
  218. void remove_group(group_list_t *group){
  219.         if (group == main_group_list) {
  220.                 return;
  221.         }
  222.         group->next->previos = group->previos;
  223.         group->previos->next = group->next;
  224.         memarea_free(group);
  225. }
  226.  
  227. group_list_t *create_group(char *name){
  228.         group_list_t *group_list = main_group_list, *group_last;
  229.        
  230.         if (!group_list) {
  231.                 return main_group_list = new_group_list(name);
  232.         }
  233.        
  234.         group_last = group_list->previos;
  235.         if (group_list == group_last) {
  236.                 group_last = group_list->next = group_list->previos = new_group_list(name);
  237.                 group_last->next = group_last->previos = group_list;
  238.         } else {
  239.                 group_last->next = group_list->previos = new_group_list(name);
  240.                 group_last->next->next = group_list;
  241.                 group_last->next->previos = group_last;
  242.                 group_last = group_last->next;
  243.         }
  244.        
  245.         return group_last;
  246. }
  247.  
  248. group_list_t *new_group_list(char *name){
  249.         group_list_t *list = memarea_alloc(sizeof(group_list_t));
  250.         if (list) {
  251.                 list->name = malloc(strlen(name));
  252.                 strcpy(list->name, name);
  253.                 list->thread_list = NULL;
  254.         }
  255.         return list;
  256. }
  257.  
  258. thread_list_t *new_thread_list(int tid){
  259.         thread_list_t *list = memarea_alloc(sizeof(thread_list_t));
  260.         if (list) {
  261.                 list->tid = tid;
  262.         }
  263.         return list;
  264. }
  265.  
  266. asm(".align 16\n.globl end\nend:");
  267.