Best way for start a rt-thread and wait

Giampaolo Bellini <[email protected]> 27 Jan 2005 09:47:43 +0100
Newsgroups gmane.linux.real-time.rtlinux.general
Organization DS4 Laser Technology
Message-ID <1106815662.2943.61.camel@Giampaolo>
Hi all...


 I need to start a rt-thread from user space, wait for the rt-thread to
complete his job and return a result in user space...

 in order to do this, I've created a rt-fifo and linked the user space
ioctl with the rtf_link_user_ioctl() function.

the problem is that sometimes my ioctl code put the user process to
sleep and never wake it up.

is there a best way to achieve this kind of functionality ?



thanks in advance



     Giampaolo


//--------------------------------------------------------------------------------------------------//

int BTN_Init(void)

{
   int result;
   
   rtl_printf("\nDS4: BTN Initializing module %s\n",	BTNVERSION);
 
   rtf_destroy(BTN_FIFON);

   if (rtf_create(BTN_FIFON, BTN_FIFOLEN)){
      rtl_printf("DS4: BTN Error making fifo...\n");
      return -ENODEV;
      }
      
   result = rtf_link_user_ioctl(BTN_FIFON, BTN_Ioctl);
   
   if (result!=0){   
      rtl_printf("DS4: BTN Error linking btn fifo to ioctl...\n");   
      rtf_destroy(BTN_FIFON);
      return -ENODEV;
      }

   return 0;
}

//--------------------------------------------------------------------------------------------------//

void BTN_Cleanup(void)

{
   rtf_link_user_ioctl(BTN_FIFON, NULL);
   
   rtf_destroy(BTN_FIFON);
     
   rtl_printf("DS4: BTN module removed from kernel\n");
}

//--------------------------------------------------------------------------------------------------//

static int BTN_Ioctl(unsigned int fifo, unsigned int cmd, unsigned long
arg)

{
   int ret=0;
   
   if (_IOC_TYPE(cmd) != BTN_IOC_MAGIC) return -ENOTTY;
   if (_IOC_NR(cmd) > BTN_IOC_MAXNR) return -ENOTTY;
   
   switch(cmd) {
       
// ---------------------
    case BTN_IOCACQUIRE:
// ---------------------
         
         if (ds4_shrt.phase != HRTIDLE) return -ERESTARTSYS;
    
         if (ds4_debug>=LINFO) rtl_printf("DS4: BTN Wakingup HRT
RT-thread\n");
         pthread_kill(threadBTN, RTL_SIGNAL_WAKEUP);      
         
         if (ds4_debug>=LINFO) rtl_printf("DS4: BTN Calling process %i
(%s) may sleep\n", current->pid, current->comm);

         if (wait_event_interruptible(btnwq, (ds4_shrt.phase ==
HRTCOMPLETE))){
            if (ds4_debug>=LINFO) rtl_printf("DS4: BTN wait loop
interrupted by a signal\n");
            ds4_shrt.phase = HRTIDLE;
            return -ERESTARTSYS;
            }
                       
         if (ds4_debug>=LINFO) rtl_printf("DS4: BTN Awoken process %i
(%s)\n", current->pid, current->comm);
         
         if (copy_to_user((char *)arg, &sbtnout, sizeof(struct
_sbtnoparms)) != 0){
            if (ds4_debug>=LERROR) rtl_printf("DS4: BTN Can't copy data
to user space\n");
            ds4_shrt.phase = HRTIDLE; // Torno in modalità IDLE   
            return -EFAULT;
            }
      
         ds4_shrt.phase = HRTIDLE;
                     
         break;

// ---------
    default:
// ---------

         if (ds4_debug>=LERROR) rtl_printf("DS4: BTN Unknow command
requested\n");
         ret = -EFAULT;
         break;
    }
       
   return ret;
}

//--------------------------------------------------------------------------------------------------//

void *BTN_ThreadRT(void *arg)

{
   if (pthread_make_periodic_np(pthread_self(), gethrtime(),
DS4_HRTSCHED*1000)){
      rtl_printf("DS4: HRT Error scheduling thread\n");
      threadHRT=NULL;
      return 0;  
      }

   ds4_shrt.phase=HRTIDLE;
         
   while(1){      
         
      pthread_suspend_np(pthread_self());

      ds4_shrt.phase=HRTFIELD0;
                  
      rtl_printf("\nDS4: HRT Starting RT thread\n");
                       
      do {
         pthread_wait_np();
         
         ...some job that chage the value of the ds4_shrt.phase
         
         if ((ds4_shrt.phase==HRTFIELD2) break;
                  
         } while(1);

      ds4_shrt.phase=HRTCOMPLETE;
      }
        
   return 0;
}


_______________________________________________
Rtl mailing list
[email protected]
http://www2.fsmlabs.com/mailman/listinfo/rtl