Lib-DVM - детальный дизайн (оглавление) Часть 1(1-7) Часть 2 (8-11) Часть 3 (12) (Сообщения об ошибках)
документ от: февраль, 2001 - дата последнего обновления 03.05.01 -

1 Функции и макроопределения общего назначения

1.1 Макроопределения выполнения некоторых математических операций

int dvm_mod(Op, D);

Макроопределение возвращает нулевое значение, если остаток от деления аргумента Op на аргумент D равен нулю, и единичное в противном случае. Аргументы Op и D должны иметь целый тип.

<TypeOfOp> dvm_abs(Op);

Макроопределение возвращает абсолютное значение аргумента Op. Аргумент Op может иметь целый или плавающий тип. Тип возвращаемого значения совпадает с типом аргумента Op.

int dvm_sign(Op);

Макроопределение возвращает 1, если Op > 0, и -1, если Op <= 0. Аргумент Op может иметь целый или плавающий тип.

<TypeOfOp> dvm_min(Op1, Op2);

Макроопределение возвращает минимальное из значений аргументов Op1 и Op2. Каждый из операндов Op1 и Op2 может иметь целый или плавающий тип. Тип возвращаемого значения определяется принятым в языке C правилам преобразования по умолчанию, примененным к операндам Op1 и Op2.

<TypeOfOp> dvm_max(Op1, Op2);

Макроопределение возвращает максимальное из значений аргументов Op1 и Op2. Каждый из операндов Op1 и Op2 может иметь целый или плавающий тип. Тип возвращаемого значения определяется принятым в языке C правилам преобразования по умолчанию, примененным к операндам Op1 и Op2.

1.2 Копирование массивов

void dvm_memcopy ( void
void
unsigned long
*DestPtr,
*SrcPtr,
Size );
     
DestPtr - указатель на область памяти, в которую будет произведено копирование.
SrcPtr - указатель на область памяти, из которой будет осуществлено копирование.
Size - число копируемых байтов.
     
void dvm_ArrayCopy (
<Type>
<Type>
unsigned int
<Type>,
*DestPtr,
*SrcPtr,
Count );
     
Type - тип элементов копируемых массивов.
DestPtr - указатель на первый элемент массива, в который будет произведено копирование.
SrcPtr - указатель на первый элемент массива, из которого будет осуществлено копирование.
Count - число копируемых элементов.

1.3 Вывод верхнего уровня с префиксом в виде номера текущего процессора

int rtl_printf ( char *format, … );
int rtl_fprintf( FILE
char
*stream,
*format, ... );

Функции аналогичны функциям printf и fprintf библиотеки языка C, но выводу заданной информации предшествует вывод номера текущего процессора в виде:

ProcNumberint (ProcNumberext) ,

где:

ProcNumberint - внутренний номер текущего процессора;
ProcNumberext - внешний номер текущего процессора.

Вопрос о номерах процессоров решающего поля рассмотрен в п.4.

int rtl_mprintf ( int
char
ProcNumber,
*format, ... );
int rtl_mfprintf( int
FILE
char
ProcNumber,
*stream,
*format, ... );

Функции аналогичны рассмотренным выше функциям rtl_printf и rtl_fprintf, но вывод осуществляется лишь в том случае, если внутренний номер текущего процессора совпадает с параметром ProcNumber.

Замечание. Функции rtl_printf и rtl_mprintf предназначены для вывода информационных сообщений системы поддержки, которые стандартно направлены в поток stdout (см.п.8).

2 Функции и макроопределения динамического распределения памяти

Рассматриваемые ниже функции и макроопределения отличаются от стандартных функций библиотеки языка C тем, что, во-первых, корректность осуществляемых с их помощью запросов и возвратов памяти контролируется системой поддержки и, во-вторых, выделяемые блоки памяти могут окаймляться слева и справа избыточными частями, расписанными определённым кодом. Последняя особенность предлагаемых функций и макроопределений дает возможность системе поддержки в процессе своего функционирования контролировать содержимое избыточных частей выделенных блоков, что облегчает нахождение ошибок, влекущих незапланированные записи в память.

void *dvm_getmem(unsigned long Size);

Функция выделяет блок памяти размером Size байтов и возвращает указатель на него. Если блок памяти заданного размера выделен быть не может, то выполнение пользовательской программы или системы поддержки завершается с выдачей соответствующей диагностики с помощью функции eprintf (см.п.7).

