]> rtime.felk.cvut.cz Git - lincan.git/commitdiff
Added missing indication CAN_ENDSF_MEM_RTL for RTL pool malloc.
authorppisa <ppisa>
Fri, 23 Jan 2004 04:18:30 +0000 (04:18 +0000)
committerppisa <ppisa>
Fri, 23 Jan 2004 04:18:30 +0000 (04:18 +0000)
This fixes serious bug in RTL LinCAN mode.
Some more small updates added.
The call canque_notify_bothends(edge,CANQUEUE_NOTIFY_NOUSR)
invoked without locks hold now.

lincan/include/can_queue.h
lincan/src/can_quekern.c
lincan/src/can_quertl.c
lincan/src/can_queue.c
lincan/src/open_rtl.c
lincan/utils/readburst_rtl.c
lincan/utils/sendburst_rtl.c

index b8cbb0989b7286a1006aa62e57c930e5ca48e8aa..8821dca02c488ea8fdc8d64af161f3879d8bd777 100644 (file)
@@ -547,8 +547,9 @@ void canque_edge_decref(struct canque_edge_t *edge)
        can_spin_lock(&outends->ends_lock);
        if(atomic_dec_and_test(&edge->edge_used)) {
                dead_fl=canque_fifo_test_and_set_fl(&edge->fifo,DEAD);
-               /*This should not be there, but it cannot be outside of the lock :-(*/
-               canque_notify_bothends(edge,CANQUEUE_NOTIFY_NOUSR);
+               /* Because of former evolution of edge references 
+                  management notify of CANQUEUE_NOTIFY_NOUSR could
+                  be moved to canque_edge_do_dead :-) */
                can_spin_unlock(&outends->ends_lock);
                can_spin_unlock_irqrestore(&inends->ends_lock, flags);
                canque_edge_do_dead(edge, dead_fl);
index 093886c2c41e01e9dfb0cdd5727a8aba993e626d..5089e5cbc2c8aec6cbc9ad95d51385c4afd65ff3 100644 (file)
 extern atomic_t edge_num_cnt;
 
 #ifdef CAN_DEBUG
-       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_queue (debug): " fmt,\
+       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_quekern (debug): " fmt,\
        ##args)
 
 #else
        #define DEBUGQUE(fmt,args...)
 #endif
 
-#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_queue: " fmt,\
+#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_quekern: " fmt,\
        ##args)
 
 
@@ -128,6 +128,27 @@ void canque_edge_do_dead(struct canque_edge_t *edge, int dead_fl)
        
        if(dead_fl) return;
        
+       canque_notify_bothends(edge,CANQUEUE_NOTIFY_NOUSR);
+    #ifdef CAN_WITH_RTL
+       /* The problem of the above call is, that in RT-Linux to Linux notify
+          case is edge scheduled for delayed notify delivery, this needs
+          to be reflected there */
+       if(atomic_read(&edge->edge_used)>0){
+               can_spin_lock_irqsave(&edge->inends->ends_lock, flags);
+               can_spin_lock(&edge->outends->ends_lock);
+               if(atomic_read(&edge->edge_used)>0){
+                       /* left edge to live for a while, banshee comes again in a while */
+                       canque_fifo_clear_fl(&edge->fifo,DEAD);
+                       can_spin_unlock(&edge->outends->ends_lock);
+                       can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+                       can_printk(KERN_ERR "can_quertl (debug): canque_edge_do_dead postponed\n");
+                       return;
+               }
+               can_spin_unlock(&edge->outends->ends_lock);
+               can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+       }
+    #endif /*CAN_WITH_RTL*/
+       
        if(canqueue_disconnect_edge(edge)<0){
                ERRMSGQUE("canque_edge_do_dead: canqueue_disconnect_edge failed !!!\n");
                return;
index 0a6fa40d38c90e4a5520161cb84d2542eeb08af5..dc59f8ebf958c1a23d428d703ed8b0347989c0aa 100644 (file)
@@ -374,6 +374,7 @@ int canqueue_ends_init_rtl(struct canque_ends_t *qends)
        rtl_wait_init(&(qends->endinfo.rtlinfo.rtl_emptyq));
        
        qends->notify=canqueue_notify_rtl;
+       qends->endinfo.rtlinfo.pend_flags=0;
        return 0;
 }
 
index 96c37a4acb9a3d44581f2269908ed20b8a56dc9f..f061f4f177017ffd03e191e2768b388338e5de36 100644 (file)
@@ -477,6 +477,7 @@ int canque_flush(struct canque_edge_t *qedge)
 int canqueue_ends_init_gen(struct canque_ends_t *qends)
 {
        int i;
+       qends->ends_flags=0;
        for(i=CANQUEUE_PRIO_NR;--i>=0;){
                INIT_LIST_HEAD(&qends->active[i]);
        }
index 230e3eb1fe46dc40356ceef96d468ee769c3eebd..2730ee3a45471238671db3e982d331d2141686f8 100644 (file)
@@ -52,6 +52,8 @@ int can_open_rtl_common(struct canuser_t *canuser, int open_flags)
        qends = (struct canque_ends_t *)rt_malloc(sizeof(struct canque_ends_t));
        if(qends == NULL) goto no_qends;
        canqueue_ends_init_rtl(qends);
+       /* mark memory as allocated from RTL memory pool */
+       qends->ends_flags|=CAN_ENDSF_MEM_RTL;
        canuser->qends = qends;
        
        can_spin_lock_irqsave(&canuser_manipulation_lock, iflags);
index 9f03cbf635186c020a374b234e9c3f7f9d8b119f..afb0eed6d18e5b3fdefce58442e275393a538f31 100644 (file)
@@ -124,6 +124,8 @@ int readburst_main(void *arg)
                        printf("\n");
                        i++;
                }
+               pthread_testcancel();
+
        }
        /* close(fd); is called by cleanup handler*/
         pthread_cleanup_pop(1);
@@ -154,4 +156,7 @@ int init_module(void) {
 
 void cleanup_module(void) {
         pthread_delete_np (t1);
+       
+       /*pthread_cancel(t1);
+       pthread_join(t1, NULL);*/
 }
index 45a69fd16b9627f9585522e85a77b3582d14cfad..94a3e0480a79a61fe8c2dc267e874d178f1d6716 100644 (file)
@@ -115,5 +115,8 @@ int init_module(void) {
 }
 
 void cleanup_module(void) {
-        pthread_delete_np (t1);
+        /*pthread_delete_np (t1);*/
+       
+       pthread_cancel(t1);
+       pthread_join(t1, NULL);
 }