00001
00002 #include "config.h"
00003 #include <sys/critsec.h>
00004 #include <critsec.h>
00005 #include <unistd.h>
00006
00007 #if defined(CONF_TM)
00008 #include <sys/tm.h>
00009 #include <tm.h>
00010
00012
00017 atomic_t kernel_critsec_count;
00018
00019 #if defined(CONF_CRITICAL_SECTIONS)
00020
00021
00032 int locked_check_and_increment(atomic_t* counter, tdata_t** tid);
00033 __asm__("\n\
00034 .text\n\
00035 .global _locked_check_and_increment\n\
00036 _locked_check_and_increment:\n\
00037 push.w r4\n\
00038 stc ccr, r4h\n\
00039 orc #0x80, ccr\n\
00040 mov.b @r0, r4l\n\
00041 beq lci_get_lock\n\
00042 \n\
00043 push.w r2\n\
00044 push.w r3\n\
00045 mov.w @_ctid, r2\n\
00046 mov.w @r1, r3\n\
00047 sub.w r3, r2\n\
00048 bne lci_cant_lock\n\
00049 \n\
00050 pop.w r3\n\
00051 pop.w r2\n\
00052 bra lci_get_lock\n\
00053 \n\
00054 lci_cant_lock:\n\
00055 pop.w r3\n\
00056 pop.w r2\n\
00057 mov.w #0xffff, r0\n\
00058 bra lci_done\n\
00059 \n\
00060 lci_get_lock:\n\
00061 inc r4l\n\
00062 mov.b r4l, @r0\n\
00063 mov.w @_ctid, r0 \n\
00064 mov.w r0, @r1 \n\
00065 sub.w r0, r0\n\
00066 \n\
00067 lci_done:\n\
00068 ldc r4h, ccr\n\
00069 pop.w r4\n\
00070 rts\n\
00071 ");
00072
00074
00078 wakeup_t wait_critical_section(wakeup_t data) {
00079 critsec_t* cs = (critsec_t*)((unsigned)data);
00080 if (locked_check_and_increment(&cs->count, &cs->task) == 0xffff)
00081 return 0;
00082 else
00083 return 1;
00084 }
00085
00087
00096 int enter_critical_section(critsec_t* cs) {
00097 if (locked_check_and_increment(&cs->count, &cs->task) == 0xffff)
00098 return wait_event(&wait_critical_section, (wakeup_t)((unsigned)cs));
00099 return 1;
00100 }
00101 #endif // CONF_CRITICAL_SECTIONS
00102 #endif // CONF_TM
00103