l4-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Developing L4 server under L4-Linux


From: Farid Hajji
Subject: Re: Developing L4 server under L4-Linux
Date: Thu, 23 Nov 2000 23:36:53 +0100

[Cc-ed to address@hidden

> Please follow the step below:
> 
> 1 backup /usr/include/asm /usr/include/asm.orig
> 2. cp -a /somewhere/linux22/include/asm-l4 /usr/include/asm
> 3. cp -a /somewhere/linux22/include/l4linux /usr/include/l4linux
> 4. edit test.c
Okay, I'll try this once I have a Linux system available. For the time
being, I've used the L4Ka root_task as a simple skeleton to get started.

 1. unpack l4-ka somewhere
 2. cd l4-ka/apps
 3. ln -s template root_task
 4. cd root_task
 5. Fix LINKBASE in Makefile to something sensible, e.g. 0x00e20000
 6. edit main.c hello-world example
 7. recompile root_task and put it on your boot floppy.

> - ------8<-----------------
> example:
> 
> #define CONFIG_L4_VX0 
> #include <asm/l4.h>
           ^^^^^^^^^^
This may work under L4Linux environment, but <asm/*> is not standard
and inherently non-portable.

BTW, which L4 protocol should we use? X0?

Typical headers in L4Ka root tasks are:

#include <l4/l4.h>
#include <l4io.h>
#include <l4/helpers.h>

> main(){
>   l4_threadid_t my;                                                           
>   
>   my=l4_myself();
> 
>   printf("thread id: %x\n", my);
> 
> }
Yes, that should work.

If you write a root_task, you should probably add an endless loop
before leaving main. As a L4 server under L4Linux, this is not
necessary (of course).

> - ----->8------------------
> 
> 5. gcc -o test test.c
> 6. /test.c
> 
> You will see the value return by l4_myself() (0x52a0028 here). I will test
> more function later. :-)

Good work!

Here's one of my root_tasks for L4Ka:

/* root_task/main.c -- a sample root task for L4ka */
/* Copyright (C) 2000/11/03 Farid Hajji <address@hidden> */
/* $Id: main.c,v 1.2 2000/11/03 15:40:16 farid Exp $ */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

/*
 * $Log: main.c,v $
 * Revision 1.2  2000/11/03 15:40:16  farid
 * * added getc() call to main control thread.
 * * added suspend/resume logic to main control thread.
 * * added suspend/resume functions (currently fiddling with priority).
 *
 * Revision 1.1  2000/11/03 14:09:54  farid
 * Initial revision
 *
 */

/*
 * Sample root task for L4Ka.
 *
 * This program activates a few threads and then enters an endless loop.
 * Each thread prints its own characterizing char ('a' for lthread 1, 'b'
 * for lthread 2 etc...) continuouusly in an endless loop.
 * The main thread getc() chars and toggles the corresponding thread
 * on or off.
 *
 * Available keystrokes:
 *  'a' thru MAXTHREAD ('f'): toggles corresponding thread on/off
 *  '1'                     : shows thread status (stopped/active)
 *
 * CAVEAT:
 *  suspend_thread(), resume_thread() are currently implemented by
 *  setting the scheduling priority of threads. Suspending threads
 *  is currently done by lowering their priority to 10, resuming them
 *  by raising their priority to 200. This should be changed!
 */

#include <l4/l4.h>
#include <l4io.h>
#include <l4/helpers.h>

void clear_screen(void);            /* empties the output screen */
void print_me(void);                /* thread entry point, prints is char */
void suspend_thread(int lthread);   /* suspend this thread */
void resume_thread(int lthread);    /* resume this thread  */

#define MAXTHREAD 'f'

int main(void)
{
  l4_threadid_t myself, mypager;      /* our own thread-id and our pager */
  char c;                             /* thread counter */
  char local_stack_ptr[26][1024];     /* stacks for 26 threads a 1024 bytes */
  char thread_active_p[26];           /* '0' if thead inactive, '1' else    */

  for (c='a'; c<='z'; ++c)
    thread_active_p[c-'a'] = '0';     /* threads are inactive first */

  /*
   * A note about locate_stack_ptr and thread_active_p:
   *   lthread 0 (our control thread) is _not_ listed there.
   *   locate_stack_ptr[0] and thread_active_p[0] correspond
   *      to lthread 1 (a.k.a. thread 'a')!
   */

  clear_screen();

  printf("%s: started\n", __FUNCTION__);

  myself = l4_myself();
  printf("%s: l4_myself() yields: %x\n", __FUNCTION__, myself);

  mypager = get_current_pager(myself);
  printf("%s: get_current_pager(%x) yields %x\n",
         __FUNCTION__, myself, mypager);

  /*
   * generate a few threads, numbered from 1 to n:
   *   We identify each thread with a char: 'a' is lthread1, 'b' lthread 2...
   *   Each lthread c-'a' gets its own stack local_stack_ptr[c-'a'].
   *   Each lthread c-'a' uses our default pager.
   * create_thread() is in <l4/helpers.h>
   */
  for (c='a'; c<=MAXTHREAD; c++) {
    create_thread((int)(c-'a')+1,                   /* first thread-id: 1 */
                  &print_me,                        /* thread entry point */
                  &local_stack_ptr[c-'a'][1024-8],  /* stack grows down!  */
                  mypager);                         /* same pager for all */
    thread_active_p[c-'a'] = '1';                   /* mark thread active */
  }

  /*
   * The main thread enters an endless loop
   * where it continuusly reads user input via primitive getc()
   * and if a valid number between 'a' and MAXTHREAD is entered,
   * that thread is toggled on or off.
   * NYI: currently only test of getc()
   */
  printf("%s: entering endless loop. reboot me!\n");
  for (;;) {
    c = getc();    /* int getc(void) defined in l4io.h */
    if (c >= 'a' && c <= MAXTHREAD)
      if (thread_active_p[c-'a'] == '1') {
        thread_active_p[c-'a'] = '0';
        suspend_thread(c-'a'+1);
      } else {
        thread_active_p[c-'a'] = '1';
        resume_thread(c-'a'+1);
      }
    else 
      switch(c) {
        int c1;
      case '1':
        for (c1='a'; c1<= MAXTHREAD; ++c1)
          printf("Thread %d is %s\n",
                 c1-'a'+1,
                 thread_active_p[c1-'a'] == '1' ? "active" : "stopped");
        break;
      default:
        printf("Key (%c) unknown\n", c);
      }
  }
}

void clear_screen() {
  /* clear up the output screen by outputting empty lines */
  int line;
  for (line=0; line<12; ++line)
    printf("                                        "
           "                                       \n");
}

/*
 * thread entry point: each thread prints a char that corresponds
 * to its lthread-id: thread-id 1 prints 'a', thread-id 2 prints 'b'...
 *
 * WARNING: No synchronization is performed while accessing the screen
 * memory with printf()! On a PC, each position in screen memory is a
 * byte pair (data,attribute) that are written to by putc(). If printf()
 * is not thread-safe, strange results could occur here!
 */
void print_me(void) {
  l4_threadid_t myself;

  myself = l4_myself();

  for (;;) {
    printf("%c", (char)(myself.id.thread)+'a'-1);
    l4_sleep(50); /* time to sleep in usecs. could be random as well */
  }
}

/*
 * suspend_thread() lowers the priority of lthread, thus effectively
 * suspending it against other threads with higher priority.
 * Note: in L4 thread-queue prio 200 is scheduled before prio 10.
 * XXX we'd better implement suspend/resume another way (NYI)! XXX
 */
void suspend_thread(int lthread) {
  l4_threadid_t tid;

  tid = l4_myself();        /* get version,control-thread,mytask,mychief */
  tid.id.thread = lthread;  /* override thread to lthread */
  l4_set_prio(tid,  10);    /* l4_set_prio(tid, prio) in <l4/helpers.h> */

  printf("Thread %d suspended (NYI)\n", lthread);
}

/*
 * resume_thread() raises the priority of lthread, thus effectively
 * resuming it if it was suspended before.
 * Note: in L4 thread-queue in prio 200 is scheduled before prio 10.
 * XXX we'd better implement suspend/resume another way (NYI)! XXX
 */
void resume_thread(int lthread) {
  l4_threadid_t tid;

  tid = l4_myself();        /* get version,control-thread,mytask,mychief */
  tid.id.thread = lthread;  /* override thread to lthread */
  l4_set_prio(tid, 200);    /* l4_set_prio(tid, prio) in <l4/helpers.h> */

  printf("Thread %d resumed (NYI)\n", lthread);
}


-- 
Farid Hajji -- Unix Systems and Network Admin | Phone: +49-2131-67-555
Broicherdorfstr. 83, D-41564 Kaarst, Germany  | address@hidden
- - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - -
Murphy's Law fails only when you try to demonstrate it, and thus succeeds.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]