Øvelse+9+-+Os+Api

=Exercise 0 Compiling with OSApi=

Host:
code make TARGET=host DEBUG=1 all or make TARGET=host all code code g++ -o testApp main.cpp -D_REENTRANT -DOS_LINUX -I/home/stud/OSAPI/inc -L /home/stud/OSAPI/lib/target/debug -lOSApi -lpthread -lrt

code

Target:
code make TARGET=targetDEBUG=1 all or make TARGET=target all code code arm-angstrom-linux-gnueabi-g++ -o testApp main.cpp -D_REENTRANT -DOS_LINUX -I/home/stud/OSAPI/inc -L /home/stud/OSAPI/lib/host/debug -lOSApi -lpthread -lrt code =Exercise 1 Completing the Linux skeleton of the OO OS Api= In this exercise you will be tasked with completing the OSApi library. The following files are missing or have not been completed.


 * int/osapi/linux/Mutex.hpp - Missing
 * linux/Mutex.cpp - Missing
 * linux/Conditional.cpp - Already started
 * int/osapi/linux/Semaphore.hpp - Missing
 * linux/Semaphore.cpp - Missing
 * linux/Utility.cpp - Missing
 * linux/Thread.cpp - Missing

Use the Linux documentation either via man pages, the net and remember to inspect the Win32-edition of the OS API. Also remember to read the \Speci cation of an OO OS API" (available on CampusNet) to write a Linux-edition of the OO OS API.

It is of course very important that the interface to the OS resources is exactly as speci ed in the OS API speci cation. Otherwise, it will be impossible to interchange the OS APIs as seen from the user when he/she tries to compile it for another platform.

To compile your revised version of the OSApi, use the following command: make DEBUG=1 TARGET=host all

The makefile has multiple dierent combinatorial uses, which means that you should take the time to study it and determine what it can and what it can't. It is a simple implementation with some interesting approaches that you might bene t by, however \feel free to improve". Having completed part or all of the OSApi library appropriate tests are needed. This means that you have to create simple tests that verify that the library does indeed work. To help verify your program thread-wise use the source le ThreadTest.cpp.

Questions to answer:

code format="cpp" /* * The most important in this class is to make a get-funktionen, because the conditional class must use it. * Else is the class easy * to implement, we need a constructer to init the mutex, a lock funktion, * a unlock funktion, a destructo * r to destory mutex and a mutex.
 * Why does the ThreadTest.cpp program behave dierently depending on whether you are running it on a single processor or multi processor system and how is this experienced?
 * The le linux/Conditional.cpp
 * In completing this file you will encounter the term CLOCK MONOTONIC. What does this mean and how does it distinguish itself from the other clock setup options that are possible?
 * //CLOCK MONOTONIC dosent use the computers clock, CLOCK MONOTONIC calculate a timespan from an event from the computer//. to use the computer clock use REAL_CLOCK, REF.: [|stackoverflow.com/questions/3523442/difference-between-clock-realtime-and-clock-monotonic].
 * Why could this possibly be important? Hint: NTP and setting time.
 * Inspecting the OSApi library, describe the chosen setup and how it works.
 * Hint: Directory structure, de ne usage, handling platforms etc.


 * 1) ifndef OSAPI_LINUX_MUTEX_HPP
 * 2) define OSAPI_LINUX_MUTEX_HPP
 * 3) include 
 * 4) include 

namespace osapi { class Mutex : Notcopyable { public: Mutex; void lock; void unlock; pthread_mutex_t& nativeHandle; ~Mutex; private: pthread_mutex_t m; } }

code
 * 1) endif

code format="cpp" /* * All the information about the pthread funktions are from: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html. * All the funktions is describe over the funktions. */
 * 1) include
 * 2) include 
 * 3) include 

