00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "src/common/shared.hpp"
00020 #include "src/common/string.hpp"
00021 #include "src/memory/memset.hpp"
00022 #include "src/thread/thread.hpp"
00023 #include "src/thread/scheduler.hpp"
00024 #include "src/arch/x86/rtc.hpp"
00025 #include "src/ipc/lock.hpp"
00026
00027 IPC::Lock::lock_t lock_system("system");
00028
00033 #define LOCK_SLEEP_STEP 70
00034 #define LOCK_SPIN_STEP 70
00035
00036
00037 #define LOCK_RETRIES 0x1000
00038 #define LOCK_RETRIES_WHEN_SLEEP 10
00039
00040 #define LOCKS_BY_CRITICAL_SECTION 1
00041
00044 namespace IPC {
00045 namespace Lock {
00046
00047 volatile bool disable_all_locks=false;
00048
00049
00050 lock_t::lock_t(const char *nam)
00051 {
00052 memset(name, 0, LOCK_NAME);
00053 memmove(name, const_cast<char*>(nam), ( lgth(const_cast<char*>(nam))<LOCK_NAME-1 ) ? lgth(const_cast<char*>(nam)) : LOCK_NAME-1 );
00054 state=FALSE;
00055 }
00056
00057 lock_t::lock_t() {
00058 state=false;
00059 }
00060
00061 void lock_t::init(const char *nam)
00062 {
00063 memset(&name, 0, LOCK_NAME);
00064 memmove(&name, nam, ( lgth(nam)<LOCK_NAME-1 ) ? lgth(nam) : LOCK_NAME-1 );
00065 state=FALSE;
00066 }
00067
00068
00069 bool lock_t::locked() {
00070 if (disable_all_locks) return false;
00071 return state;
00072 }
00073
00074
00075 void lock_t::lock(bool slp)
00076 {
00077 if (disable_all_locks)
00078 return ;
00079 bool ret;
00080 uint64 retries=0;
00081 uint32 fl;
00082 #if 0
00083 ENTER_CRITICAL(eflags);
00084 if (Arch::x86::Interr::isInInterruptHandler())
00085 if (name[0]!='t' || name[1]!='t'||name[2]!='y'||name[3]!='\0')
00086 {
00087 TTYDisableLock=true;
00088 cout(name);
00089 cout("\t");
00090 TTYDisableLock=false;
00091 }
00092 LEAVE_CRITICAL(eflags);
00093 #endif
00094
00095 ENTER_CRITICAL(eflags);
00096
00097 bool flag=false;
00098 do {
00099 asm volatile ("lock\nxchg (%%edx),%%ebx" :"=b"(ret) :"b"(true), "d"(&state));
00100
00101 if (Thread::Scheduler::multitasking_running == true)
00102 if (ret == TRUE) {
00103 asm volatile("sti");
00104 if (slp)
00105 Thread::sleep(LOCK_SLEEP_STEP);
00106 else {
00107 uint64 t= Arch::x86::RTC::up_time+(DEF_SECOND/1024)*LOCK_SPIN_STEP;
00108 while (Arch::x86::RTC::up_time < t) ;
00109 }
00110
00111 asm volatile("cli");
00112 }
00113
00114 if (retries++ == (slp ? LOCK_RETRIES_WHEN_SLEEP : LOCK_RETRIES))
00115 {
00116 asm volatile ("pushf\npopl %0\ncli":"=g"(fl));
00117 TTYDisableLock=true;
00118 alert(" lock ");
00119 bool state = disable_all_locks;
00121
00122 debug_dump_call_trace(eipebp.eip,eipebp.ebp);
00123 debug_dump_call_trace();
00124 flag=true;
00125 cout("caution: locked on ");
00126 cout( (char*)&name );
00127 cout("\n");
00128 TTYDisableLock=false;
00129 disable_all_locks=state;
00130 asm volatile("pushl %0\npopf"::"g"(fl));
00131 }
00132 } while (ret == TRUE) ;
00133 save_eip_ebp(eipebp);
00134
00135 if (flag==true) { cout("relocked on "); cout( (char*)&name); cout("\n"); }
00136
00137
00138
00139 #if LOCKS_BY_CRITICAL_SECTION
00140 #else
00141 LEAVE_CRITICAL(eflags);
00142 #endif
00143
00144 #ifdef LOCKS_BY_CRITICAL_SECTION
00145
00146 #endif
00147 }
00148
00149
00150 void lock_t::lock2() {
00151 lock(true);
00152 }
00153
00154
00155 void lock_t::lock() {
00156 lock(false);
00157 }
00158
00159
00160 void lock_t::ulock()
00161 {
00162 state=FALSE;
00163 #ifdef LOCKS_BY_CRITICAL_SECTION
00164 LEAVE_CRITICAL(eflags);
00165 #endif
00166 }
00167
00168
00169 };
00170 };
00171
00172
00173
00174
00175
00176
00177