void *dvm_getmemnoerr(unsigned long Size);

Функция аналогична рассмотренной выше функции dvm_getmem, но при отсутствии блока памяти требуемого размера возвращает NULL.

void *dvm_getclearmem(unsigned long Size);

Функция аналогична рассмотренной выше функции dvm_getmem, но выделяемый блок памяти расписывается нулевым кодом.

void dvm_realloc ( void
unsigned long
**Ptr,
NewSize );

Функция возвращает в свободную память блок памяти, определяемый указателем *Ptr, выделяет новый блок памяти размером NewSize байтов и присваивает его адрес указателю *Ptr. Содержимое старого блока будет сохранено в новом блоке (насколько это позволяет размер NewSize). Если новый блок памяти требуемого размера выделен быть не может, то выполнение задачи пользователя или системы поддержки завершается.

При нулевом значении параметра NewSize выделение нового блока памяти не производится, а указателю *Ptr присваивается значение NULL.

void dvm_reallocnoerr ( void
unsigned long
**Ptr,
NewSize );

Функция аналогична рассмотренной выше функции dvm_realloc, но при отсутствии блока памяти требуемого размера возвращает NULL.

void dvm_freemem(void **Ptr);

Функция возвращает в свободную память блок памяти, определённый указателем *Ptr, и устанавливает значение этого указателя равным NULL. Допустимо обращение к функции с равным NULL значением указателя *Ptr.

void dvm_AllocArray (
unsigned long
<Type>
<Type>,
Size,
*ArrayPtr );

Макроопределение выделяет блок памяти, состоящий из Size элементов типа Type, и присваивает его адрес указателю ArrayPtr. Если блок памяти требуемого размера выделен быть не может, то выполнение программы пользователя или системы поддержки будет прекращено.

void dvm_ReallocArray (
unsigned long
<Type>
<Type>,
NewSize,
*ArrayPtr );

Макроопределение возвращает в свободную память блок памяти, определённый указателем ArrayPtr, выделяет новый блок памяти из NewSize элементов типа Type и присваивает его адрес указателю ArrayPtr. Содержимое старого блока будет сохранено в новом блоке (насколько это позволяет размер NewSize). Если новый блок памяти требуемого размера выделен быть не может, то выполнение пользовательской задачи или системы поддержки будет завершено.

void dvm_FreeArray(void *ArrayPtr);

Макроопределение возвращает в свободную память блок памяти, заданный указателем ArrayPtr, и устанавливает значение этого указателя равным NULL. Допустимо обращение к макроопределению со значением указателя ArrayPtr равным NULL.

void dvm_AllocStruct (
<Type>
<Type>,
*StructPtr );

Макроопределение выделяет блок памяти размера sizeof(Type) байтов и присваивает его адрес указателю StructPtr. Если блок памяти требуемого размера выделен быть не может, то выполнение задачи пользователя или системы поддержки будет прекращено.

void dvm_FreeStruct(void *StructPtr);

Макроопределение возвращает в свободную память блок памяти, заданный указателем StructPtr, и устанавливает значение этого указателя равным NULL. Допустимо обращение к макроопределению со значением указателя StructPtr равным NULL.

3 Опрос времени выполнения программы в независимой от аппаратурно-программной среды форме

double dvm_time(void);

Функция возвращает время выполнения программы в секундах. Отметим, что содержание понятия времени выполнения может быть разным для различных сред.

4 Опрос внутренних номеров функционально выделенных процессоров

Запуск программы пользователя для выполнения на многопроцессорной системе требует задания (в качестве параметров запуска) характеристик многопроцессорной системы как многомерного массива: размерности и размеров по каждому измерению. Пусть размерность многопроцессорной системы задана равной n, а размер по измерению k - равным PSSizek (1 <= k <= n). Тогда при инициализации системы поддержки каждому процессору будет присвоен внутренний номер ProcNumberint:

где Ik - значение индекса процессора по измерению k индексного пространства многопроцессорной системы (0 <= Ik <= PSSizek -1).

То есть, внутренний номер - это линейный индекс процессора в индексном пространстве многопроцессорной системы.