namespace osapi {

/*  * The funktion must init the mutex and throw a exception if it fails. *  * If  successful, the pthread_mutex_init function shall return  zero;  otherwise,  an  error  number  shall  be   * returned to indicate the error and throw will catch it. */ Mutex::Mutex { if (pthread_mutex_init(&m, NULL)) throw MutexError; }

/* * The funktion must lock the mutex and throw a exception if it fails * * If  successful, the  pthread_mutex_lock function  shall return zero; otherwise, an error number shall be  * returned to indicate the error and throw will catch it. */ void Mutex::lock {  if(pthread_mutex_lock(&m)) throw MutexError; }

/* * The funktion must unlock the mutex and throw a exception if it fails * * If  successful, the  pthread_mutex_unlock function  shall return zero; otherwise, an error number shall be  * returned to indicate the error. */ void Mutex::unlock {  if(pthread_mutex_unlock(&m)) throw MutexError; }

/* * The funktion must return a ref. to the mutex */ pthread_mutex_t& Mutex::nativeHandle {  return m; }

/* * The funktion must destroy the mutex, the funktion may not throw an exeption * * If successful, the pthread_mutex_destroy function shall return  zero;  otherwise,  an  error  number  shall  be * returned to indicate the error. */ Mutex::~Mutex {  pthread_mutex_destroy(&m); // Ignores return value, may not throw an exeption anyway } } code code format="cpp" /* * All the information about the pthread funktions are from: http://www.yolinux.com/TUTORIALS/LinuxTutorialsPosixThreads.html. * * All the funktions is describe over the funktions.
 * 1) include 
 * 2) include 
 * 1) include 

namespace osapi { /*   * The funktion must init the cond attribute and catch the exception if it fails, * it must set the clock time on the attribute to CLOCK_MONOTONIC and catch the exceptions if it fails, and last init a cond * wait attribute and catch the exception if it fails */ Conditional::Conditional {   //Init cond atribute if(pthread_condattr_init(&condattr_)) throw ConditionalError;

//Set the atribute to use monotonic time instead og real if(pthread_condattr_setclock(&condattr_, CLOCK_MONOTONIC)) throw ConditionalError;

//Init cond wait with new atribute if(pthread_cond_init(&cond_, &condattr_)) throw ConditionalError; }

/*  * The funktion must send a signal to the cond_ attribute and catch the exception if it fails. * If successful, the pthread_cond_signal function shall     return     zero;    otherwise,  an    error  number shall be   * returned to indicate the error. */ void Conditional::signal {   if(pthread_cond_signal(&cond_)) throw ConditionalError; }

/*  * The funktion must release the _cond attribute and catch the exception if it fails. * If successful, the pthread_cond_broadcastfunction shall     return     zero;    otherwise, * an error number shall be returned to indicate the error. */ void Conditional::broadcast {   if(pthread_cond_broadcast(&cond_)) throw ConditionalError; }

/*  * The funktion shall block on the _cond. * They shall be called with mutex locked by the calling thread. */ void Conditional::wait(Mutex& mut) {   if(pthread_cond_wait(&cond_, &mut.nativeHandle)) throw ConditionalError; } /*   * The funktion is implemented in advance. * It compares the standart real-time clock, but in this implemention will feature a struct with monotonic clock instead. * Therefore, the conditional is set to use monotonic clock */ Conditional::Awoken Conditional::waitTimed(Mutex& mut, unsigned long timeout) {   struct timespec ts;

// Get monotonic clock - current time clock_gettime(CLOCK_MONOTONIC, &ts);

// Calculate new absolute time by getting current monotonic time and offsetting it   size_t secs = timeout/1000; size_t msecs = timeout - secs*1000;

ts.tv_sec += secs; ts.tv_nsec += msecs*1000000; size_t overflow = ts.tv_nsec/1000000000;

if(overflow) {     ts.tv_sec += overflow; ts.tv_nsec -= overflow*1000000000; }

int res = pthread_cond_timedwait(&cond_, &mut.nativeHandle, &ts);

switch(res) {     case ETIMEDOUT: return TIMEDOUT; break;

case 0: return SIGNALED; break;

default: throw ConditionalError; } }

/*  * The funktion must destory the _cond */ Conditional::~Conditional {   pthread_cond_destroy(&cond_); } }

code code format="cpp" /* * In this class we don't need any special funktion, we only need a constructor, destructor, a wait funktion, * a signal funktion and a semaphore. * To see how to use init: http://linux.die.net/man/3/sem_init * To see how to use signal: http://linux.die.net/man/3/sem_post * To see how to use wait: http://linux.die.net/man/3/sem_wait * To see how to use destroy: http://linux.die.net/man/3/sem_destroy */
 * 1) ifndef OSAPI_LINUX_SEMAPHORE_HPP
 * 2) define OSAPI_LINUX_SEMAPHORE_HPP
 * 3) include 
 * 4) include 

