Hi all,

rt_task_ipc_init doesn't initialise task->mq_at only task->sem_at.

This causes trouble when the task is an automatic variable, since it
then isn't set to zero. I know that this is normally a don't do that
situation but I've got a good reason for wanting it to be automatic, and
the lifetime of the task variable is as long as the lifetime of the task
itself.

I've attached the code triggering this problem since it might be usefull
for others, it allows one to run long rtl-thread blocking functions like
sem_read from the linux thread, by running them in a seperate thread,
answering a question of mine from some time ago.

I've also attached a fix for the problem for rtlinux-2.2 (initialise the
darn thing in rt_task_ipc_init.

Regards,

Hans
--- rtlinux-2.2/semaphores/rt_ipc.c.hdg Wed Feb 23 23:07:24 2000
+++ rtlinux-2.2/semaphores/rt_ipc.c     Fri Nov 24 15:27:56 2000
@@ -289,7 +289,8 @@
   /* initially task is not blocked on a semaphore */
   int ret;
   task->sem_at = NULL;
-  task->magic = RT_TASK_IPC_MAGIC;
+  task->mq_at  = NULL;
+  task->magic  = RT_TASK_IPC_MAGIC;
   ret = rt_task_init(MAKE_RT_TASK(task), fn, data, stack_size, priority);
   if (ret < 0) {
          return ret;
@@ -341,7 +342,7 @@
 {
   int ret = 0;
   int flags;
-         rtl_critical(flags);
+  rtl_critical(flags);
   /* mark the task as delayed */
   pthread_self()->resume_time = duration;
   pthread_self()->period = 0;
/* Function to execute a blocking int(int) function from the Linux-kerneltask
   under an RT-Linux task, so that it doesn't hang the entire Linux-kerneltask

   Copyright 2000 RADAC, Hans de Goede

   This file and the acompanying files unblock.h, error.c, error.h,
   begin_code.h and end_code.h are free software; you can redistribute
   them and/or modify them under the terms of the
   GNU Library General Public License as published by the
   Free Software Foundation; either version 2 of the License,
   or (at your option) any later version.

   These files are distributed in the hope that they will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with these files; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/
/* Changelog
Version 0.1, November 2000
-initial release (Hans de Goede)
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <rt_ipc.h>
#include "error.h"
#include "unblock.h"

struct unblock_task_args
{
   int ready;
   int arg;
   int res;
   int (*func)(int data);
};

static void unblock_task_fn(int data);

int unblock(int (*func)(int data), int arg)
{
   int res;
   RT_TASK_IPC unblock_task;
   struct unblock_task_args args;
   
   unblock_task.mq_at = NULL;
   
   args.ready = 0;
   args.arg   = arg;
   args.func  = func;
   
   res = rt_task_ipc_init(&unblock_task, unblock_task_fn, (int)&args,
      16384, sched_get_priority_max(0));
   if(res)
      ERROR(ERR_SYS, -res, 0)
   
   res = rt_task_make_periodic(MAKE_RT_TASK(&unblock_task), rt_get_time(), 0);
   if(res)
      ERROR(ERR_SYS, -res, 0)
   
   while(!args.ready)
   {
      current->state = TASK_UNINTERRUPTIBLE;
      schedule_timeout(1); /* sleep 1 tick */
   }
   res = rt_task_ipc_delete(&unblock_task);
   if(res)
      ERROR(ERR_SYS, -res, 0)
      
   return args.res;
}

static void unblock_task_fn(int data)
{
   /* ugly and only works on 32 bits machines, but its better then nothing */
   struct unblock_task_args *args = (struct unblock_task_args *) data;
   
   args->res = args->func(args->arg);
   args->ready = 1;
}

int init_module(void)
{
   ERR_LOG(ERR_INFO, ERR_SYS,
      ("sys: info: RTLinux unblock module; (C) 2000 RADAC & Hans de Goede; build %s %s 
- installed\n",
      __DATE__, __TIME__))
      
   return 0;
}

void cleanup_module(void)
{
   ERR_LOG(ERR_INFO, ERR_SYS,
      ("sys: info: RTLinux unblock module; removed\n"))
}
/* RTL unblock test module

   Copyright 2000 RADAC, Hans de Goede

   This file and the acompanying files error.c, error.h, unblock.c, unblock.h,
   begin_code.h and end_code.h are free software; you can redistribute
   them and/or modify them under the terms of the
   GNU Library General Public License as published by the
   Free Software Foundation; either version 2 of the License,
   or (at your option) any later version.

   These files are distributed in the hope that they will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with these files; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/
/* Changelog
Version 0.1, November 2000
-initial release (Hans de Goede)
*/
#include <linux/module.h>
#include <rtl_core.h>
#include <rt_ipc.h>
#include "unblock.h"

static int blocking_func(int data)
{
   rtl_printf("sleeping (blocking) for 5 seconds\n");
   rt_task_delay(RELATIVE_TIME(RT_TICKS_PER_SEC * 5));
   rtl_printf("done arg = %d\n", data);
   
   return 135;
}

int init_module(void)
{
   int retval;
   
   printk("RTLinux unblock demo module; (C) 2000 RADAC & Hans de Goede; build %s %s - 
installed\n",
      __DATE__, __TIME__);
   printk("running unblock(blocking_func, 2468)\n");

   retval = unblock(blocking_func, 2468);

   printk("retval = %d\n", retval);
   
   return 0;
}

void cleanup_module(void)
{
   printk("RTLinux unblock demo module - removed\n");
}

Reply via email to