Каждый процессор имеет также внешний номер ProcNumberext (номер процессора в аппаратурно-программной среде, в которой функционирует система поддержки). Внешний номер опрашивается системой поддержки при ее инициализации с помощью средозависимых средств.

При межпроцессорных обменах в качестве адреса процессора используется его идентификатор ProcIdent. Соответствие

ProcNumberint => ProcIdent

возвращается системе поддержки системой передачи сообщений (Message Passing System) при её инициализации.

Среди процессоров выделенного задаче решающего поля функционально выделены три: главный процессор, процессор ввода/вывода и центральный процессор задачи (или просто центральный процессор).

Главный процессор - это первый процессор, на котором была инициализирована параллельная программа (выполняющаяся на нём подзадача рассматривается как инициализатор всех остальных подзадач). Главный процессор имеет нулевой внутренний номер.

Процессор ввода/вывода предназначен для непосредственного общения с файловой системой и имеет нулевой внутренний номер.

Центральный процессор осуществляет вычисление редукционных функций и определяется индексным вектором ([PSSize1 /2] , ... , [PSSizen /2]).

int rtl_GetCurrentProc(void);

Функция возвращает внутренний номер текущего процессора.

int rtl_GetMasterProc(void);

Функция возвращает внутренний номер главного процессора.

int rtl_GetIOProc(void);

Функция возвращает внутренний номер процессора ввода/вывода.

int rtl_GetCentralProc(void);

Функция возвращает внутренний номер центрального процессора.

5 Средства передачи сообщений, независимые от базовой системы передачи сообщений

Совокупность представленных ниже функций является интерфейсным "срезом" между собственно системой поддержки и используемой ею системой передачи сообщений (MPI, PVM и т.д.) и выходит за рамки средств, предоставляемых системой поддержки программе пользователя. Тем не менее, минимальный средонезависимый набор функций передачи сообщений может оказаться полезным для тестовых и экспериментирующих со средой программ, сопровождающих систему поддержки.

В качестве адреса процессора в рассматриваемых ниже функциях используется внутренний номер процессора, который при непосредственном обращении к функциям системы передачи сообщений заменяется на идентификатор процессора (см.п.4). Логика основных схем передачи сообщений (синхронная, асинхронная и схема "NO WAIT") предполагается известной.

Область памяти, предназначенная для передаваемого или принимаемого сообщения, должна быть запрошена динамически с помощью рассмотренных в п. 2 функций.

5.1 Синхронный обмен сообщениями

5.1.1 Синхронная передача

int rtl_Send ( void
int
int
int
*MesPtr,
Count,
Size,
ProcNum );
     
MesPtr - указатель на передаваемое сообщение.
Count - число элементов, содержащихся в передаваемом сообщении.
Size - длина в байтах одного элемента передаваемого сообщения.
ProcNum - внутренний номер процессора, которому посылается сообщение.

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.1.2 Синхронный прием

int rtl_Recv ( void
int
int
int
*MesPtr,
Count,
Size,
ProcNum );
     
MesPtr - указатель области памяти, в которую необходимо принять сообщение.
Count - число элементов, содержащихся в принимаемом сообщении.
Size - длина в байтах одного элемента принимаемого сообщения.
ProcNum - внутренний номер процессора, сообщение от которого требуется принять.

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.2 Асинхронный обмен сообщениями

5.2.1 Асинхронная передача

int rtl_SendA ( void
int
int
int
int
*MesPtr,
Count,
Size,
ProcNum,
Tag );
     
MesPtr - указатель на передаваемое сообщение.
Count - число элементов, содержащихся в передаваемом сообщении.
Size - длина в байтах одного элемента передаваемого сообщения.
ProcNum - внутренний номер процессора, которому посылается сообщение.
Tag - номер класса передаваемого сообщения (классификация сообщений в компетенции пользователя системы передачи сообщений).

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.2.2 Асинхронный прием

int rtl_RecvA ( void
int
int
int
int
*MesPtr,
Count,
Size,
ProcNum,
Tag );
     
MesPtr - указатель области памяти, в которую необходимо принять сообщение.
Count - число элементов, содержащихся в принимаемом сообщении.
Size - длина в байтах одного элемента принимаемого сообщения.
ProcNum - внутренний номер процессора, сообщение от которого требуется принять.
Tag - номер класса принимаемого сообщения.

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.3 Обмен сообщениями в режиме "NO WAIT"

