|
API ядра
|
Введение
В данном документе представлен набор интерфейсных частей классов, используя которые,
приложения пользователя могут взаимодействовать с ядром 3OS. Эти классы не являются
отражением внутренней структуры и физической реализации ядра, а являются формальными
"точками входа" в ядро. Реализация методов этих классов зависит от версии ядра и
сопровождается группой занимающейся разработкой ядра (KG - kernel group). Пользователь
не должен делать никаких предположений о реализации этих классов. Кроме описанных
в данном документе классов, KG может добавлять/удалять в Kernel API вспомогательные,
технические классы. Пользоваться такими классами не рекомендуется т. к. их функциональность
зависит от текущей версии ядра, и в другой версии может не поддерживаться.
Объекты этих классов следует рассматривать как ссылки на соответствующие объекты
ядра. Но это не означает, что в ядре реализован класс обладающий такой же функциональностью.
Например, описанный ниже класс Mutex инкапсулирует логику объекта синхронизации
mutex. В коде ядра, действительно, может быть реализован некий класс KernelMutex,
а может и не быть. Во втором случае ядро может имитировать логику mutex, используя
другие механизмы синхронизации.
Права доступа
Любой объект в 3OS имеет владельца и ассоциирован с какой либо группой пользователей.
Операции, производимые над объектом, регламентируются правами доступа. Права доступа
устанавливает владелец объекта. Пользователь может установить одни права для себя,
другие для группы, в которую он входит, третьи для всех остальных.
В 3OS существуют такие права доступа:
- Видимость объекта (visible)
Под видимостью объекта понимается возможность узнать о существовании объекта.
Например, право видимости установлено для владельца объекта и группы в которую
он входит. Если это файл, то пользователь не входящий в группу ассоциированную
с владельцем, вообще не сможет узнать о существовании этого файла.
Примечание. Здесь, и далее по тексту, проводятся
параллели с файловой системой в парадигме UNIX. Это сделано для краткости пояснений
и удобства восприятия. Никакого отношения к организации файловых систем 3OS
это не имеет
- Константный доступ к объекту (read)
Этот вид доступа позволяет получить информацию о свойствах объекта, но не позволяет
их изменять
- Изменение свойств объекта (write)
Наличие этого права позволяет изменять свойства объекта, но не позволяет уничтожить
объект.
- Полный доступ к объекту (access)
Имея это право, можно создать/уничтожить объект. Например, если для каталога не
установлено такое право доступа, то в нем нельзя ни создать, ни уничтожить файл,
хотя, возможно, можно читать и записывать существующие файлы
class SecurityAttribute{
public:
bool Visible(void)const;
bool Visible(bool value);
bool Read(void)const;
bool Read(bool value);
bool Write(void)const;
bool Write(bool value);
bool Access(void)const;
bool Access(bool value);
};
Класс SecurityAttribute описывает набор прав доступа:
- константные функции возвращают информацию о соответствующем праве доступа
- функции, устанавливающие право доступа, возвращают информацию об успешном изменении
права доступа:
- если удалось установить право доступа, возвращается true
- если процесс выполняется не от имени владельца, то он не может устанавливать
права доступа
Конструктор этого класса не приводится т. к. пользователь не должен создавать экземпляры
этого класса.
class Security{
public:
SecurityAttribute Owner;
SecurityAttribute Group;
SecurityAttribute Other;
};
Класс Security определяет права доступа к объекту. Конструктор этого класса не
приводится, т. к. пользователь не должен создавать экземпляры этого класса.
Объекты синхронизации
SyncObject
class SyncObject{
public:
Security sa;
virtual SyncObject* Clone(void)=0;
virtual void Close(void)=0;
virtual int Wait(int time_out=WAIT_INFINITE);
const char *GetName(void);
};
Класс SyncObject - базовый класс для всех объектов синхронизации:
- доступ к нему регламентирется правами доступа (sa)
- метод Clone переопределяется в дочерних классах для создания копии ссылки
на объект синхронизации
- метод Close уничтожает ссылку на объект синхронизации
- метод Wait приостанавливает поток до тех пор пока объект не перейдет
в свободное состояние. Параметр time_out определяет время ожидания. Константа
WAIT_INFINITE предполагает бесконечное ожидание, а константа WAIT_TRY - немедленное
возобновление выполнения потока. Другие значения time_out (положительные) определяют
время ожидания в миллисекундах. Метод возвращает WAIT_OK если объект находится
в свободном состоянии и WAIT_BUSY, если в занятом
- метод GetName возвращает указатель на строку содержащую имя объекта синхронизации
Mutex
class Mutex : public SyncObject{
public:
Mutex(const char *name=0);
void Release(void);
};
Класс Mutex реализует логику объекта синхронизации mutex:
- объект этого класса может быть захвачен только одним потоком
- конструктор класса создает объект-ссылку на mutex с именем name. Если mutex
с таким именем не существует, создается новый объект
- метод Release освобождает mutex. Для действительного освобождения mutex
этот метод необходимо вызвать столько раз, сколько вызывался метод Wait
Права доступа для Mutex:
- Visible - процесс может получить ссылку на этот объект
- Read - поток может узнать состояние объекта, но не может его захватить
- Write - поток может захватить объект
- Access - поток может уничтожить объект
Event
class Event : public SyncObject{
public:
Event(const char *name=0);
void Signal(bool to_all=false);
void Busy(void);
};
Класс Event реализует логику триггера:
- объект этого класса может находиться в свободном (signaled) и занятом (busy)
состояниях
- конструктор класса создает объект-ссылку на event с именем name. Если event
с таким именем не существует, создается новый объект
- метод Signal переводит объект в свободное состояние:
- если метод был вызван с параметром true, все потоки, ожидающие переход
этого объекта в свободное состояние, возобновят выполнение, а объект останется
в свободном состоянии
- в противном случае, выполнение возобновит только один поток (на усмотрение
планировщика потоков), а объект остается в занятом состоянии
- если переход объекта в свободное состояние ожидался только одним потоком,
то этот поток возобновляет выполнение, а объект переходит в свободное состояние
- метод Busy переводит объект в занятое состояние
Права доступа для Event:
- Visible - процесс может получить ссылку на этот объект
- Read - поток может узнать состояние объекта и "проснуться" при
переходе объекта в свободное состояние, но не может изменить состояние объекта
(вызовы Signal/Busy)
- Write - поток может изменять состояние объекта
- Access - поток может уничтожить объект
Потоки управления
Потоки управления выполняются в соответствии с их приоритетом. В 3OS основные приоритеты
потоков представлены константами:
- TH_PRIO_IDLE - самый низкий приоритет (screen saver)
- TH_PRIO_LOW - фоновые задачи
- TH_PRIO_NORMAL - обыкновенные приложения
- TH_PRIO_HIGH - приложения требующие быстрой реакции
- TH_PRIO_CRITICAL - драйверы устройств
- TH_PRIO_REALTIME - потоки ядра 3OS (swap-file и т. п.)
Шкала приоритетов потоков не является сплошной. KG могут вводиться дополнительные
приоритеты.
Поток запускается как функция, имеющая такой прототип:
typedef void (*ThreadProc)(Thread*, void*);
class Thread : public SyncObject{
public:
Thread(void);
Thread(int thread_id);
void Resume(void);
void Suspend(void);
int Priority(void)const;
void Priority(int prio);
void Terminate(void);
void Run(ThreadProc thread_proc, void *param);
int GetId(void)const;
int State(void)const;
};
Класс Thread реализует управление потоком:
- конструктор по умолчанию создает объект потока в ядре, а объект класса Thread
является ссылкой на него
- конструктор с параметром thread_id создает объект-ссылку на поток с идентификатором
thread_id
- метод Resume возобновляет выполнение потока
- метод Suspend приотанавливает выполнение потокам
- метод int Priority(void)const возвращает приоритет потока
- метод void Priority(int prio) устанавливает приоритет потока
- метод Terminate уничтожает поток
- метод Run запускает на выполнение функцию потока thread_proc с параметром
param
- метод GetId возвращает внутренний идентификатор потока
- метод State возвращает состояние потока:
- TH_SUSPENDED - поток остановлен
- TH_RUN - поток выполняется
- TH_TERMINATED - поток завершил выполнение
Права доступа для Thread:
- Visible - процесс может получить ссылку на поток
- Read - текущий поток может узнать состояние потока и его приоритет, получить
его внутренний идентификатор
- Write - текущий поток может изменить состояние потока (Suspend, Resume)
- Access - поток может уничтожить объект (Terminate)
Сообщения
class Message{
public:
bool Send(int thread_id, const void *data, int data_size, bool wait=true);
void Reply(int thread_id);
bool Receive(int thread_id, void *buf, int buf_size, int &real_size, int &thread_sender, int time_out);
};
Класс Message инкапсулирует логику передачи/получения сообщений:
- метод Send передает сообщение потоку с внутренним идентификатором thread_id:
- если в качестве параметра wait передается true, то поток приостанавливается
до вызова потоком получателем метода Reply
- если поток получатель не существует или завершил выполнение функция возвращает
false
- метод Reply извещает поток отправитель, что сообщение получено
- метод Receive приостанавливает поток получателя до прихода сообщения
или истечения time_out. time_out задается так же, как в объектах синхронизации.
Если не важен поток-отправитель, то в качестве параметра thread_id задается константа
RECEIVE_ALL. В параметре thread_sender возвращается внутренний идентификатор потока
отправителя
Права доступа для Message:
- Visible - в данном случае это не имеет смысла
- Read - поток может получать сообщения
- Write - поток может отправлять сообщения
- Access - в данном случае это не имеет смысла