uIP 1.0
C:/asm/STM32-ethernet/ENC28J60prj/uip-master/uip/pt.h
См. документацию.
00001 /*
00002  * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
00003  * Все права зарезервированы. *
00004  * Повторное распространение, использование в исходном и двоичном виде,
00005  * с модификацией или без - разрешается, если выполняются следующие
00006  * условия:
00007  * 1. Распространение исходного кода должно сохранить вышеуказанную пометку
00008  *    копирайта, этот список условий и следующую правовую оговорку.
00009  * 2. Распространение исходного кода должно сохранить вышеуказанную пометку
00010  *    копирайта, этот список условий и следующую правовую оговорку в
00011  *    документации и/или других материалах, которые будут предоставлены
00012  *    вместе с распространяемыми материалами.
00013  * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть
00014  *    продукты, написанные с использованием этого программного обеспечения
00015  *    без специального на то разрешения.
00016  *
00017  * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ
00018  * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ,
00019  * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ
00020  * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН
00021  * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ
00022  * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ
00023  * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ;
00024  * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ,
00025  * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ
00026  * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ
00027  * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ
00028  * ТАКОГО ПОВРЕЖДЕНИЯ.
00029  *
00030  * Этот файл является частью стека uIP TCP/IP.
00031  *
00032  * Author: Adam Dunkels <adam@sics.se>
00033  *
00034  * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
00035  */
00036 
00037 /**
00038  * \addtogroup pt
00039  * @{
00040  */
00041 
00042 /**
00043  * \file
00044  * Реализация protothread-ов.
00045  * \author
00046  * Adam Dunkels <adam@sics.se>
00047  *
00048  */
00049 
00050 #ifndef __PT_H__
00051 #define __PT_H__
00052 
00053 #include "lc.h"
00054 
00055 struct pt {
00056   lc_t lc;
00057 };
00058 
00059 #define PT_WAITING 0
00060 #define PT_EXITED  1
00061 #define PT_ENDED   2
00062 #define PT_YIELDED 3
00063 
00064 /**
00065  * \name Initialization
00066  * @{
00067  */
00068 
00069 /**
00070  * Инициализация protothread.
00071  *
00072  * Инициализирует protothread. Инициализация должна быть выполнена до начала
00073  * выполнения protothread.
00074  *
00075  * \param pt Указатель на protothread control structure (структура управления).
00076  *
00077  * \sa PT_SPAWN()
00078  *
00079  * \hideinitializer
00080  */
00081 #define PT_INIT(pt)   LC_INIT((pt)->lc)
00082 
00083 /** @} */
00084 
00085 /**
00086  * \name Декларация и определение
00087  * @{
00088  */
00089 
00090 /**
00091  * Декларация protothread.
00092  *
00093  * Этот макрос используется для декларации protothread. Все protothread-ы должны
00094  * быть задекларированы с помощью этого макроса.
00095  *
00096  * \param name_args Имя и аргументы функции C, реализующей protothread.
00097  *
00098  * \hideinitializer
00099  */
00100 #define PT_THREAD(name_args) char name_args
00101 
00102 /**
00103  * Декларирует начало protothread внутри функции C, реализующей protothread.
00104  *
00105  * Этот макрос используется для декларирования стартовой точки для
00106  * protothread. Она должна быть размещена в начале функции, в которой
00107  * запускается protothread. Все операторы C до вызова PT_BEGIN()
00108  * будут выполнены каждый раз, когда назначается шедулинг для protothread.
00109  *
00110  * \param pt Указатель на protothread control structure.
00111  *
00112  * \hideinitializer
00113  */
00114 #define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
00115 
00116 /**
00117  * Декларируется конец для protothread.
00118  *
00119  * Этот макрос используется для декларирования места, где заканчивается 
00120  * protothread. Он должен всегда использоваться совместно с соответствующим 
00121  * парным вызовом макроса PT_BEGIN().
00122  *
00123  * \param pt Указатель на protothread control structure.
00124  *
00125  * \hideinitializer
00126  */
00127 #define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
00128                    PT_INIT(pt); return PT_ENDED; }
00129 
00130 /** @} */
00131 
00132 /**
00133  * \name Блокирующее ожидание.
00134  * @{
00135  */
00136 
00137 /**
00138  * Блокирует выполнения и ждет, пока условие не станет true.
00139  *
00140  * Этот макрос блокирует выполнение protothread, пока указанное условие не
00141  * станет равным true.
00142  *
00143  * \param pt Указатель на protothread control structure.
00144  * \param condition Условие.
00145  *
00146  * \hideinitializer
00147  */
00148 #define PT_WAIT_UNTIL(pt, condition)            \
00149   do {                                          \
00150     LC_SET((pt)->lc);                           \
00151     if(!(condition)) {                          \
00152       return PT_WAITING;                        \
00153     }                                           \
00154   } while(0)
00155 
00156 /**
00157  * Блокировка и ожидание, пока условие true.
00158  *
00159  * Эта функция блокирует выполнение и ждет, пока условие в состоянии true.
00160  * См. также PT_WAIT_UNTIL().
00161  *
00162  * \param pt Указатель на protothread control structure.
00163  * \param cond Условие.
00164  *
00165  * \hideinitializer
00166  */
00167 #define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
00168 
00169 /** @} */
00170 
00171 /**
00172  * \name Иераржия protothread-ов
00173  * @{
00174  */
00175 
00176 /**
00177  * Блокирует и ждет, пока не завершится дочерний protothread.
00178  *
00179  * Этот макрос запускает шедулинг дочернего protothread. Текущий protothread
00180  * будет заблокирован, пока дочерний protothread не завершится.
00181  *
00182  * \note Дочерний protothread должен быть инициализирован вручную функцией
00183  * PT_INIT() до того, как будет использована функция PT_SPAWN.
00184  *
00185  * \param pt Указатель на protothread control structure.
00186  * \param thread Дочерний protothread с аргументами.
00187  *
00188  * \sa PT_SPAWN()
00189  *
00190  * \hideinitializer
00191  */
00192 #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
00193 
00194 /**
00195  * Порождает дочерний protothread и ждет выхода из него.
00196  *
00197  * Этот макрос порождает дочерний protothread и ждет, пока он не выполнит
00198  * выход. Макрос может быть использован только в пределах protothread.
00199  * macro can only be used within a protothread.
00200  *
00201  * \param pt Указатель на protothread control structure.
00202  * \param child Указатель на protothread control structure дочернего protothread.
00203  * \param thread Дочерний protothread с аргументами.
00204  *
00205  * \hideinitializer
00206  */
00207 #define PT_SPAWN(pt, child, thread)             \
00208   do {                                          \
00209     PT_INIT((child));                           \
00210     PT_WAIT_THREAD((pt), (thread));             \
00211   } while(0)
00212 
00213 /** @} */
00214 
00215 /**
00216  * \name Выход и рестарт
00217  * @{
00218  */
00219 
00220 /**
00221  * Делает рестарт для protothread.
00222  *
00223  * Этот макрос заблокирует и перезапустит работающий protothread
00224  * с того места, где стоит вызов PT_BEGIN().
00225  *
00226  * \param pt Указатель на protothread control structure.
00227  *
00228  * \hideinitializer
00229  */
00230 #define PT_RESTART(pt)                          \
00231   do {                                          \
00232     PT_INIT(pt);                                \
00233     return PT_WAITING;                  \
00234   } while(0)
00235 
00236 /**
00237  * Выход из protothread.
00238  *
00239  * Этот макрос производит выход из protothread. Если protothread был
00240  * порожден другим protothread, то родительский protothread станет
00241  * разблокированным и сможет продолжить работу.
00242  *
00243  * \param pt Указатель на protothread control structure.
00244  *
00245  * \hideinitializer
00246  */
00247 #define PT_EXIT(pt)                             \
00248   do {                                          \
00249     PT_INIT(pt);                                \
00250     return PT_EXITED;                   \
00251   } while(0)
00252 
00253 /** @} */
00254 
00255 /**
00256  * \name Вызов protothread
00257  * @{
00258  */
00259 
00260 /**
00261  * Шедулинг для protothread.
00262  *
00263  * Эта функция осуществляет шедулинг для protothread. Возвращаемое значение
00264  * функции не рано 0, если protothread работает, или 0, если protothread 
00265  * сделал выход.
00266  *
00267  * \param f Вызов C-функции, которая реализует шедулинг для protothread.
00268  *
00269  * \hideinitializer
00270  */
00271 #define PT_SCHEDULE(f) ((f) == PT_WAITING)
00272 
00273 /** @} */
00274 
00275 /**
00276  * \name Уступка контекста (Yielding) из protothread
00277  * @{
00278  */
00279 
00280 /**
00281  * Уступка контекста управления (Yield) из текущего protothread.
00282  *
00283  * Эта функция уступает процессорное время этого protothread, что позволяет
00284  * другим protothread выполняться в системе.
00285  *
00286  * \param pt Указатель на protothread control structure.
00287  *
00288  * \hideinitializer
00289  */
00290 #define PT_YIELD(pt)                            \
00291   do {                                          \
00292     PT_YIELD_FLAG = 0;                          \
00293     LC_SET((pt)->lc);                           \
00294     if(PT_YIELD_FLAG == 0) {                    \
00295       return PT_YIELDED;                        \
00296     }                                           \
00297   } while(0)
00298 
00299 /**
00300  * \brief      Делает уступку процессорного времени из protothread, пока не
00301  *             не будет выполнено условие.
00302  * \param pt   Указатель на protothread control structure.
00303  * \param cond Условие.
00304  *
00305  *             Эта функция будет приводить к уступке процессорного времени 
00306  *             для этого protothread, пока указанное условие вычисляется
00307  *             как true.
00308  *
00309  *
00310  * \hideinitializer
00311  */
00312 #define PT_YIELD_UNTIL(pt, cond)                \
00313   do {                                          \
00314     PT_YIELD_FLAG = 0;                          \
00315     LC_SET((pt)->lc);                           \
00316     if((PT_YIELD_FLAG == 0) || !(cond)) {       \
00317       return PT_YIELDED;                        \
00318     }                                           \
00319   } while(0)
00320 
00321 /** @} */
00322 
00323 #endif /* __PT_H__ */
00324 
00325 /** @} */