00001 /*********************************************************** 00002 *PANALIX 0.06, (c) Adrian Panasiuk 2002-4 * 00003 *adek336[at]o2.pl, panalix.prv.pl * 00004 *under GPLv3 license * 00005 * * 00006 *panalix - small osdev project * 00007 ************************************************************ 00008 * msg.cpp, version 1.1 * 00009 ************************************************************ 00010 * * 00011 *draft * 00012 * * 00013 *26'05'04- first revision (1.0), based a little on 0.05 * 00014 *experimental branch's message passing * 00015 * * 00016 ***********************************************************/ 00017 00018 #include "src/common/shared.hpp" 00019 #include "src/common/blist.hpp" 00020 #include "src/common/blistsort.hpp" 00021 #include "src/memory/memset.hpp" 00022 #include "src/memory/align.hpp" 00023 #include "src/memory/heap.hpp" 00024 #include "src/arch/x86/interr.hpp" 00025 #include "src/arch/x86/except_c.hpp" 00026 #include "src/arch/x86/rtc.hpp" 00027 #include "src/thread/scheduler.hpp" 00028 #include "src/thread/thread.hpp" 00029 #include "src/ipc/msg.hpp" 00030 #include "src/ipc/sem.hpp" 00031 00032 00033 namespace IPC { 00034 namespace Message { 00035 00036 00037 //create a mailbox 00038 int allocate_mailbox (mailbox *mbx, class ::Thread::thread_t *owner, Memory::Heap::heapbox *hp) 00039 { 00040 //init vars 00041 memset(mbx,0,sizeof(mailbox)); 00042 mbx->lock_mail.init(const_cast<char*>("mailbox")); 00043 sem_init(&mbx->sem_mail,0,"mailbox"); 00044 (*(blist_t*)&mbx->inbox).init(FAC_MSG|FAC_MSGLIST); 00045 mbx->heap=hp; 00046 mbx->thread=owner; 00047 00048 return ESUCCESS; 00049 } 00050 // 00051 // //add a message to the inbox 00052 // int mailbox::new_mail(mailbox *sender, void *data, size_t size, uint32 flags) 00053 // { 00054 // union 00055 // { 00056 // uint32 i32[2]; 00057 // uint64 i64; 00058 // } uu; 00059 // 00060 // int i; 00061 // message *msg; 00062 // //alloc a message 00063 // msg=(message*)heap->malloc(sizeof(message)+size, NO_ALIGN, FAC_MSG|FAC_MESSAGE, NULL); 00064 // 00065 // if (msg == NULL) 00066 // { 00067 // complain("out of memory"); 00068 // return EFAIL; 00069 // } 00070 // memset(msg, 0, sizeof(message)+size); 00071 // //prepare a message 00072 // msg->sender=sender; 00073 // msg->flags=flags; 00074 // msg->size=size; 00075 // msg->time_stamp=Arch::x86::RTC::up_time; 00076 // //copy data 00077 // memmove(&msg[1], data, size); 00078 // 00079 // lock_mail.lock(); 00080 // //add to inbox 00081 // i=((*(blist_t*)&inbox).ptr(msg, NULL)==NULL? EFAIL:ESUCCESS); 00082 // if (i==EFAIL) {lock_mail.ulock(); 00083 // // asm volatile("popf\ncli"); 00084 // return EFAIL; } 00085 // //increase counter 00086 // mail++; 00087 // // asm volatile("pushf\ncli"); 00088 // //unblock the owner-thread of the mailbox 00089 // uu.i64=((Thread::thread_t*)thread)->sem_dt; 00090 // // write_bochs("(");write_bochs(thread->name);write_bochs("A)"); 00091 // if (((Thread::thread_t*)thread)->sem_id==&sem_mail) 00092 // if (( (mailbox*) uu.i32[1] == NULL) || 00093 // ( (mailbox*) uu.i32[1] == msg->sender)) 00094 // { Thread::sem_awake(thread); } 00095 // 00096 // lock_mail.ulock(); 00097 // // asm volatile("popf\ncli"); 00098 // 00099 // return i; 00100 // } 00101 // 00102 //free memory 00103 void mailbox::done() 00104 { 00105 lock_mail.lock(); 00106 sem_destroy(&sem_mail); 00107 ((blist_t*)&inbox)->done(); 00108 } 00109 // 00110 // int mailbox::ksend(mailbox *dest, void *data, size_t size, uint32 flags) { 00111 // return dest->new_mail(this, data, size, flags); 00112 // } 00113 // 00114 // int mailbox::kreceive(message **msg) 00115 // { 00116 // union 00117 // { 00118 // uint32 i32[2]; 00119 // uint64 i64; 00120 // } uu; 00121 // // asm volatile("pushf\ncli"); 00122 // *msg=NULL; 00123 // lock_mail.lock(); 00124 // //check for messages 00125 // if (inbox.head == NULL) 00126 // { 00127 // asm volatile("pushf\ncli"); 00128 // uu.i32[0]=(uint32)this; 00129 // uu.i32[1]=0; 00130 // lock_mail.ulock(); 00131 // Thread::sem_sleep( &sem_mail, uu.i64 ); 00132 // asm volatile("popf"); 00133 // } 00134 // //get and remove the oldest 00135 // *msg=bli_dt(inbox.head,message*); 00136 // (*(blist_t*)&inbox).del(inbox.head); 00137 // //decrease counter 00138 // mail--; 00139 // lock_mail.ulock(); 00140 // // asm volatile("popf"); 00141 // return ESUCCESS; 00142 // } 00143 // 00144 // int mailbox::kreceive(message **msg, mailbox *sender) 00145 // { 00146 // union 00147 // { 00148 // uint32 i32[2]; 00149 // uint64 i64; 00150 // } uu; 00151 // *msg=NULL; 00152 // blist_s *item; 00153 // //wait for messages 00154 // 00155 // do { 00156 // lock_mail.lock(); 00157 // for (item=inbox.head;item;item=item->next) 00158 // if (bli_dt(item,message*)->sender == sender) 00159 // { 00160 // //get and remove 00161 // *msg=bli_dt(item,message*); 00162 // (*(blist_t*)&inbox).del(item); 00163 // //decrease counter 00164 // mail--; 00165 // 00166 // lock_mail.ulock(); 00167 // return ESUCCESS; 00168 // } 00169 // 00170 // asm volatile("pushf\ncli"); 00171 // lock_mail.ulock(); 00172 // //no messages from that source? block 00173 // uu.i32[0]=(uint32)this; 00174 // uu.i32[1]=(uint32)sender; 00175 // Thread::sem_sleep( &sem_mail, uu.i64 ); 00176 // asm volatile("popf"); 00177 // } while(1); 00178 // 00179 // return ESUCCESS; 00180 // } 00181 // 00182 // //how many messages are waiting in the inbox 00183 // int mailbox::count() { 00184 // return mail; 00185 // } 00186 // 00187 // int mailbox::free_msg(message *msg) { 00188 // return heap->free(msg); 00189 // } 00190 00191 00192 }; /*namespace Message*/ 00193 }; /*namespace IPC*/ 00194 00195 00196 /*********************************************************** 00197 * * 00198 *panalix 0.06 (c) Adrian Panasiuk 2002-4 * 00199 *adek336[at]o2.pl, panalix.prv.pl * 00200 * * 00201 ***********************************************************/