1 / 51

Vorlesung Echtzeitbetriebssysteme V.

Vorlesung Echtzeitbetriebssysteme V. Dr.-Ing. Frank Golatowski. Ziele der Vorlesung. Überblick verschaffen, welche Spezifikation der POSIX-Standard umfasst. Einordnung der Standards 1003.1a bis c. POSIX-Profile kennen lernen. API-Funktionalität vorstellen. Gliederung. POSIX Standards.

oakes
Télécharger la présentation

Vorlesung Echtzeitbetriebssysteme V.

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. VorlesungEchtzeitbetriebssysteme V. Dr.-Ing. Frank Golatowski

  2. Ziele der Vorlesung • Überblick verschaffen, welche Spezifikation der POSIX-Standard umfasst. • Einordnung der Standards 1003.1a bis c. • POSIX-Profile kennen lernen. • API-Funktionalität vorstellen.

  3. Gliederung

  4. POSIX Standards • Portable Operating System Interface (into a uniX like kernel) • Familie von Standards • Entwickelt durch die IEEE und • IEEE: The Institute of Electrical and Electronics Engineers • Adopted by ISO/IEC • ISO: International Organization for Standardization • IEC: International Electrotechnical Commission • Naming convention • POSIX.x • POSIX-Part x • IEEE Std 1003.x-yyyy yyyy • P1003.x -yyyy yyyy • ISO/IEC 9945-x: yyyy yyyy Eagleeye: Behörden in den USA verlangen bei Rechnerkauf, dass die Software eine POSIX-Schnittstelle hat -> Aus diesem Grund gibt es das Posix-Sub-System unter Windows

  5. POSIX Komponenten • POSIX-Part 1: System Application Program Interface • POSIX.1, POSIX.1b, POSIX.1c, and etc. • POSIX-Part 2: Shell and Utilities • POSIX.2, POSIX.2a, POSIX.21, and etc. • POSIX-Part 3: System Administration • Under development • P1003.5-1992 • Ada Language Interfaces: Binding for System API • P1003.13-1998 • Realtime System Profile

  6. POSIX Teil 1

  7. POSIX-Teil 1: System Application Program Interface • POSIX.1 (1990) • POSIX.1b (1993) (called POSIX.4 under developing process) • Echtzeit- Erweiterungen • POSIX.1i (1995) • Technische Berichtigungen zu den Echtzeit- Erweiterungen • POSIX.1c (1995) (called POSIX.4a under developing process) • Thread (Pthreads) • ISO/IEC 9945-1: 1996 (IEEE Std 1003.1-1996) • POSIX.1 + POSIX.1b + POSIX.1c + POSIX.1i • POSIX.1d (1999) • Zusätzliche Echtzeit- Erweiterungen • POSIX.1j (2000) • Ergänzungen zu den Echtzeit- Erweiterungen

  8. IEEE Std 1003.1-1996 • Process Primitives • Process creation/termination, signals • Process Environment • Files and Directories • Input and Output Primitives • Language-Specific Services for the C Programming Language • Libc library • Synchronization • semaphore, mutex, and condition variable

  9. IEEE Std 1003.1-1996 • Memory Management • Execution Scheduling • Fixed priority scheduling • Clocks and Timers • Message Passing • Thread Management / Thread-Specific Data / Thread Cancellation

  10. POSIX.1b (Realtime Extension) Service Flag Bemerkungen Real-time Signal _POSIX_REALTIME_SIGNALS sigwait() (synchronous signal) sigqueue() signotify Input und Output Primitiven _POSIX_SYNCHRONIZED _IO _POSIX_FSYNC _POSIX_AYNCHRONOUS _POSIX_PRIORIZED_IO Synchronisation _POSIX_SEMAPHORES Benannte und memory-based Semaphore Memory Management _POSIX_MEMLOCK _POSIX_MEMLOCK_RANGE _POSIX_MEMORY_PROTECTION_POSIX_MAPPED_FILES _POSIX_SHARED_MEMORY_OBJECTS Scheduling _POSIX_PRIORITY_SCHEDULING SCHED_FIFO SCHED_RR SCHED_OTHER Clocks und Timers _POSIX_TIMERS One shot und periodische Timer, nanosleep() Message Passing _POSIX_MESSAGE_PASSING Message queue Message notification

  11. POSIX.1c (Posix Threads) Synchronisation _POSIX_THREADS _POSIX_THREAD_PROCESS_SHARED Mutex Condition Variable Scheduling _POSIX_THREADPRIORITY_ SCHEDULING _POSIX_THREADPRIO_INHERIT _POSIX_THREAD_PRIO_PROTECT Thread Managment _POSIX_THREADS _POSIX_THREADS_ATTR_STACKADR _POSIX_THREADS_ATTR_STACKSIZE Thread: create, exit, join, detach, etc. Thread Specific Data _POSIX_THREADS Thread Cancellation _POSIX_THREADS Multi-thread Safeness _POSIX_THREADS_SAFE_FUNCTIONS

  12. P1003.13

  13. P1003.13-1998Realtime System Profiles • Originaltitel • Standardized Application Environment Profile POSIX Realtime Application Support (AEP) • Gegenstand sind Eigenschaften verschiedener kommerziell erfolgreicher Realtime-Kerne • pSOS, VRTX32, and VxWorks • Abkürzung • PSE: Generic (System) Environment Profiles • PSE5: Realtime Environments • PSE51: Minimal Realtime System Profile • PSE52: Realtime Controller System Profile • PSE53: Dedicated Realtime System Profile • PSE54: Multi-Purpose Realtime System Profile

  14. Realtime System Profile(PSE51) • System Modell • Systeme, die bestimmt sind für die unbeaufsichtigte Steuerung eines oder mehrerer I/O Geräte. • Keine Interaktion mit Nutzer. Kein Filesystem. • Programmiermodell • Ein einzelner POSIX Prozess enthält ein oder mehrere Threads (threads of control (POSIX.1c threads)). • Spezielle Geräte werden mittels memory mapped I/O oder I/O mapped gesteuert • Hardwaremodell • Ein einzelner Prozessor mit Speicher, aber ohne MMU oder andere übliche I/O-Geräte. • Wenn es mehrere Prozessoren gibt, • mehrere Instanzen des Betriebssystems, die über shared memory oder einem Rückwandbus (backplane channel) kommunizieren

  15. Realtime Controller System Profile(PSE52) • System / Programmiermodell • Erweiterung zu PSE51 • Unterstützung für Dateisystem und asynchrone (nicht blockierende) I/O Interfaces • Hardware Modell • ein Prozessor und Speicher (MMU ist nicht erforderlich). • Keine Massenspeicher erforderlich • Das Dateisystem kann im Speicher (RAM Disk) implementiert sein.

  16. Dedicated Realtime System Profile (PSE53) • System / Programmiermodell • Erweiterung zu PSE51 • Unterstützung mehrerer Prozesse • Einheitliches Interface für Gerätetreiber und Files, aber kein hierachisches Datei system • Memory locking • Hardwaremodell • Ein oder mehrere Prozessoren mit oder ohne MMUs im selben System

  17. Multi-Purpose Realtime System Profile(PSE54) • System / Programmiermodell • Das System unterstützt einen Mix aus real-time and non-real-time Tasks und einigen interaktiven Usertasks • Umfassende Funktionalität • Alles aus POSIX.1, POSIX.1b, und POSIX.1c • Interaktive Sessions (alles aus POSIX.2 und POSIX.2a) • Multi-tasking kann mittels Threads (POSIX.1c threads), Prozessen oder beidem durchgeführt werden. • Unterstützung für „multi-threaded“ Prozesse • Hardwaremodell • Ein oder mehrere Prozessoren mit MMU (memory management units), schnelle Massenspeichern, speziellen Interfaces, Netzwerkunterstützung und Anzeigegeräten (display devices).

  18. POSIX.1 Requirements PSE51 PSE52 PSE53 PSE54 POSIX_SINGLE_PROCESS X X X X POSIX_MULTI_PROCESS - - X X POSIX_SIGNALS X X X X POSIX_USER_GROUPS - - - X POSIX_FILE_SYSTEM - X - X POSIX_FILE_ATTRIBUTES - - - X POSIX_FIFO - - - X POSIX_DEVICE_IO X X X X POSIX_FD_MGMT - X X X POSIX_PIPE - - X X POSIX_DEVICE_SPECIFIC - - - X POSIX_SYSTEM_DATABASE - - - X POSIX_C_LANG_SUPPORT X X X X POSIX_ADA_LANG_SUPPORT X X X X PSE51 PSE52 PSE53 PSE54 _POSIX_JOB_CONTROL X - - X _POSIX_SAVED_IDS - - - X _POSIX_CHOWN_RESTRICTED - - - X _POSIX_NO_TRUNC X X X X _POSIX_VDISABLE - - - X NGROUPS_MAX - - - >=8

  19. POSIX.1b Requirements PSE51 PSE52 PSE53 PSE54 _POSIX_FSYNC X X X X _POSIX_MAPPED_FILES - X - X _POSIX_MEMLOCK X X X X _POSIX_MEMLOCK_RANGE X X X X _POSIX_MEMORY_PROTECTION - - X X _POSIX_PRIORITY_SCHEDULING - - X X _POSIX_SEMAPHORES X X X X _POSIX_SHARED_MEMORY_OBJECTS X X X X _POSIX_REALTIME_SIGNALS X X X X _POSIX_TIMERS X X X X _POSIX_MESSAGE_PASSING X X X X _POSIX_SYNCHRONIZED_IO X X X X _POSIX_ASYNCHRONOUS_IO - X X X _POSIX_PRIORITIZED_IO - - X X

  20. POSIX.1c Requirements PSE51 PSE52 PSE53 PSE54 POSIX_USER_GROUPS_R - - - X POSIX_DEVICE_SPECIFIC_R - - - X POSIX_FILE_LOCKING X X X X POSIX_C_LANG_SUPPORT_R X X X X POSIX_SYSTEM_DATABASE_R - - - X Option PSE51 PSE52 PSE53 PSE54 _POSIX_THREADS X X X X _POSIX_THREAD_ATTR_STACKSIZE - - X X _POSIX_THREAD_PRIO_INHERIT X X X X _POSIX_THREAD_PRIORITY_SCHEDULING - - - X _POSIX_THREAD_PRIO_PROTECT - X - X _POSIX_ THREAD_PROCESS_SHARED - - - X _POSIX_THREAD_ATTR_STACKADDR - - - X

  21. Pthreads (POSIX.1c)

  22. Pthreads (POSIX.1c) • Thread management • Basic primitives • Thread attributes • Execution Scheduling • Synchronization • Mutex • Condition variable • Thread Specific data • ...

  23. Thread Management:Basic Primitives int pthread_create(pthread_t * thread ,const pthread_attr_t * attr ,void * (* start_routine)(void *) ,void * arg); void pthread_exit(void * value_ptr); pthread_t pthread_self(void); int pthread_equal(pthread_t t1, pthread_t t2); • Attr Struktur vorher erläutern? • Hinweis, dass Synchronisation zwischen Threads unbedingt beachtet werden muss • Thread erzeugen

  24. Thread Management:Basic Primitives Was wird hier „gejoined“? • Join & detach • int pthread_join(pthread_t thread, void ** status); • int pthread_detach(pthread_t thread);

  25. Beispiel #include <stdio.h> #include <pthread.h> void Worker(int *idp) { int i; for (i = 0; i < 4; i++) printf("thread %d %dth iteration\n",*idp, i); pthread_exit(0); } void main() { int i; pthread_t threads[3]; int thread_ids[3] = {0,1,2}; for( i = 0 ; i < 3 ; i++ ) pthread_create(&threads[i], NULL , (void *) Worker, &thread_ids[i]); for( i = 0 ; i < 3 ; i++ ) pthread_join(threads[i], NULL); pthread_exit(0); }

  26. Thread Management:Thread Attribute int pthread_attr_init(pthread_attr_t * attr); int pthread_attr_destroy(pthread_attr_t * attr); int pthread_attr_setstacksize(pthread_attr_t * attr, size_t size); int pthread_attr_getstacksize(pthread_attr_t * attr, size_t * size); //PTHREAD_STACK_MIN, PTHREAD_STACK_DEFAULT int pthread_attr_setstackaddr(pthread_attr_t * attr, void * stackaddr); int pthread_attr_getstackaddr(pthread_attr_t * attr, void ** stackaddr); int pthread_attr_setdetachstate(pthread_attr_t * attr, int joinstate); int pthread_attr_getdetachstate(pthread_attr_t * attr, int * joinstate); //PTHREAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACHED int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit); int pthread_attr_getinheritsched(pthread_attr_t *attr, int * inherit); //PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); int pthread_attr_getschedpolicy(pthread_attr_t * attr, int * policy); //SCHED_RR, SCHED_FIFO, SCHED_OTHER

  27. Execution Scheduling The pthread_getschedparam() and pthread_setschedparam() allow the scheduling policy and scheduling parameters of individual threads within a multi-threaded process to be retrieved and set. For SCHED_FIFO and SCHED_RR, the only required member of the sched_param structure is the priority sched_priority. For SCHED_OTHER, the affected scheduling parameters are implementation-dependent. http://www.rtlinux.org/documents/documentation/man_pages/susv2/xsh/pthread_getschedparam.html Daraus geht hervor, dass es auch andere Scheduler geben kann und demnach die Struktur sched_param flexibel bzw. von policy abhängt • Static scheduling parameter int pthread_attr_setschedparam(pthread_attr_t * attr , struct sched_param * param); int pthread_attr_getschedparam(pthread_attr_t * attr , struct sched_param * param); Kann nur vom Main-Thread aufgerufen werden • Dynamic scheduling parameter int pthread_getschedparam(pthread_t thread, int * policy, struct sched_param *param); int pthread_setschedparam(pthread_t thread, int policy, struct sched_param * param); Eagleeye: Kann von Vater und Sohn-Thread aufgerufen werden struct sched_param { int sched_priority; };

  28. Beispiel #include <stdio.h> #include <pthread.h> void Worker(int *idp) { int i; for (i = 0; i < 4; i++) printf("thread %d %dth iteration\n",*idp, i); pthread_exit(0); } void main() { int i; pthread_t threads[3]; pthread_attr_t thread_attrs; int thread_ids[3] = {0,1,2}; for( i = 0 ; i < 3 ; i++ ) { pthread_attr_init(&thread_attrs); pthread_attr_setschedpolicy(&thread_attrs, SCHED_FIFO); pthread_attr_getschedparam(&thread_attrs, &param); param.sched_priority = PTHREAD_MAX_PRIORITY; // 254 pthread_attr_setschedparam(&thread_attrs, &param); pthread_create(&threads[i],&thread_attrs,(void *) Worker,&thread_ids[i]); } pthread_exit(0); }

  29. Pthreads (POSIX.1c) • Thread management • Basic primitives • Thread attributes • Execution Scheduling • Synchronization • Mutex • Condition variable • Thread Specific data • ... Wo sind die Semaphoren? Mutex sind binäre Semaphore? Zählende Semaphore muss man sich mit Conditions selber bauen.

  30. Mutex Primitives int pthread_mutex_init(pthread_mutex_t * mutex , const pthread_mutexattr_t * attr); PTHREAD_MUTEX_INITIALIZER int pthread_mutex_destroy(pthread_mutex_t * mutex); int pthread_mutex_lock(pthread_mutex_t * mutex); int pthread_mutex_unlock(pthread_mutex_t * mutex); int pthread_mutex_trylock(pthread_mutex_t * mutex); int pthread_mutex_setprioceiling(pthread_mutex_t * mutex , int prioceiling, int * old_ceiling); int pthread_mutex_getprioceiling(pthread_mutex_t * mutex , int * ceiling);

  31. Pthreads (POSIX.1c) • Thread management • Basic primitives • Thread attributes • Execution Scheduling • Synchronization • Mutex • Condition variable • Thread Specific data • ...

  32. Mutex Attributes int pthread_mutexattr_init(pthread_mutexattr_t * attr); int pthread_mutexattr_destroy(pthread_mutexattr_t * attr); int pthread_mutexattr_setprotocol(pthread_mutexattr_t * attr , int protocol); int pthread_mutexattr_getprotocol( const pthread_mutexattr_t * attr, int * protocol); //PTHREAD_PRIO_NONE, PTHREAD_PRIO_PROTECT, PTHREAD_PRIO_INHERIT int pthread_mutexattr_setprioceiling( pthread_mutexattr_t * attr, int prioceiling); int pthread_mutexattr_getprioceiling( const pthread_mutexattr_t * attr, int * ceiling); int pthread_mutexattr_setpshared(pthread_mutexattr_t * attr , int pshared); int pthread_mutexattr_getpshared(const pthread_mutexattr_t * attr , int * pshared); //PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED

  33. Beispiel Dynamische Initialisierung Statische Initialisierung void Thread1(void *data); ... pthread_t thread_id1; ... pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ... void main(void){ ... pthread_create(&thread_id1, ...); ...} void Thread1(void *data){ while(1) { ... pthread_mutex_lock(&mutex); ... pthread_mutex_unlock(&mutex); ... } } void Thread1(void *data); ... pthread_t thread_id1; ... pthread_mutex_t mutex; void main(void){ ... pthread_mutex_init(&mutex, NULL); ... pthread_create(&thread_id1, ...); ... }

  34. Beispiel (2/2) • Ex3: mutex attribute usage void Thread1(void *data); ... pthread_t thread_id1; ... pthread_mutex_t mutex; pthread_mutexattr_t mutex_attr; ... void main(void){ .. pthread_mutexattr_init(&mutex_attr); pthread_mutexattr_setprotocol(&mutex_attr,PTHREAD_PRIO_PROTECT); pthread_mutexattr_setprioceiling(&mutex_attr,0); pthread_mutex_init(&mutex, &mutex_attr); ... pthread_create(&thread_id1, NULL, (void *)Thread1, 0); ... }

  35. Condition Variable int pthread_condattr_init(pthread_condattr_t * attr); int pthread_condattr_destroy(pthread_condattr_t *attr); int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *attr); //PTHREAD_COND_INITIALIZER int pthread_cond_destroy(pthread_cond_t * cond); int pthread_cond_broadcast(pthread_cond_t * cond); int pthread_cond_signal(pthread_cond_t * cond); int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex); int pthread_cond_timedwait(pthread_cond_t * cond ,pthread_mutex_t * mutex ,const struct timespec * abstime); int pthread_condattr_setpshared(pthread_mutexattr_t *attr, int pshared); int pthread_condattr_getpshared(const pthread_mutexattr_t * attr , int *pshared); //PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED typedef struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ } timespec_t; typedef long time_t;

  36. Beispiel ... pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t count_threshold_cv = PTHREAD_COND_INITIALIZER; void main(void) { int i; pthread_t threads[3]; pthread_create( &threads[0] ,NULL,(void *) inc_count ,&thread_ids[0]); pthread_create( &threads[1] ,NULL,(void *) inc_count ,&thread_ids[1]); pthread_create( &threads[2] ,NULL,(void *) watch_count ,&thread_ids[2]); for( i = 0; i < 3; i++) pthread_join(threads[i], (void **)NULL); pthread_exit(0); } void watch_count(int *idp) { timespec_t abstime = {1,0}; // 1 sec pthread_mutex_lock(&count_mutex); pthread_cond_timedwait( &count_threshold_cv, &count_mutex, &abstime); printf("watch_count(): Thread %d, Count is %d\n",*idp,count); pthread_mutex_unlock(&count_mutex); } void inc_count(int *idp) { int i; for(i =0; i < TCOUNT; i++) { pthread_mutex_lock(&count_mutex); count++; printf("inc_counter(): Thread %d, new count %d\n",*idp, count); if (count == WATCH_COUNT) pthread_cond_signal(&count_threshold_cv); pthread_mutex_unlock(&count_mutex); } }

  37. Thread Specific Data int pthread_key_create(pthread_key_t * key, void (* destructor)(void *)); int pthread_key_delete(pthread_key_t key); int pthread_setspecific(pthread_key_tkey, const void *value); void *pthread_getspecific(pthread_key_t key); ThreadOnce-Execution int pthread_once(pthread_once_t * once_control, void (* init_routine)(void)); PTHREAD_ONCE_INIT

  38. Beispiel static void make_key(void) { (void)pthread_key_create(&key, NULL); } void func(void) { void *ptr; pthread_once(&key_once, make_key); if((ptr = pthread_getspecific(key)) == NULL) { ptr = malloc(OBJECT_SIZE); pthread_setspecific(key, ptr); ... } ... }

  39. Execution Scheduling • Threadbeendigung (Thread cancellation) int pthread_cancel(pthread_t thread); int pthread_setcancelstate(int state, int * oldstate); int pthread_setcanceltype(int type, int * oldtype); // PTHREAD_CANCEL_DEFFERED, PTHREAD_CANCEL_ASYNCHRONOUS void pthread_testcancel(void); void pthread_cleanup_push(void (* routine)(void *), void * args); void pthread_cleanup_pop(int execute); • Prozesserzeugung int pthread_atfork(void (* prepare)(void), void (* parent)(void), void (* child)(void)); • Signal int pthread_kill(pthread_t thread, int sig); int pthread_sigmask(int how, const sigset_t * set, sigset_t * oset);

  40. Probleme • Periodische Ausführung in POSIX • Standard der POSIX-Erweiterung

  41. Periodische Ausführung in POSIX 1/1 • Verwendung von sleep() • Ad-hoc Methode periodic_thread(void* data) { time_t t1, t2; while(1) { time(&t1); /* do something */ time(&t2); if((t2 -t1)>deadline){ /* handle deadline miss */ } sleep(period-(t2-t1)); } } Overhead Späte Behandlung verpasster Deadlines Eagleeye: Den Source versteh ich nicht. Müssen wir mal drüber snacken.

  42. Periodische Ausführung in POSIX 2/2 Eagleeye: Run-time Overhead? Wo, in der Waitroutine? Wie könnte es schneller gehen? Eagleeye: Vorteil: Lokale Variablen müssen nicht bei jedem Thread-Start neu angelegt werden. (Verhinderung von Exceptions, Schnellere Programmabarbeitung) • Periodischer Timer • Thread • Erzeugung eines neuen Threads. Am Ende des Threads wird dieser schlafen gelegt • Problem: • Run-time Overhead • Signal • Ein Signal wird einem Thread zugewiesen und periodisch aktiviert • Problem • Verwendung von Signalen in Multithreaded Umgebung erfordert komplexe und wohl durchdachte Programmierung • Grundlegender Blick auf Signale in POSIX • POSIX unterscheidet Registrierung und Übergabe von Signalen. • Ein Signal wird an jeden Thread gesendet, der dieses nicht blockiert. Eagleeye: Wo werden in dem vorangegangenen Beispiel Signale verwendet?

  43. Beispiel struct sigevent { int sigev_notify; /* notification mode */ int sigev_signo; /* signal number */ union sigval sigev_value; /* signal value */ void (*sigev_notify_function)(union sigval); pthread_attr_t *_sigev_notify_attributes; }; /* no notification */ #define SIGEV_NONE 1 /* queued signal notification */ #define SIGEV_SIGNAL 2 /* call back from another thread */ #define SIGEV_THREAD 3 periodic_routine(){ /* ... */} timer_setup() { /* ... */ #ifdef PERIODIC_THREAD event.sigev_notify = SIGEV_THREAD; /* ... */ #else ifdef PERIODIC_SIGNAL event.sigev_notify = SIGEV_SIGNAL; /* ... */ #endif tid = timer_create (CLOCK_REALTIME, &event); timer.it_value = {release_time,0}; //release_time sec. timer.it_interval = {period, 0}; // period sec. timer_settime (tid, 0, &timer, NULL); } Sekunde Nanosekunde 0: relative time TIMER_ABSTIME:absolute time Eagleeye: 2. #endif fehlt

  44. Standard Way of POSIX Extension • Hinzufügen weiterer Mitglieder zur Struktur sched_param • Problem: Mix der Interfaces und möglich Konfusion bei der Nutzung pthread_attr_t thr1_attr; struct sched_param param; pthread_attr_init(&thr1_attr); pthread_attr_getschedparam(&thr1_attr,&param); param.sched_priority = PTHREAD_MAX_PRIORITY - 1; param.period = period; param.release_time = release_time; param.deadline = deadline; param.dhandler = dhandler; pthread_attr_setschedparam(&thr1_attr,&param); pthread_attr_setschedpolicy(&thr1_attr,SCHED_POLICY); pthread_create(&thr1_id, &thr1_attr, &thr1,&thr1_arg); Erweiterte Scheduling parameter

  45. Periodische Prozesse unter RT-Linux Anforderungszeitpunkt Periode Sched_delay Freigabe- zeit Initialisierungs- phase Eagleeye: Müssen wir mal diskutieren

  46. Erweiterung des RT-Linux-Schedulers • Beschreibung, RT-Linux (F.G.) • Beschreibung RT-Linux-Scheduler • allgemein • Beschreibung EDF-Scheduler • Erweiterbarkeit • Beschreibung ELLF- Algorithmus • Integration in RT-Linux

  47. RTLinux Scheduler • Stat. Scheduler • Vergabe der Rechenzeit nach Höhe der Priorität • Periodische und nicht-periodische Threads • Unterbrechung von Threads nur durch Threads höherer Priorität möglich • Linux läuft als „Idle-Task“ mit Priorität 0. • Linux Task • Nicht periodischer Echtzeitprozess • Kommunikation mit RT-Processen nur über Shared-Memory bzw. RT-FIFO‘s • Wird benötigt, um RT-Linux zu beenden • Synchronisationsmechanismen • Mutex • Semaphoren • Conditions variables

  48. RT-Scheduler (Auszug) for (t = sched->rtl_tasks; t; t = t->next) { // evaluate expired timers if (test_bit(RTL_THREAD_TIMERARMED, &t->threadflags)) { if (now >= t->resume_time) // start new task ? { clear_bit(RTL_THREAD_TIMERARMED, &t->threadflags); rtl_sigaddset (&t->pending, RTL_SIGNAL_TIMER); // process can be scheduled if (t->period != 0) // process periodically ? { t->resume_time += t->period; // set next start of process while (now >= t->resume_time) { t->resume_time += t->period; } } else // unknown deadline { t->resume_time = HRTIME_INFINITY; } } } // and find highest priority runnable task if ((t->pending & ~t->blocked) && (!new_task || (t->sched_param.sched_priority > new_task->sched_param.sched_priority))) { new_task = t; } }

  49. ELLF-Scheduler • Basiert auf LLF-Scheduler • Verhinderung des „Trashings“ -> Schedulerlaufzeit vermindert sich • Erkennen von verpassten Deadlines frühzeitig möglich, so dass Notfallprogramm startbar • Prinzip, grundsätzlich wie LLF mit folgenden Erweiterungen: • Beginnen Threads zu „trashen“, wird der mit der geringsten Deadline gewählt – alle anderen werden ausgeschlossen (excluded). • Alle Threads nehmen am Schedulingprozess teil, zugeteilt werden letztendlich aber nur Threads, die nicht ausgeschlossen sind. • Werden ausgeschlossene Threads ausgewählt, wird der laufende Thread weiterbearbeitet.

  50. Vergleich LLF & ELLF Eagleeye: Gute Prüfungsfrage  Warum trasht LLF? LLF-Scheduler -> 12 Taskwechsel ELLF-Scheduler -> 3 Taskwechsel • Vergleich der Scheduler LLF und ELLF unter folgenden Extrembedingungen: 3 Tasks mit Px=Dx=td, Rechenzeit Rx=4. • Die Folge ist ein Trashing bei LLF, das mit der Tickauflösung des Schedulers durchgeführt wird. Deadline P3 P2 P1 t tt td Deadline P3 P2 P1 td t tt

More Related