namespace osapi { class Semaphore : Notcopyable { public: Semaphore(unsigned int initCount); void wait; // decrement void signal; //increment ~Semaphore; private: sem_t _sem; }; }


 * 1) endif

code code format="cpp" /* * All the funktions are describe over the funktions. */
 * 1) include 

namespace osapi {   /*     * arg(1) is a reference to the semaphore. * If arg(2) has the value 0, then the semaphore is shared between the threads of a process. * The arg(3) specifies the initial value for the semaphore. * If successful, the funktion shall return zero; otherwise, an error number shall be returned. */   Semaphore::Semaphore(unsigned int initCount) {     if(sem_init(&_sem, 0, initCount)) throw SemaphoreError; }

/*    * Wait decrements (locks) the semaphore pointed to by sem. * If the semaphore's value is greater than zero, then the decrement proceeds, and the funktion returns, immediately. * If the semaphore currently has the value zero, then the call blocks until either it besomes possible * to perform the decrement. * If successful, the funktion shall return zero; otherwise, an error number shall be returned. */   void Semaphore::wait // decrement {     if(sem_wait(&_sem)) throw SemaphoreError; }   /*     * Post increments (unlock) the semaphore pointed to by sem. * If the semaphore value conseqently becomes greater than zero. * Then another process or thread blocked in a wait call will be woken up and proceed to lock the semaphore. * If succesful, the funktion shall return zero; otherwise, an error number shall be returned. */   void Semaphore::signal //increment {     if(sem_post((&_sem))) throw SemaphoreError; }

/*    * Destroys the unnamed semaphore at the address pointed to by sem. */   Semaphore::~Semaphore {     sem_destroy(&_sem); } }

code code format="cpp" /* In this class we only need a sleep funktion, we need to sleep in ms*/
 * 1) include 
 * 2) include 

namespace osapi {

void sleep(unsigned long msecs) {   usleep(msecs * 1000); //From us to ms  }

} code code format="cpp" /* * */
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include <osapi/Thread.hpp>

namespace osapi { Thread::Thread(Thread::ThreadPriority p, const std::string& name) : priority_(p), name_(name), jonied(false) {   if(getuid != 0) {    printf("You must be admin"); exit(1); } }  /*   * Destructor calls the join, catcher exceptions and ignoring them. */ Thread::~Thread {   join; pthread_join(threadId_, NULL); pthread_attr_destroy(&attr_); }

void Thread::start {

if(getuid == 0) // Check to see if we are root {     sched_param sched_p; if(pthread_attr_setschedpolicy(&attr_, SCHED_RR) != 0) throw ThreadError;// Set RR scheduling (RT, timesliced) if(pthread_attr_setinheritsched(&attr_, PTHREAD_EXPLICIT_SCHED) != 0) throw ThreadError; // Create thread with explicit (non-inherited) scheduling - setting priority will not work otherwise! sched_p.sched_priority = static_cast (priority_);// Set priority if(pthread_attr_setschedparam(&attr_, &sched_p) != 0) throw ThreadError;// Use the priority

if(pthread_create(&threadId_, &attr_, threadMapper, this) != 0) throw ThreadError; }   else {     if(pthread_create(&threadId_, NULL, threadMapper, this) != 0) throw ThreadError; } }

void Thread::setPriority(Thread::ThreadPriority p) { if(pthread_setschedprio(threadId_, (int)p)) throw ThreadError; }

Thread::ThreadPriority Thread::getPriority const {   int Policy; sched_param sched_p; if(pthread_getschedparam(threadId_, &Policy, &sched_p)) throw ThreadError;

return (Thread::ThreadPriority)sched_p.sched_priority; }

void Thread::join {   threadDone_.wait; }

std::string Thread::getName const {  return name_; } /*   * Ensures that the run-funktion can have the same signature (void run(void)) on linux and windows, * although the various thread create funktion takes a different line funktion. *  * Ensures that call the appropriate run mode. It should be called via a pointer to the thread class, * so the correct virtual run-funktion is called. */ void* Thread::threadMapper(void* thread) {   static_cast<Thread*>(thread) -> run; return NULL; }

} code =Exercise 2 On target= Verify that your OSApi library can compile for both Linux host and target. The same applies to your test applications.