5.3.1 Передача в режиме "NO WAIT"

int rtl_Sendnowait ( void
int
int
int
int
RTL_Request
*MesPtr,
Count,
Size,
ProcNum,
Tag,
*ReqPtr );
     
MesPtr - указатель на передаваемое сообщение.
Count - число элементов, содержащихся в передаваемом сообщении.
Size - длина в байтах одного элемента передаваемого сообщения.
ProcNum - внутренний номер процессора, которому посылается сообщение.
Tag - номер класса передаваемого сообщения (классификация сообщений в компетенции пользователя системы передачи сообщений).
*ReqPtr - структура-признак, который устанавливается в состояние "заявка выполнена", когда сообщение будет доставлено адресату.

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.3.2 Прием в режиме "NO WAIT"

int rtl_Recvnowait ( void
int
int
int
int
RTL_Request
*MesPtr,
Count,
Size,
ProcNum,
Tag,
*ReqPtr );
     
MesPtr - указатель области памяти, в которую необходимо принять сообщение.
Count - число элементов, содержащихся в принимаемом сообщении.
Size - длина в байтах одного элемента принимаемого сообщения.
ProcNum - внутренний номер процессора, сообщение от которого требуется принять.
Tag - номер класса принимаемого сообщения.
*ReqPtr - структура-признак, который устанавливается в состояние "заявка выполнена", когда сообщение поступит по адресу MesPtr.

Возвращается неотрицательное значение при успешном выполнении функции и отрицательное - в противном случае.

5.3.3 Ожидание завершения передачи или приема

void rtl_Waitrequest(RTL_Request *ReqPtr);

*ReqPtr - структура-признак, от которого ожидается состояние "заявка выполнена".

5.3.4 Опрос завершения передачи или приема

int rtl_Testrequest(RTL_Request *ReqPtr);

*ReqPtr - структура-признак, от которого ожидается состояние "заявка выполнена".

Возвращается значение:

0 - пересылка сообщения не завершена (*ReqPtr не установлен в состояние "заявка выполнена");
1 - пересылка сообщения завершена (*ReqPtr установлен в состояние "заявка выполнена").

5.4 Передача сообщения от заданного процессора всем остальным (широковещательная передача)

int rtl_BroadCast ( void
int
int
int
PSRef
*MesPtr,
Count,
Size,
SenderProcNum,
*PSRefPtr );
     
MesPtr - указатель на передаваемое сообщение или указатель области памяти, в которую необходимо принять сообщение.
Count - число элементов, содержащихся в сообщении.
Size - длина в байтах одного элемента сообщения.
SenderProcNum - внутренний номер посылающего процессора.
*PSRefPtr - ссылка на процессорную систему, процессорам которой осуществляется передача.

Функция осуществляет передачу, если внутренний номер текущего процессора равен SenderProcNum, и приём - в противном случае.

Все процессоры системы, заданной параметром PSRefPtr, должны принадлежать текущей процессорной системе. Равное NULL значение указателя PSRefPtr или нулевое значение ссылки *PSRefPtr задают текущую процессорную систему.

Процессор с номером SenderProcNum не обязан входить в состав процессорной системы, заданной ссылкой *PSRefPtr, но должен принадлежать текущей процессорной системе.

6 Синхронизация программ, выполняющихся на разных процессорах

long bsynch_(void);

Выполнение функции заключается в том, что центральный процессор (см.п.4) принимает синхросообщения от всех остальных процессоров, а затем рассылает им синхросообщения-ответы. Любой другой процессор передает синхросообщение центральному процессору, после чего принимает от него синхросообщение-ответ. Синхросообщение - это слово (integer), содержимое которого несущественно.

Функция возвращает нулевое значение.

long tsynch_(void);

Функция tsynch_, как и функция bsynch_, выполняет барьерную синхронизацию процессоров текущей процессорной системы, но дополнительно производит выравнивание времен процессоров. Под выравниванием времен понимаются такие действия системы поддержки, в результате которых функция dvm_time (см.п.3) в один и тот же момент астрономического времени будет возвращать на всех процессорах одно и то же время - время, возвращаемое функцией dvm_time на центральном процессоре задачи до выполнения функции tsynch_ .

