SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2004 David Decotigny
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007    
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012    
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA. 
017 */
018 
019 #include <sos/errno.h>
020 #include <sos/klibc.h>
021 #include <sos/assert.h>
022 #include <sos/list.h>
023 
024 #include "sched.h"
025 
026 
027 /**
028  * The definition of the scheduler queue. We could have used a normal
029  * kwaitq here, it would have had the same properties. But, in the
030  * definitive version (O(1) scheduler), the structure has to be a bit
031  * more complicated. So, in order to keep the changes as small as
032  * possible between this version and the definitive one, we don't use
033  * kwaitq here.
034  */
035 static struct
036 {
037   unsigned int nr_threads;
038   struct sos_thread *thread_list;
039 } ready_queue;
040 
041 
042 sos_ret_t sos_sched_subsystem_setup()
043 {
044   memset(& ready_queue, 0x0, sizeof(ready_queue));
045 
046   return SOS_OK;
047 }
048 
049 
050 /**
051  * Helper function to add a thread in a ready queue AND to change the
052  * state of the given thread to "READY".
053  *
054  * @param insert_at_tail TRUE to tell to add the thread at the end of
055  * the ready list. Otherwise it is added at the head of it.
056  */
057 static sos_ret_t add_in_ready_queue(struct sos_thread *thr,
058                                     sos_bool_t insert_at_tail)
059 {
060 
061   SOS_ASSERT_FATAL( (SOS_THR_CREATED == thr->state)
062                     || (SOS_THR_RUNNING == thr->state) /* Yield */
063                     || (SOS_THR_BLOCKED == thr->state) );
064 
065   /* Add the thread to the CPU queue */
066   if (insert_at_tail)
067     list_add_tail_named(ready_queue.thread_list, thr,
068                         ready.rdy_prev, ready.rdy_next);
069   else
070     list_add_head_named(ready_queue.thread_list, thr,
071                         ready.rdy_prev, ready.rdy_next);
072   ready_queue.nr_threads ++;
073 
074   /* Ok, thread is now really ready to be (re)started */
075   thr->state = SOS_THR_READY;
076 
077   return SOS_OK;
078 }
079 
080 
081 sos_ret_t sos_sched_set_ready(struct sos_thread *thr)
082 {
083   sos_ret_t retval;
084 
085   /* Don't do anything for already ready threads */
086   if (SOS_THR_READY == thr->state)
087     return SOS_OK;
088 
089   /* Real-time thread: schedule it for the present turn */
090   retval = add_in_ready_queue(thr, TRUE);
091 
092   return retval;
093 }
094 
095 
096 struct sos_thread * sos_reschedule(struct sos_thread *current_thread,
097                                    sos_bool_t do_yield)
098 {
099 
100   if (SOS_THR_ZOMBIE == current_thread->state)
101     {
102       /* Don't think of returning to this thread since it is
103          terminated */
104       /* Nop */
105     }
106   else if (SOS_THR_BLOCKED != current_thread->state)
107     {
108       /* Take into account the current executing thread unless it is
109          marked blocked */
110       if (do_yield)
111         /* Ok, reserve it for next turn */
112         add_in_ready_queue(current_thread, TRUE);
113       else
114         /* Put it at the head of the active list */
115         add_in_ready_queue(current_thread, FALSE);
116     }
117 
118   /* The next thread is that at the head of the ready list */
119   if (ready_queue.nr_threads > 0)
120     {
121       struct sos_thread *next_thr;
122 
123       /* Queue is not empty: take the thread at its head */
124       next_thr = list_pop_head_named(ready_queue.thread_list,
125                                      ready.rdy_prev, ready.rdy_next);
126       ready_queue.nr_threads --;
127 
128       return next_thr;
129     }
130 
131   SOS_FATAL_ERROR("No kernel thread ready ?!");
132   return NULL;
133 }

source navigation ] diff markup ] identifier search ] general search ]