Questions to answer:
 * Did you do need to change code for this to work, if so what?
 * //Just remember to make the OSApi to the target and compile the applikation to the taget. Look at Exercise 0. If you do that all will work//
 * //When you are using your target the OSApi and the applikation must be on the target ;)//

=Exercise 3 PCLS now the OS Api= At this point we have created the PCLS system and it works great with Message and Message queues :-).

The next natural step is obviously to port your PCLS application such that it now is based on your newly created OS Api.

Remember that the loop in the thread function run must look like this: <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">#include <unistd.h> code format="cpp" void MyThread :: run { while ( running_ ) {   unsigned long id; osapi :: Message * msg = mq_. receive (id); handleMsg (msg, id); delete msg ; } } code What is important here is that the receive function must be in this loop and NOT anywhere else!

Questions to answer:


 * Which changes did you make and why?
 * Does this modi cation whereby you utilize the OSApi library improve your program or not. Substantiate you answer with reasoning.

Finally the complete solution for this exercise must be available for reading!

code format="cpp" /*All the code to ParkALot2012, there isen't comments*/


 * 1) include <osapi/MsgQueue.hpp>
 * 2) include <osapi/Thread.hpp>
 * 3) include <osapi/Message.hpp>


 * 1) include <pthread.h>
 * 2) include
 * 3) include

osapi::MsgQueue entryMq(10); osapi::MsgQueue exitMq(10); osapi::MsgQueue carMq(10);

enum {	ID_Car_Entry_Open_Req = 0, ID_Car_Entry_Open_Con = 1, ID_Car_Exit_Open_Req = 2, ID_Car_Exit_Open_Con = 3, ID_Car_Waiting_Enter = 4, ID_Car_Waiting_Exit = 5, ID_DONE = 6 };

int carWait = 0;

struct entryOpenRequest : public osapi::Message {	osapi::MsgQueue* mq_; };

struct entryOpenConfirm : public osapi::Message {	bool result_; };

struct exitOpenRequest : public osapi::Message {	osapi::MsgQueue* mq_; };

struct exitOpenConfirm : public osapi::Message {	bool result_; };

void garageDoorOpenControllerHandler(osapi::Message* msg, unsigned long id) {	switch(id) {	case ID_Car_Entry_Open_Req: {		std::cout << "Entry Request Recieved" << std::endl; entryOpenRequest* req = reinterpret_cast<entryOpenRequest*>(msg); // create responds entryOpenConfirm* cfm = new entryOpenConfirm; cfm->result_ = true;

req->mq_->send(ID_Car_Entry_Open_Con, cfm);

break;} default: std::cout << "Unknown identifier" << std::endl; } }

void garageDoorExitControllerHandler(osapi::Message* msg,unsigned long id) {	switch(id) {	case ID_Car_Exit_Open_Req: {		std::cout << "Exit Request Recieved" << std::endl; exitOpenRequest* ereq = reinterpret_cast<exitOpenRequest*>(msg); exitOpenConfirm* cfm = new exitOpenConfirm; cfm->result_ = true;

ereq->mq_->send(ID_Car_Exit_Open_Con, cfm); break;} default: std::cout << "Unknown identifier" << std::endl; } }