Выравнивание времен осуществляется следующим образом. Пусть центральный процессор в момент времени t1 (по своему датчику времени) посылает сообщение процессору P, находящемуся в состоянии приёма этого сообщения. Процессор P, получив сообщение от центрального, посылает ему время приёма этого сообщения T (по своему датчику времени). Центральный процессор, отослав сообщение процессору P, переходит к приёму от него сообщения со временем T и принимает его в момент времени t2 по своему датчику времени. После этого центральный процессор отсылает процессору P время (t1+t2)/2 - T , которое при выполнении им функции dvm_time всегда будет добавляться к показанию его датчика времени.

Такая операция осуществляется центральным процессором со всеми остальными процессорами. Чтобы избежать случайных помех, операция выравнивания времен повторяется несколько раз, и для каждого процессора в качестве результата принимается та величина (t1+t2)/2 - T, для которой время передачи сообщения, равное (t1-t2)/2, минимально.

Функция возвращает нулевое значение.

7 Трассировка программы пользователя и системы поддержки

7.1 Общие сведения о накоплении информации трассировки

Будем называть внутренним событием (или просто событием) выполнение определённой точки или участка пользовательской программы или системы поддержки при определённых условиях. Системная трассировка является накоплением информации о происходящих событиях в их временной последовательности.

Событиями являются обращения ко всем функциям системы поддержки, доступным программе пользователя. Кроме того, прохождение некоторых внутренних участков системы поддержки и обращения к части ее внутренних функций также являются событиями. Примером трассируемых внутренних функций могут служить функции доступа к коммуникационным библиотекам. Трассируемое обращение к функции влечет трассировку и возврата из неё.

Полный список событий трассировки содержится в файле events.def исходных текстов системы поддержки, в котором имени каждого события сопоставлен его номер. Событие обращения к функции имеет имя call_<имя функции>, а событие возврата из неё - имя ret_<имя функции>.

Трассировка каждого события может быть включена и выключена по его номеру.

Накапливаемая при трассировке информация содержит также все информационные сообщения системы поддержки и все сообщения об обнаруженных ею ошибках (см. п.8).

Накопление трассировочной информации система поддержки осуществляет с помощью функций, рассмотренных в п.7.3. Информация, выводимая этими функциями в текстовом виде, может поступать в три независимо включаемых (открываемых) и выключаемых (закрываемых) потока трассировки:

Трассировка в поток информационных сообщений осуществляется согласно общим правилам управления выводом информационных сообщений (см.п.8). Информация, поступающая в этот поток, не содержит информационных сообщений и сообщений об ошибках системы поддержки.

При трассировке в буфер оперативной памяти информация накапливается в буфере каждого процессора до завершения выполнения программы, а затем выгружается в файл (свой для каждого процессора). Инициализация буферов трассировки производится при инициализации системы поддержки.

Трассировка в буфер предусматривает два варианта. В первом исчерпание размера буфера влечет останов трассировки (вариант сохранения начала трассировки). Второй вариант обеспечивает сохранение последней информации за счет уничтожения наиболее старой (вариант трассировки "по кольцу").

Трассировка в файл осуществляется выводом информации непосредственно в свой для каждого процессора файл по мере ее поступления. Файлы для непосредственного вывода трассировки открываются при инициализации системы поддержки и закрываются при завершении выполнения программы.

Все файлы с накопленной трассировкой система поддержки помещает в одну директорию (как при трассировке в буфер, так и при трассировке непосредственно в файлы). Имя этой директории, а также расширения файлов для каждого потока задаются в файле параметров systrace.* (см. п.7.2.2). Имена файлов с трассировкой имет вид <внутренний номер процессора>_<внешний номер процессора>.

Состав накапливаемой при трассировке информации определяется режимом трассировки. При кратком режиме выводится:

При подробном режиме трассировки сохраняемая информация расширяется и зависит от типа события. Если событием является обращение к функции, то выводятся ее входные параметры. При возврате из функции выводятся ее выходные параметры. Для каждого события может быть задан подробный режим трассировки вне зависимости от общего режима.

