home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume27 / clc / part15 < prev    next >
Encoding:
Text File  |  1993-11-28  |  29.0 KB  |  897 lines

  1. Newsgroups: comp.sources.unix
  2. From: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v27i121: clc - C Libraries Collection, Part15/20
  4. References: <1.754527080.23891@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: panos@anchor.cs.colorado.edu (Panos Tsirigotis)
  9. Posting-Number: Volume 27, Issue 121
  10. Archive-Name: clc/part15
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 15 (of 20)."
  19. # Contents:  libs/src/dict/dll.c libs/src/timer/STATES
  20. #   libs/src/timer/timer.3
  21. # Wrapped by panos@eclipse on Sun Nov 28 14:48:17 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'libs/src/dict/dll.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'libs/src/dict/dll.c'\"
  25. else
  26. echo shar: Extracting \"'libs/src/dict/dll.c'\" \(8638 characters\)
  27. sed "s/^X//" >'libs/src/dict/dll.c' <<'END_OF_FILE'
  28. X/*
  29. X * (c) Copyright 1993 by Panagiotis Tsirigotis
  30. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  31. X * and conditions for redistribution.
  32. X */
  33. X
  34. Xstatic char RCSid[] = "$Id: dll.c,v 3.3 93/09/28 21:07:56 panos Exp $" ;
  35. X
  36. X#include "dllimpl.h"
  37. X
  38. X
  39. Xdict_h dll_create( oo_comp, ko_comp, flags, errnop )
  40. X    dict_function    oo_comp ;                    /* object-object comparator */
  41. X    dict_function    ko_comp ;                    /* key-object comparator */
  42. X    int                flags ;
  43. X    int                *errnop ;
  44. X{
  45. X    header_s            *hp ;
  46. X    char                *id = "dll_create" ;
  47. X
  48. X    if ( ! __dict_args_ok( id,
  49. X                flags, errnop, oo_comp, ko_comp, DICT_ORDERED + DICT_UNORDERED ) )
  50. X        return( NULL_HANDLE ) ;
  51. X
  52. X    hp = (header_s *) malloc( sizeof( header_s ) ) ;
  53. X    if ( hp == NULL )
  54. X        return( __dict_create_error( id, flags, errnop, DICT_ENOMEM ) ) ;
  55. X    
  56. X    /*
  57. X     * Create an allocator
  58. X     */
  59. X    hp->alloc = fsm_create( sizeof( node_s ), 0,
  60. X                ( flags & DICT_RETURN_ERROR ) ? FSM_RETURN_ERROR : FSM_NOFLAGS ) ;
  61. X    if ( hp->alloc == NULL )
  62. X    {
  63. X        free( (char *)hp ) ;
  64. X        return( __dict_create_error( id, flags, errnop, DICT_ENOMEM ) ) ;
  65. X    }
  66. X    
  67. X    /*
  68. X     * Allocate and initialize head node
  69. X     */
  70. X    hp->head = (node_s *) fsm_alloc( hp->alloc ) ;
  71. X    if ( hp->head == NULL )
  72. X    {
  73. X        fsm_destroy( hp->alloc ) ;
  74. X        free( (char *)hp ) ;
  75. X        return( __dict_create_error( id, flags, errnop, DICT_ENOMEM ) ) ;
  76. X    }
  77. X
  78. X    NEXT( hp->head ) = PREV( hp->head ) = hp->head ;
  79. X    OBJ( hp->head ) = NULL ;
  80. X
  81. X    /*
  82. X     * Initialize dictionary header, hints
  83. X     */
  84. X    __dict_init_header( DHP( hp ), oo_comp, ko_comp, flags, errnop ) ;
  85. X    HINT_CLEAR( hp, last_search ) ;
  86. X    HINT_CLEAR( hp, last_successor ) ;
  87. X    HINT_CLEAR( hp, last_predecessor ) ;
  88. X
  89. X    return( (dict_h) hp ) ;
  90. X}
  91. X
  92. X
  93. Xvoid dll_destroy( handle )
  94. X    dict_h        handle ;
  95. X{
  96. X    header_s        *hp = LHP( handle ) ;
  97. X
  98. X    fsm_destroy( hp->alloc ) ;
  99. X    free( (char *)hp ) ;
  100. X}
  101. X
  102. X
  103. X
  104. XPRIVATE int dll_do_insert( hp, must_be_uniq, object, objectp )
  105. X    register header_s        *hp ;
  106. X    bool_int                    must_be_uniq ;
  107. X    register dict_obj        object ;
  108. X    dict_obj                    *objectp ;
  109. X{
  110. X    register dheader_s    *dhp                = DHP( hp ) ;
  111. X    register bool_int     unordered_list = ( dhp->flags & DICT_UNORDERED ) ;
  112. X    register node_s        *np ;
  113. X    node_s                    *new ;
  114. X    node_s                    *before, *after ;
  115. X    char                        *id = "dll_do_insert" ;
  116. X
  117. X    if ( object == NULL )
  118. X        HANDLE_ERROR( dhp, id, DICT_ENULLOBJECT, DICT_ERR ) ;
  119. X
  120. X    if ( unordered_list && ! must_be_uniq )
  121. X        np = NEXT( hp->head ) ;
  122. X    else
  123. X    {
  124. X        /*
  125. X         * Find node n such that key(OBJ(n)) >= key(object)
  126. X         */
  127. X        for ( np = NEXT( hp->head ) ; np != hp->head ; np = NEXT( np ) )
  128. X        {
  129. X            register int v = (*dhp->oo_comp)( OBJ( np ), object ) ;
  130. X
  131. X            if ( v > 0 && ! unordered_list )
  132. X                break ;
  133. X            if ( v == 0 )
  134. X                if ( must_be_uniq )
  135. X                {
  136. X                    if ( objectp != NULL )
  137. X                        *objectp = OBJ( np ) ;
  138. X                    ERRNO( dhp ) = DICT_EEXISTS ;
  139. X                    return( DICT_ERR ) ;
  140. X                }
  141. X                else
  142. X                    break ;
  143. X        }
  144. X    }
  145. X
  146. X    new = (node_s *) fsm_alloc( hp->alloc ) ;
  147. X    if ( new == NULL )
  148. X        HANDLE_ERROR( dhp, id, DICT_ENOMEM, DICT_ERR ) ;
  149. X
  150. X    /*
  151. X     * The new node is inserted BEFORE np
  152. X     */
  153. X    before = PREV( np ) ;
  154. X    after = np ;
  155. X    NEXT( new ) = after ;
  156. X    PREV( new ) = before ;
  157. X    NEXT( before ) = new ;
  158. X    PREV( after ) = new ;
  159. X    OBJ( new ) = object ;
  160. X    if ( objectp != NULL )
  161. X        *objectp = object ;
  162. X    return( DICT_OK ) ;
  163. X}
  164. X
  165. X
  166. Xint dll_insert( handle, object )
  167. X    dict_h        handle ;
  168. X    dict_obj        object ;
  169. X{
  170. X    header_s        *hp = LHP( handle ) ;
  171. X
  172. X    return( dll_do_insert( hp, hp->dh.flags & DICT_UNIQUE_KEYS,
  173. X                    object, (dict_obj *)NULL ) ) ;
  174. X}
  175. X
  176. X
  177. X
  178. Xint dll_insert_uniq( handle, object, objectp )
  179. X    dict_h        handle ;
  180. X    dict_obj        object ;
  181. X    dict_obj        *objectp ;
  182. X{
  183. X    header_s        *hp    = LHP( handle ) ;
  184. X    dheader_s    *dhp    = DHP( hp ) ;
  185. X
  186. X    if ( dhp->oo_comp == NULL_FUNC )
  187. X        HANDLE_ERROR( dhp, "dll_insert_uniq", DICT_ENOOOCOMP, DICT_ERR ) ;
  188. X    return( dll_do_insert( hp, TRUE, object, objectp ) ) ;
  189. X}
  190. X
  191. X
  192. Xint dll_delete( handle, object )
  193. X    dict_h                handle ;
  194. X    register dict_obj object ;
  195. X{
  196. X    register header_s *hp    = LHP( handle ) ;
  197. X    dheader_s            *dhp    = DHP( hp ) ;
  198. X    register node_s    *np ;
  199. X    node_s                *after, *before ;
  200. X
  201. X    if ( object == NULL )
  202. X        HANDLE_ERROR( dhp, "dll_delete", DICT_ENULLOBJECT, DICT_ERR ) ;
  203. X
  204. X    if ( OBJ( hp->hint.last_search ) == object )
  205. X        np = hp->hint.last_search ;
  206. X    else
  207. X        for ( np = NEXT( hp->head ) ;; np = NEXT( np ) )
  208. X            if ( np == hp->head )
  209. X            {
  210. X                ERRNO( dhp ) = DICT_ENOTFOUND ;
  211. X                return( DICT_ERR ) ;
  212. X            }
  213. X            else if ( object == OBJ( np ) )
  214. X                break ;
  215. X
  216. X    /*
  217. X     * First disconnect, then release
  218. X     */
  219. X    after = NEXT( np ) ;
  220. X    before = PREV( np ) ;
  221. X    NEXT( before ) = after ;
  222. X    PREV( after ) = before ;
  223. X    OBJ( np ) = NULL ;
  224. X    fsm_free( hp->alloc, (char *)np ) ;
  225. X
  226. X    /*
  227. X     * Clear all hints
  228. X     */
  229. X    HINT_CLEAR( hp, last_search ) ;
  230. X    HINT_CLEAR( hp, last_successor ) ;
  231. X    HINT_CLEAR( hp, last_predecessor ) ;
  232. X
  233. X    return( DICT_OK ) ;
  234. X}
  235. X
  236. X
  237. Xdict_obj dll_search( handle, key )
  238. X    dict_h                    handle ;
  239. X    register dict_key        key ;
  240. X{
  241. X    register header_s        *hp                = LHP( handle ) ;
  242. X    register dheader_s    *dhp                = DHP( hp ) ;
  243. X    register bool_int        unordered_list    = ( dhp->flags & DICT_UNORDERED ) ;
  244. X    register node_s        *np ;
  245. X
  246. X    for ( np = NEXT( hp->head ) ; np != hp->head ; np = NEXT( np ) )
  247. X    {
  248. X        register int v = (*dhp->ko_comp)( key, OBJ( np ) ) ;
  249. X
  250. X        if ( v == 0 )
  251. X        {
  252. X            hp->hint.last_search = np ;        /* update search hint */
  253. X            return( OBJ( np ) ) ;
  254. X        }
  255. X        else if ( v < 0 && ! unordered_list )
  256. X            break ;
  257. X    }
  258. X    return( NULL_OBJ ) ;
  259. X}
  260. X
  261. X
  262. X/*
  263. X * Returns a pointer to the object with the smallest key value or
  264. X * NULL if the list is empty.
  265. X *
  266. X * NOTE: here we depend on the fact that OBJ( head ) == NULL
  267. X */
  268. Xdict_obj dll_minimum( handle )
  269. X    dict_h        handle ;
  270. X{
  271. X    header_s        *hp = LHP( handle ) ;
  272. X    node_s        *np = NEXT( hp->head ) ;
  273. X
  274. X    hp->hint.last_successor = np ;            /* update hint */
  275. X    return( OBJ( np ) ) ;
  276. X}
  277. X
  278. X
  279. X/*
  280. X * Returns a pointer to the object with the greatest key value or
  281. X * NULL if the list is empty.
  282. X *
  283. X * NOTE: here we depend on the fact that OBJ( head ) == NULL
  284. X */
  285. Xdict_obj dll_maximum( handle )
  286. X    dict_h        handle ;
  287. X{
  288. X    header_s        *hp = LHP( handle ) ;
  289. X    node_s        *np = PREV( hp->head ) ;
  290. X
  291. X    hp->hint.last_predecessor = np ;            /* update hint */
  292. X    return( OBJ( np ) ) ;
  293. X}
  294. X
  295. X
  296. X/*
  297. X * Returns a pointer to the object with the next >= key value or
  298. X * NULL if the list is empty or the given object is the last one on the
  299. X * list.
  300. X *
  301. X * NOTE: here we depend on the fact that OBJ( head ) == NULL
  302. X */
  303. Xdict_obj dll_successor( handle, object )
  304. X    dict_h                handle ;
  305. X    register dict_obj object ;
  306. X{
  307. X    register header_s *hp    = LHP( handle ) ;
  308. X    dheader_s            *dhp    = DHP( hp ) ;
  309. X    register node_s    *np ;
  310. X    node_s                *successor ;
  311. X    char                    *id = "dll_successor" ;
  312. X
  313. X    if ( object == NULL )
  314. X        HANDLE_ERROR( dhp, id, DICT_ENULLOBJECT, NULL_OBJ ) ;
  315. X
  316. X    if ( OBJ( hp->hint.last_successor ) == object )
  317. X        successor = NEXT( hp->hint.last_successor ) ;
  318. X    else
  319. X    {
  320. X        ERRNO( dhp ) = DICT_ENOERROR ;
  321. X        for ( np = NEXT( hp->head ) ; np != hp->head ; np = NEXT( np ) )
  322. X            if ( OBJ( np ) == object )
  323. X                break ;
  324. X        if ( np == hp->head )
  325. X            HANDLE_ERROR( dhp, id, DICT_EBADOBJECT, NULL_OBJ ) ;
  326. X        successor = NEXT( np ) ;
  327. X    }
  328. X    hp->hint.last_successor = successor ;
  329. X    return( OBJ( successor ) ) ;
  330. X}
  331. X
  332. X
  333. X
  334. X/*
  335. X * Returns a pointer to the object with the next <= key value or
  336. X * NULL if the list is empty or the given object is the first one on the
  337. X * list.
  338. X *
  339. X * NOTE: here we depend on the fact that OBJ( head ) == NULL
  340. X */
  341. Xdict_obj dll_predecessor( handle, object )
  342. X    dict_h                handle ;
  343. X    register dict_obj object ;
  344. X{
  345. X    register header_s *hp    = LHP( handle ) ;
  346. X    dheader_s            *dhp    = DHP( hp ) ;
  347. X    node_s                *predecessor ;
  348. X    register node_s    *np ;
  349. X    char                    *id = "dll_predecessor" ;
  350. X
  351. X    if ( object == NULL )
  352. X        HANDLE_ERROR( dhp, id, DICT_ENULLOBJECT, NULL_OBJ ) ;
  353. X
  354. X    if ( OBJ( hp->hint.last_predecessor ) == object )
  355. X        predecessor = PREV( hp->hint.last_predecessor ) ;
  356. X    else
  357. X    {
  358. X        ERRNO( dhp ) = DICT_ENOERROR ;
  359. X        for ( np = PREV( hp->head ) ; np != hp->head ; np = PREV( np ) )
  360. X            if ( OBJ( np ) == object )
  361. X                break ;
  362. X        if ( np == hp->head )
  363. X            HANDLE_ERROR( dhp, id, DICT_EBADOBJECT, NULL_OBJ ) ;
  364. X        predecessor = PREV( np ) ;
  365. X    }
  366. X    hp->hint.last_predecessor = predecessor ;
  367. X    return( OBJ( predecessor ) ) ;
  368. X}
  369. X
  370. X
  371. Xvoid dll_iterate( handle, direction )
  372. X    dict_h                    handle ;
  373. X    enum dict_direction    direction ;
  374. X{
  375. X    register header_s        *hp    = LHP( handle ) ;
  376. X    dheader_s                *dhp    = DHP( hp ) ;
  377. X    struct dll_iterator    *dip    = &hp->iter ;
  378. X
  379. X    if ( dhp->flags & DICT_UNORDERED )
  380. X        dip->direction = DICT_FROM_START ;
  381. X    else
  382. X        dip->direction = direction ;
  383. X
  384. X    if ( dip->direction == DICT_FROM_START )
  385. X        dip->next = NEXT( hp->head ) ;
  386. X    else
  387. X        dip->next = PREV( hp->head ) ;
  388. X}
  389. X
  390. X
  391. Xdict_obj dll_nextobj( handle )
  392. X    dict_h        handle ;
  393. X{
  394. X    struct dll_iterator    *dip        = &LHP( handle )->iter ;
  395. X    node_s                    *current = dip->next ;
  396. X
  397. X    if ( dip->direction == DICT_FROM_START )
  398. X        dip->next = NEXT( current ) ;
  399. X    else
  400. X        dip->next = PREV( current ) ;
  401. X    return( OBJ( current ) ) ;
  402. X}
  403. X
  404. END_OF_FILE
  405. if test 8638 -ne `wc -c <'libs/src/dict/dll.c'`; then
  406.     echo shar: \"'libs/src/dict/dll.c'\" unpacked with wrong size!
  407. fi
  408. # end of 'libs/src/dict/dll.c'
  409. fi
  410. if test -f 'libs/src/timer/STATES' -a "${1}" != "-c" ; then 
  411.   echo shar: Will not clobber existing file \"'libs/src/timer/STATES'\"
  412. else
  413. echo shar: Extracting \"'libs/src/timer/STATES'\" \(8393 characters\)
  414. sed "s/^X//" >'libs/src/timer/STATES' <<'END_OF_FILE'
  415. X
  416. XThe following is a state table showing how the state of a timer changes
  417. Xwhen various operations are applied to it.  The state is represented as
  418. Xa triple: the first member shows the state of the "ticking" part of the
  419. Xtimer, the second member shows if the timer is blocked  and the third 
  420. Xmember shows the state of the action associated with the timer.
  421. X
  422. XThe "ticking" state can be:
  423. X   INACTIVE    :  the timer is not ticking
  424. X   TICKING     :  the timer is ticking
  425. X   DESTROYED   :  the timer has been destroyed
  426. X
  427. XThe "blocked" state can be TRUE or FALSE.
  428. X
  429. XThe action state can be:
  430. X   IDLE        :  this is the original state (quiescent)
  431. X    SCHEDULED:        the action is scheduled to be invoked
  432. X   PENDING     :  the timer has expired but the action is pending because the
  433. X                        the timer is blocked.
  434. X   INVOKED     :  the action has been invoked (i.e. the user-specified function
  435. X                  is running)
  436. X
  437. X
  438. XThe operations that affect timers fall into 2 groups. In the first group 
  439. Xare the operations available by the library interface:
  440. X
  441. X   timer_start
  442. X   timer_stop
  443. X   timer_block
  444. X   timer_unblock
  445. X   timer_destroy
  446. X
  447. XIn the second group are internal operations:
  448. X
  449. X   INVOKE      :  invoke the function associated with the timer
  450. X   RETURN      :  the function associated with the timer returns
  451. X   INTERRUPT   :  the timer expired
  452. X
  453. XThe initial timer state is (INACTIVE,NONE).
  454. X
  455. X
  456. X
  457. X
  458. X
  459. X
  460. X
  461. X
  462. X
  463. X
  464. XSTATES      | start     | stop      | block     | unblock   | destroy   | INVOKE    | RETURN    | INTERRUPT
  465. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  466. XINACTIVE    |           |           |           |           |           |           |           |
  467. XUNBLOCKED   |  T,U,ID   |     X     |     X     |     X     | destroy   |     X     |     X     |    X
  468. XIDLE        |           |           |           |           |           |           |           |
  469. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  470. XINACTIVE    |           |           |           |           |           |           |           |
  471. XUNBLOCKED   |    E      |  I,U,ID   |  I,B,P    |     X     | destroy   |     X     |     X     |    X
  472. XPENDING     |           |           |           |           |           |           |           |
  473. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  474. XINACTIVE    |           |           |           |           |           |           |           |
  475. XUNBLOCKED   |    E      |  I,U,IN   |  I,B,S    |     X     |  D,U,IN   |  I,U,IN   |     X     |    X
  476. XSCHEDULED   |           |           |           |           |           |           |           |
  477. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  478. XINACTIVE    |           |           |           |           |           |           |           |
  479. XUNBLOCKED   |  T,U,IN   |     X     |     X     |     X     |  D,U,IN   |     X     |  I,U,ID   |    X
  480. XINVOKED     |           |           |           |           |           |           |           |
  481. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  482. XINACTIVE    |           |           |           |           |           |           |           |
  483. XBLOCKED     |     E     |  I,U,ID   |     X     |  I,U,S    | destroy   |     X     |     X     |    X
  484. XPENDING     |           |           |           |+ INVOKE(1)|           |           |           |
  485. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  486. XINACTIVE    |           |           |           |           |           |           |           |
  487. XBLOCKED     |     E     |  I,U,IN   |     X     |  I,U,S    |  D,U,IN   |  I,B,P    |     X     |    X
  488. XSCHEDULED   |           |           |           |           |           |           |           |
  489. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  490. XTICKING     |           |           |           |           |           |           |           |
  491. XUNBLOCKED   |     E     |  I,U,ID   |  T,B,ID   |     X     | destroy   |     X     |     X     |  I|T,U,S (2)
  492. XIDLE        |           |           |           |           |           |           |           |+ INVOKE
  493. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  494. XTICKING     |           |           |           |           |           |           |           |
  495. XUNBLOCKED   |     E     |  I,U,IN   |  T,B,S    |     X     |  D,U,IN   |  T,U,IN   |     X     |  T,U,S (3)
  496. XSCHEDULED   |           |           |           |           |           |           |           |
  497. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  498. XTICKING     |           |           |           |           |           |           |           |
  499. XUNBLOCKED   |     E     |  I,U,IN   |  T,B,IN   |     X     |  D,U,IN   |     X     |  T,U,ID   |  T,U,S (3)
  500. XINVOKED     |           |           |           |           |           |           |           |+ INVOKE (1)
  501. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  502. XTICKING     |           |           |           |           |           |           |           |
  503. XBLOCKED     |     E     |  I,U,ID   |     X     |  T,U,ID   | destroy   |     X     |     X     |  I|T,B,P (2)
  504. XIDLE        |           |           |           |           |           |           |           |
  505. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  506. XTICKING     |           |           |           |           |           |           |           |
  507. XBLOCKED     |     E     |  I,U,ID   |     X     |  T,U,S    | destroy   |     X     |     X     |    X
  508. XPENDING     |           |           |           |+ INVOKE(1)|           |           |           |
  509. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  510. XTICKING     |           |           |           |           |           |           |           |
  511. XBLOCKED     |     E     |  I,U,IN   |     X     |  T,U,S    |  D,U,IN   |  T,B,P    |  T,B,P    |    X
  512. XSCHEDULED   |           |           |           |           |           |           |           |
  513. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  514. XTICKING     |           |           |           |           |           |           |           |
  515. XBLOCKED     |     E     |  I,U,IN   |     X     |  T,U,IN   |  D,U,IN   |     X     |  T,B,ID   |  T,B,S
  516. XINVOKED     |           |           |           |           |           |           |           |
  517. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  518. XDESTROYED   |           |           |           |           |           |           |           |
  519. XUNBLOCKED   |     E     |     X     |     X     |     X     |     X     |     X     | destroy   |    X
  520. XINVOKED     |           |           |           |           |           |           |           |
  521. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  522. X            |           |           |           |           |           |           |           |
  523. X            |           |           |           |           |           |           |           |
  524. X            |           |           |           |           |           |           |           |
  525. X------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|------------------
  526. X
  527. XX stands for NO-OP.
  528. X
  529. XNotes:
  530. X
  531. X1. The INVOKE operation immediately follows.
  532. X2. Whether the ticking state changes to INACTIVE depends on whether the timer expires periodically (if it does,
  533. X   the ticking state does not change).
  534. X3. There is no change of the ticking state since we know that the timer expires periodically.
  535. X
  536. X
  537. XSome states may seem impossible. For example, (TICKING, BLOCKED, INVOKED) can only happen if the user function
  538. Xissues a timer_block operation. This makes sense, if the timer expires periodically.
  539. X
  540. END_OF_FILE
  541. if test 8393 -ne `wc -c <'libs/src/timer/STATES'`; then
  542.     echo shar: \"'libs/src/timer/STATES'\" unpacked with wrong size!
  543. fi
  544. # end of 'libs/src/timer/STATES'
  545. fi
  546. if test -f 'libs/src/timer/timer.3' -a "${1}" != "-c" ; then 
  547.   echo shar: Will not clobber existing file \"'libs/src/timer/timer.3'\"
  548. else
  549. echo shar: Extracting \"'libs/src/timer/timer.3'\" \(9093 characters\)
  550. sed "s/^X//" >'libs/src/timer/timer.3' <<'END_OF_FILE'
  551. X.\"(c) Copyright 1993 by Panagiotis Tsirigotis
  552. X.\"All rights reserved.  The file named COPYRIGHT specifies the terms 
  553. X.\"and conditions for redistribution.
  554. X.\"
  555. X.\" $Id: timer.3,v 5.1 93/11/26 12:16:09 panos Exp $
  556. X.TH TIMER 3X "20 April 1993"
  557. X.SH NAME
  558. Xtimer_create, timer_destroy, timer_start, timer_stop, timer_block, timer_unblock, timer_expirations, timer_block_type, timer_unblock_type - timer management functions
  559. X.SH SYNOPSIS
  560. X.LP
  561. X.nf
  562. X.ft B
  563. X#include "timer.h"
  564. X.LP
  565. X.ft B
  566. Xenum timer_types { TIMER_REAL, TIMER_VIRTUAL, TIMER_PROF } ;
  567. Xenum timer_timetypes { TIMER_ABSOLUTE, TIMER_RELATIVE } ;
  568. X.LP
  569. X.ft B
  570. Xextern int timer_errno ;
  571. X.LP
  572. X.ft B
  573. Xtimer_h timer_create( type, flags, errnop )
  574. Xenum timer_types type ;
  575. Xint flags ;
  576. Xint *errnop ;
  577. X.LP
  578. X.ft B
  579. Xvoid timer_destroy( handle )
  580. Xtimer_h handle ;
  581. X.LP
  582. X.ft B
  583. Xint timer_start( handle, itvp, time_type, action )
  584. Xtimer_h handle ;
  585. Xstruct itimerval *itvp ;
  586. Xenum timer_timetypes time_type ;
  587. Xstruct timer_action *action ;
  588. X.LP
  589. X.ft B
  590. Xvoid timer_stop( handle )
  591. Xtimer_h handle ;
  592. X.LP
  593. X.ft B
  594. Xvoid timer_block( handle )
  595. Xtimer_h handle ;
  596. X.LP
  597. X.ft B
  598. Xvoid timer_unblock( handle )
  599. Xtimer_h handle ;
  600. X.LP
  601. X.ft B
  602. Xunsigned timer_expirations( handle )
  603. Xtimer_h handle ;
  604. X.LP
  605. X.ft B
  606. Xvoid timer_block_type( type )
  607. Xenum timer_types type ;
  608. X.LP
  609. X.ft B
  610. Xvoid timer_unblock_type( type )
  611. Xenum timer_types type ;
  612. X.SH DESCRIPTION
  613. X.LP
  614. XThis library provides support for multiple timers of various types by
  615. Xmultiplexing the timers provided by the operating system.
  616. XAn action is associated with each timer.
  617. XThe action can either be a function that will be invoked when the
  618. Xtimer expires,
  619. Xor it can be an integer variable that will either be set to
  620. X.SM TRUE
  621. Xwhen the timer expires or it will be increased for every expiration
  622. Xof the timer (it is up to the user to clear the variable after inspecting
  623. Xits value).
  624. XIf a function is used, then it is possible that while that function is running,
  625. Xmore timers may expire and their functions be called 
  626. X(i.e. timer interrupts are not blocked while the function is running).
  627. XThe timer-action association can change through the lifetime of the timer.
  628. XThe timer types supported by this library depend on the operating system.
  629. X.\" *********************** timer_create *****************************
  630. X.LP
  631. X.B timer_create()
  632. Xcreates a timer and returns a handle to it. When the timer is created, it
  633. Xis inactive. Possible values for \fItype\fP are:
  634. X.TP 18
  635. X.SB TIMER_REAL
  636. Xtimers of this type are wall-clock timers
  637. X.TP
  638. X.SB TIMER_VIRTUAL
  639. Xtimers of this type are running only when the process is running
  640. X.TP
  641. X.SB TIMER_PROF
  642. Xtimers of this type are running only when the process is running 
  643. Xor the system is doing work on behalf of the process.
  644. X.LP
  645. XPossible values for \fIflags\fP are formed by ORing any of the following
  646. Xconstants:
  647. X.TP 20
  648. X.SB TIMER_RETURN_ERROR
  649. Xif an error
  650. Xoccurs while handling \fIthis\fP timer an error indication will be returned
  651. X(the default is program termination)
  652. X.LP
  653. XYou can use the constant
  654. X.B TIMER_NOFLAGS
  655. Xto specify no flags at all.
  656. XThe argument
  657. X.I errnop
  658. Xis a pointer to a variable where error values will be placed
  659. X(the default, in case 
  660. X.I errnop
  661. Xis
  662. X.SM NULL,
  663. Xis \fItimer_errno\fP).
  664. X.\" *********************** timer_destroy *****************************
  665. X.LP
  666. X.B timer_destroy()
  667. Xdestroys the timer specified by \fIhandle\fP. 
  668. XIf the timer is active, it is deactivated first.
  669. X.\" *********************** timer_start *****************************
  670. X.LP
  671. X.B timer_start()
  672. Xactivates the timer specified by
  673. X.I handle.
  674. XThe expiration time is determined by
  675. X.I itvp
  676. Xand
  677. X.I time_type.
  678. X.I time_type
  679. Xcan be either
  680. X.B TIMER_ABSOLUTE
  681. Xor 
  682. X.B TIMER_RELATIVE.
  683. XTimers of the former
  684. Xtype expire at the time 
  685. Xspecified by
  686. X.I "itvp->it_value"
  687. X(if that time is before the
  688. Xcurrent time then the timer expires immediately), while the expiration
  689. Xtime of timers of the latter type expire at
  690. X.I "current time + itvp->it_value."
  691. X.I "itvp->it_interval"
  692. Xis the interval between subsequent expirations of the timer after the
  693. Xoriginal expiration.
  694. XThe
  695. X.I action
  696. Xargument determines the action to be taken when the timer expires.
  697. X.LP
  698. X.I "struct timer_action"
  699. Xis defined as follows:
  700. X.sp 1
  701. X.PD .1v
  702. X.RS
  703. X.nf
  704. Xstruct timer_action
  705. X{
  706. X.RS
  707. X.IP "int" 15
  708. Xta_flags ;
  709. X.IP "void"
  710. X(*ta_func)() ;
  711. X.IP void
  712. X*ta_arg ;
  713. X.IP jmp_buf
  714. Xta_env ;
  715. X.RE
  716. X} ;
  717. X.RE
  718. X.PD
  719. X.fi
  720. X.LP
  721. XThe type of action taken when a timer expires depends on
  722. X.I ta_func
  723. Xand
  724. X.I ta_arg.
  725. X.RS
  726. X.IP "Case 1: ta_func != NULL"
  727. XThe function will be invoked with 2 arguments: the handle of the expired
  728. Xtimer and
  729. X.I ta_arg.
  730. X.I "Such functions should not use longjmp."
  731. X.IP "Case 2: ta_func == NULL && ta_arg != NULL"
  732. X.I ta_arg
  733. Xis assumed to be a pointer to an integer variable. This variable will
  734. Xeither be set to
  735. X.SM TRUE
  736. Xor its value will be increased.
  737. X.IP "Case 3: ta_func == NULL && ta_arg == NULL"
  738. Xnothing happens.
  739. X.RE
  740. X.sp 1
  741. X.I ta_flags
  742. Xis formed by ORing any of the following constants:
  743. X.TP 20
  744. X.SB TIMER_INC_VAR
  745. XWhen the action associated with the timer is an integer variable then
  746. Xthe variable will be increased by the number of timer expirations (the
  747. Xdefault is for the variable to be set to 1).
  748. X.TP
  749. X.SB TIMER_BLOCK_ALL
  750. XWhen the action associated with the timer is a function, all timer
  751. Xinterrupts will be blocked while the function is running.
  752. X.TP
  753. X.SB TIMER_BLOCK_SAME
  754. XWhen the action associated with the timer is a function, all timers
  755. Xof the same type will be blocked while the function is running.
  756. X.TP
  757. X.SB TIMER_LONGJMP
  758. XA longjmp(3) will be performed using
  759. X.I ta_env
  760. Xafter the action associated with the timer is performed.
  761. X.LP
  762. XYou can use the constant
  763. X.B TIMER_NOFLAGS
  764. Xto specify no flags at all.
  765. X.\" *********************** timer_stop *****************************
  766. X.LP
  767. X.B timer_stop()
  768. Xstops the specified timer. The timer becomes inactive and it cannot
  769. Xbe restarted for the time that was remaining until expiration.
  770. X.\" *********************** timer_block *****************************
  771. X.LP
  772. X.B timer_block()
  773. Xblocks the specified timer. The timer is still active and may expire
  774. Xbut its action will not be executed until the
  775. Xtimer is unblocked.
  776. X.\" *********************** timer_unblock *****************************
  777. X.LP
  778. X.B timer_unblock()
  779. Xunblocks the specified timer. If the timer is past its expiration time,
  780. Xthe associated action will be executed immediately.
  781. X.\" *********************** timer_expirations *****************************
  782. X.LP
  783. X.B timer_expirations()
  784. Xshould be used by the user-specified function to find out 
  785. Xthe number of times the timer expired until the function was called.
  786. XMultiple expirations are possible for a timer that expires periodically.
  787. X.\" *********************** timer_block_type *****************************
  788. X.LP
  789. X.B timer_block_type()
  790. Xblocks all timers of the specified \fItype\fP.
  791. XThis also includes any timers started 
  792. X.I after
  793. Xthis function is invoked.
  794. X.\" *********************** timer_unblock_type *****************************
  795. X.LP
  796. X.B timer_unblock_type()
  797. Xunblocks all timers of the specified \fItype\fP.
  798. X.\" *********************** notes *****************************
  799. X.SH NOTES
  800. X.LP
  801. XAny of the timer operations can be used on any timer handle at any time.
  802. XSpecifically, the operations can be used from within the functions
  803. Xinvoked when the timers expire.
  804. X.LP
  805. XThe function associated with a timer is not
  806. Xinvoked for each expiration of that timer.
  807. XIt is possible for a timer to expire
  808. Xmultiple times while its function is running (because timers can
  809. Xbe scheduled to expire periodically), or while other timer functions
  810. Xare running. The timer function can find out how many times its timer
  811. Xhas expired by using the
  812. X.B timer_expirations()
  813. Xoperation.
  814. X.LP
  815. XIt is guaranteed that the function associated with a specific timer will 
  816. Xnot be called recursively if that timer expires multiple times.
  817. X.LP
  818. XThe order of execution of timer-associated functions for
  819. Xtimers that expire at the same time is undefined.
  820. X.SH "RETURN VALUES"
  821. X.LP
  822. XValues for 
  823. X.I timer_errno
  824. Xwill be stored in the user-specified variable if one was provided.
  825. X.LP
  826. X.B timer_create()
  827. Xreturns a timer handle if successful or
  828. X.SM NULL
  829. Xif it fails.
  830. X.LP
  831. X.B timer_start()
  832. Xreturns 
  833. X.B TIMER_OK
  834. Xif successful or
  835. X.B TIMER_ERR
  836. Xif it fails.
  837. X.LP
  838. X.B timer_expirations()
  839. Xreturns a positive (non-zero) number when invoked from a timer-associated
  840. Xfunction; otherwise its return value is undefined.
  841. X.RE
  842. X.SH "ERRORS"
  843. XThe following is a list of error codes which will be placed in
  844. X.I timer_errno
  845. Xor the user-specified variable when a timer operation fails:
  846. X.RS
  847. X.TP 20
  848. X.SB TIMER_ENOMEM
  849. XA memory allocation request failed.
  850. X.TP
  851. X.SB TIMER_EBADTYPE
  852. XAn unknown timer type was specified.
  853. X.TP
  854. X.SB TIMER_ESIGPROBLEM
  855. XA signal handler could not be installed.
  856. X.TP
  857. X.SB TIMER_EBADSTATE
  858. XThe timer state does not allow this operation (for example, the timer is
  859. Xrunning and the operation attempted was \fBtimer_start()\fP).
  860. X.TP
  861. X.SB TIMER_EBADTIME
  862. XThe time value specified was negative.
  863. X.TP
  864. X.SB TIMER_ENOTAVAILABLE
  865. XThe requested timer type is not available.
  866. X.TP
  867. X.SB TIMER_ECANTINSERT
  868. XThe insertion of this timer in the queue of timers failed.
  869. X.TP
  870. X.SB TIMER_SIGPROBLEM
  871. XThere was an error while trying to install a signal handler.
  872. X.SH "SEE ALSO"
  873. Xsetitimer(2), setjmp(3), longjmp(3)
  874. END_OF_FILE
  875. if test 9093 -ne `wc -c <'libs/src/timer/timer.3'`; then
  876.     echo shar: \"'libs/src/timer/timer.3'\" unpacked with wrong size!
  877. fi
  878. # end of 'libs/src/timer/timer.3'
  879. fi
  880. echo shar: End of archive 15 \(of 20\).
  881. cp /dev/null ark15isdone
  882. MISSING=""
  883. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  884.     if test ! -f ark${I}isdone ; then
  885.     MISSING="${MISSING} ${I}"
  886.     fi
  887. done
  888. if test "${MISSING}" = "" ; then
  889.     echo You have unpacked all 20 archives.
  890.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  891. else
  892.     echo You still need to unpack the following archives:
  893.     echo "        " ${MISSING}
  894. fi
  895. ##  End of shell archive.
  896. exit 0
  897.