class carDriver : public osapi::Thread { public: void run {	int state = ID_Car_Waiting_Enter; unsigned long id = 0; osapi::MsgQueue* mq;

for {		switch(state) {		 case ID_Car_Waiting_Enter: {			// create request to enter entryOpenRequest* req = new entryOpenRequest; req->mq_ = mq; // send request entryMq.send(ID_Car_Entry_Open_Req, req); sleep(1);

//recieve answer osapi::Message* msg = mq->receive(id); entryOpenConfirm* cfm = reinterpret_cast<entryOpenConfirm*>(msg); if(cfm->result_) {				carWait++; std::cout << "Car driving into lot, there is now " << carWait << " car(s)" << std::endl; // drive into parking lot; srand(time(NULL)); sleep(rand%10); // set state state = ID_Car_Waiting_Exit; }			break;} case ID_Car_Waiting_Exit: {			// create request to exit exitOpenRequest* ereq = new exitOpenRequest; ereq->mq_ = mq; // send request exitMq.send(ID_Car_Exit_Open_Req, ereq);

//recieve answer osapi::Message* msg = mq->receive(id); exitOpenConfirm* cfm = reinterpret_cast<exitOpenConfirm*>(msg); if(cfm->result_) {			     carWait--; std::cout << "Car driving out of lot, there is now " << carWait << " car(s)" << std::endl; // drive out of parking lot; state = ID_DONE; }			break;} case ID_DONE: {			break;

}		}	} } };

class entryFunc : public osapi::Thread { public: void run {   	osapi::MsgQueue* mq;

for {		unsigned long id; osapi::Message* msg = mq->receive(id); garageDoorOpenControllerHandler(msg, id); delete msg; } } };

class exitFunc : public osapi::Thread { public: void run {   	osapi::MsgQueue* mq;

for {		unsigned long id; osapi::Message* msg = mq->receive(id); garageDoorExitControllerHandler(msg, id); delete msg; } } };

int main(int argc, char* arg[]) {	char input; std::cout << "How many cars?\n"; std::cin >> input; int car = input;

carDriver carDriverThread; entryFunc entryFuncThread; exitFunc exitFuncThread;

entryFuncThread.start; exitFuncThread.start;

sleep(1);

for( int i = 0; i < car; i++ ) {		carDriverThread.start; sleep(1); }

/*while(1) {	 std::cin >> input;

if(input == 'q' || input == 'Q') {	   exit(1); }	 }*/

carDriverThread.join; entryFuncThread.join; exitFuncThread.join; }

code

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">#include <errno.h> <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">#include <stdlib.h> <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">#include <stdio.h> <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">#include <osapi/Thread.hpp>

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">namespace osapi <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">Thread::Thread(Thread::ThreadPriority p, const std::string& name) : priority_(p), name_(name), jonied(false) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(getuid != 0) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">printf("You must be admin"); <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">exit(1); <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">} <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">Thread::~Thread <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">join; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">pthread_join(threadId_, NULL); <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">pthread_attr_destroy(&attr_); <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">void Thread::start <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(getuid == 0) //Check to see if we are root// <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">//{// <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">//sched_param sched_p;// <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">//if(pthread_attr_setschedpolicy(&attr_, SCHED_RR) != 0) throw ThreadError;// Set RR scheduling (RT, timesliced) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_attr_setinheritsched(&attr_, PTHREAD_EXPLICIT_SCHED) != 0) throw ThreadError; //Create thread with explicit (non-inherited) scheduling - setting priority will not work otherwise!// <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">//sched_p.sched_priority = static_cast (priority_);// Set priority <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_attr_setschedparam(&attr_, &sched_p) != 0) throw ThreadError; // Use the priority

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_create(&threadId_, &attr_, threadMapper, this) != 0) throw ThreadError; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">} <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">else <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_create(&threadId_, NULL, threadMapper, this) != 0) throw ThreadError; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">} <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">void Thread::setPriority(Thread::ThreadPriority p) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_setschedprio(threadId_, (int)p)) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">throw ThreadError; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">Thread::ThreadPriority Thread::getPriority const <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">int Policy; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">sched_param sched_p; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">if(pthread_getschedparam(threadId_, &Policy, &sched_p)) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">throw ThreadError;

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">return (Thread::ThreadPriority)sched_p.sched_priority; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">void Thread::join <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">threadDone_.wait; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">std::string Thread::getName const <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">return name_; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">void* Thread::threadMapper(void* thread) <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">{ <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">static_cast<Thread*>(thread) -> run; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">return NULL; <span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}

<span style="display: block; height: 1px; left: -40px; overflow-x: hidden; overflow-y: hidden; position: absolute; top: 9033px; width: 1px;">}