Замечание. Системная трассировка функционирует только при ненулевом значении параметра Is_DVM_TRACE, содержащегося в файлах systrace.* (см. п. 7.2.1). Часть функций, тем не менее, при этом не трассируется. К таким функциям относятся функции, требующие высокой эффективности выполнения из-за предполагаемой большой частоты обращений к ним (например, функция tstelm_ проверки принадлежности заданного элемента распределённого массива его локальной части). Включение трассировки такого рода функций осуществляется заданием ненулевого значения параметра Is_ALL_TRACE (файлы systrace.*). Кроме того, для трассировки функций обращения к DVM-отладчику необходимо задание ненулевого значения параметра Is_DEB_TRACE, а для трассировки функций обращения к подсистеме сбора инфомации для анализа производительности – ненулевого значения параметра Is_STAT_TRACE (см. п. 7.2.1).

7.2 Управление накоплением трассировки с помощью файлов параметров

Управление режимами трассировки и составом трассируемых событий осуществляется с помощью параметров, содержащихся в файлах systrace.* и trcevent.* . Рассмотрим основные из них. По умолчанию считается, что параметр содержится в файлах systrace.* .

7.2.1 Включение и выключение трассировки

7.2.2 Задание открытых (включенных) потоков трассировки

7.2.3 Задание режимов трассировки

7.2.4 Управление формой накапливаемой информации

7.2.5 Управление механизмами внутреннего самоконтроля системы поддержки, функционирующими при накоплении трассировки

В процессе накопления трассировочной информации система поддержки может контролировать определённые области оперативной памяти, при изменении содержимого которых она завершает выполнение программы с выводом соответствующего сообщения об ошибке. К таким областям относятся:

Контрольные части динамически запрашиваемых блоков памяти создаются при специальном указании в файлах параметров sysdebug.* и расписываются задаваемым там же кодом при выделении блока. Контроль их содержимого может осуществляться при каждом запросе и освобождении блока памяти, а также в процессе трассировки.

Явно задаваемая область памяти контролируется путем сравнения ее эталонной контрольной суммы с текущей. Эталонная контрольная сумма вычисляется при инициализации системы поддержки.

Начальный и конечный адреса области памяти с программным кодом задаются программой, запускающей на выполнение систему поддержки, посредством записи этих адресов в ее (системы поддержки) исполняемый модуль. Эта же программа вычисляет и записывает в исполняемый модуль системы поддержки эталонную контрольную сумму памяти команд. Система поддержки в процессе своего функционирования (в частности, по событиям трассировки) контролирует память команд, сравнивая ее текущую контрольную сумму с эталонной.

Управление механизмами контроля областей памяти осуществляется с помощью следующих параметров файлов systrace.* .

Кроме рассмотренных выше средств контроля заданных областей памяти, система поддержки предоставляет также возможность вывода в трассировку значения заданной переменной, управляемого следующими параметрами файлов systrace.* :

Адрес переменной может задаваться в десятичном или шестнадцатеричном виде (по правилам языка C). При нулевом значении адреса вывод переменной в трассировку не осуществляется.

Номер типа переменной может принимать значения:

  1. int;
  2. long;
  3. float;
  4. double;
  5. char;
  6. short.

При указания номера типа, отличающегося от перечисленных выше, вывод переменной в трассировку не производится.

7.2.6 Управление выводом дополнительной информации при трассировке некоторых функций системы поддержки в расширенном режиме

0 - не выводить дополнительной информации;
1 - выводить выходные начальные и конечные значения индексных переменных параллельного цикла для текущего процессора;
2 - дополнительно выводить карту отображения цикла.

7.3 Функции вывода информации в потоки трассировки

Вывод информации в потоки трассировки осуществляется с помощью следующих функций (параметр format и следующие за ним параметры аналогичны соответствующим параметрам функции printf библиотеки языка C).

int tprintf (char *format, ... );

Функция осуществляет вывод информации во все открытые потоки трассировки. Возвращается число выведенных символов.

int pprintf ( int
char
prefix,
*format, ... );

Функция выводит информацию в открытые потоки трассировки, направленные в буфер оперативной памяти и непосредственно в файл. Кроме того, вывод производится в потоки, предназначенные для вывода информационных сообщений системы поддержки (параметр prefix равен 0 или 1), либо в потоки, предназначенные для вывода сообщений об ошибках (prefix равен 2 или 3) (см.п.8).

При значении параметра prefix, равном 1 или 3, вывод осуществляет каждый процессор решающего поля, предваряя заданную информацию своим номером (см.п.1.3 и п.4). Если значение prefix равно 0 или 2, то вывод информации в потоки трассировки осуществляет каждый процессор решающего поля, а в остальные потоки - только главный процессор (см.п.4). Предварительный вывод номера процессора в этом случае не производится.

Возвращается число выведенных символов.

void dvm_trace ( int
char
number,
*format, ... );

Функция выводит информацию о состоявшемся событии с номером number во все открытые потоки трассировки. Выводимая информация состоит из:

Стандартная информация включает в себя:

Фактический вывод информации в потоки трассировки происходит лишь в том случае, если событие с номером number включено.

Вывод дополнительной информации осуществляется только в расширенном режиме трассировки или при задании такого режима отдельно для события с номером number.

Имя файла и номер строки, определяющие точку произошедшего события, сообщаются программе трассировки макровызовом DVM_CALL. Название макроса проистекает из того, что все события трассировки, за несколькими исключениями, - это вызовы функций системы поддержки. Если событие произошло внутри системы поддержки и событием является обращение к функции, то используется макровызов RTL_CALL. Макровызовы DVM_CALL и RTL_CALL должны исполнительно предшествовать событию и максимально к нему приближены (по расположению в файле с программой). Таким образом, трассировка событий осуществляется по следующей схеме:

DVM_CALL; (или RTL_CALL;)
……………………..
< точка наступившего события >
..................................
dvm_trace( ........ );

Трассировка функций системы поддержки организована таким образом, что обращение к dvm_trace происходит внутри трассируемой функции. Наиболее предпочтительным способом использования макровызовов DVM_CALL и RTL_CALL при трассировке функций является применение операции последовательного вычисления:

( DVM_CALL , < обращение к функции > )

или

( RTL_CALL , < обращение к функции > ) .

В этом случае номер строки, сообщаемый программе трассировки, будет точно равен номеру строки наступившего события (обращения к функции), а обращение к функции в любом выражении языка C может быть эквивалентно заменено на какую-либо из вышеприведенных конструкций.

Замечание. Имя файла и номер строки, определяющие точку наступившего события, могут быть сообщены системе поддержки также с помощью функций

long fname_ ( char
long
*FileNamePtr,
FileNameLength );
long lnumb_ ( long *LineNumberPtr );
     
FileNamePtr - указатель на текстовую строку с именем файла.
FileNameLength - длина строки с именем файла в байтах.
*LineNumberPtr - номер строки.

При выполнении функции fname_ последнему байту строки с именем файла будет присвоено нулевое значение. Функции возвращают нулевые значения.

Данные функции могут быть использованы препроцессорными программами для "привязки" точки предполагаемого события к своему входному тексту.

Отметим, что последовательность обращений

long line;
..............................
..............................
line = __LINE__ ;
fname_ ( __FILE__ ,
strlen(__FILE__)+1 ) ;
lnumb_ ( &line ) ;

эквивалентна макровызову

DVM_CALL ; .

void eprintf ( char
int
char
*FileNamePtr,
Line,
*format, . . . );

Функция выводит информацию в открытые потоки трассировки, направленные в буфер оперативной памяти и непосредственно в файл, а также в потоки, предназначенные для сообщений об ошибках (см.п.8), после чего завершает выполнение программы пользователя и системы поддержки. Информации, выводимой в потоки, предназначенные для сообщений об ошибках, предшествует вывод номера текущего процессора.

После вывода информации, заданной параметром format и последующими параметрами (если таковые имеются), выводятся строка, заданная указателем FileNamePtr и целое число, заданное параметром Line. Предполагается, что выводимые строка и число - это имя файла и номер строки, содержащие данное обращение к функции eprintf, то есть, что обращение к eprintf имеет вид:

eprintf(__FILE__ , __LINE__ , format , . . . );

Кроме того, функция eprintf выводит координаты точки программы пользователя, из которой произошло последнее обращение к системе поддержки (имя файла и номер строки).

void epprintf ( int
char
int
char
prefix,
*FileNamePtr,
Line,
*format, . . . );

Функция аналогична рассмотренной выше функции eprintf , но при нулевом значении параметра prefix вывод информации в потоки, предназначенные для сообщений об ошибках, осуществляет только главный процессор (см. п.4). Номер текущего процессора в этом случае не выводится.


Lib-DVM - детальный дизайн (оглавление) Часть 1(1-7) Часть 2 (8-11) Часть 3 (12) (Сообщения об ошибках)