Changeset 2c577e0b in mainline


Ignore:
Timestamp:
2011-01-29T11:29:35Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
64d2b10
Parents:
9c81703
Message:
  • implement service_realtime_share_in()
  • cstyle changes in time.c
Location:
uspace/lib/c
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/ipc/ns.c

    r9c81703 r2c577e0b  
    7979}
    8080
     81void *service_realtime_share_in(void)
     82{
     83        void *rtime = as_get_mappable_page(PAGE_SIZE);
     84        if (rtime == NULL)
     85                return NULL;
     86       
     87        int res = async_share_in_start_1_0(PHONE_NS, rtime, PAGE_SIZE,
     88            SERVICE_MEM_REALTIME);
     89        if (res != EOK) {
     90                as_area_destroy((void *) rtime);
     91                return NULL;
     92        }
     93       
     94        return rtime;
     95}
     96
    8197/** @}
    8298 */
  • uspace/lib/c/generic/time.c

    r9c81703 r2c577e0b  
    3535#include <sys/time.h>
    3636#include <unistd.h>
    37 #include <ipc/ipc.h>
    38 #include <stdio.h>
     37#include <bool.h>
     38#include <ipc/ns.h>
    3939#include <arch/barrier.h>
    40 #include <unistd.h>
    41 #include <atomic.h>
    42 #include <sysinfo.h>
    43 #include <ipc/services.h>
     40#include <macros.h>
    4441#include <libc.h>
    45 
    46 #include <sysinfo.h>
    47 #include <as.h>
    48 #include <ddi.h>
    49 
    5042#include <time.h>
    5143
    52 /* Pointers to public variables with time */
     44/** Pointer to kernel shared variables with time */
    5345struct {
    5446        volatile sysarg_t seconds1;
     
    5951/** Add microseconds to given timeval.
    6052 *
    61  * @param tv            Destination timeval.
    62  * @param usecs         Number of microseconds to add.
     53 * @param tv    Destination timeval.
     54 * @param usecs Number of microseconds to add.
     55 *
    6356 */
    6457void tv_add(struct timeval *tv, suseconds_t usecs)
     
    6659        tv->tv_sec += usecs / 1000000;
    6760        tv->tv_usec += usecs % 1000000;
     61       
    6862        if (tv->tv_usec > 1000000) {
    6963                tv->tv_sec++;
     
    7468/** Subtract two timevals.
    7569 *
    76  * @param tv1           First timeval.
    77  * @param tv2           Second timeval.
    78  *
    79  * @return              Return difference between tv1 and tv2 (tv1 - tv2) in
    80  *                      microseconds.
     70 * @param tv1 First timeval.
     71 * @param tv2 Second timeval.
     72 *
     73 * @return Difference between tv1 and tv2 (tv1 - tv2) in
     74 *         microseconds.
     75 *
    8176 */
    8277suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
    8378{
    84         suseconds_t result;
    85 
    86         result = tv1->tv_usec - tv2->tv_usec;
    87         result += (tv1->tv_sec - tv2->tv_sec) * 1000000;
    88 
    89         return result;
     79        return (tv1->tv_usec - tv2->tv_usec) +
     80            ((tv1->tv_sec - tv2->tv_sec) * 1000000);
    9081}
    9182
    9283/** Decide if one timeval is greater than the other.
    9384 *
    94  * @param t1            First timeval.
    95  * @param t2            Second timeval.
    96  *
    97  * @return              Return true tv1 is greater than tv2. Otherwise return
    98  *                      false.
     85 * @param t1 First timeval.
     86 * @param t2 Second timeval.
     87 *
     88 * @return True if tv1 is greater than tv2.
     89 * @return False otherwise.
     90 *
    9991 */
    10092int tv_gt(struct timeval *tv1, struct timeval *tv2)
    10193{
    10294        if (tv1->tv_sec > tv2->tv_sec)
    103                 return 1;
    104         if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec)
    105                 return 1;
    106         return 0;
     95                return true;
     96       
     97        if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
     98                return true;
     99       
     100        return false;
    107101}
    108102
    109103/** Decide if one timeval is greater than or equal to the other.
    110104 *
    111  * @param tv1           First timeval.
    112  * @param tv2           Second timeval.
    113  *
    114  * @return              Return true if tv1 is greater than or equal to tv2.
    115  *                      Otherwise return false.
     105 * @param tv1 First timeval.
     106 * @param tv2 Second timeval.
     107 *
     108 * @return True if tv1 is greater than or equal to tv2.
     109 * @return False otherwise.
     110 *
    116111 */
    117112int tv_gteq(struct timeval *tv1, struct timeval *tv2)
    118113{
    119114        if (tv1->tv_sec > tv2->tv_sec)
    120                 return 1;
    121         if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec >= tv2->tv_usec)
    122                 return 1;
    123         return 0;
    124 }
    125 
    126 
    127 /** POSIX gettimeofday
    128  *
    129  * The time variables are memory mapped(RO) from kernel, which updates
    130  * them periodically. As it is impossible to read 2 values atomically, we
    131  * use a trick: First read a seconds, then read microseconds, then
    132  * read seconds again. If a second elapsed in the meantime, set it to zero.
    133  * This provides assurance, that at least the
    134  * sequence of subsequent gettimeofday calls is ordered.
     115                return true;
     116       
     117        if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
     118                return true;
     119       
     120        return false;
     121}
     122
     123/** Get time of day
     124 *
     125 * The time variables are memory mapped (read-only) from kernel which
     126 * updates them periodically.
     127 *
     128 * As it is impossible to read 2 values atomically, we use a trick:
     129 * First we read the seconds, then we read the microseconds, then we
     130 * read the seconds again. If a second elapsed in the meantime, set
     131 * the microseconds to zero.
     132 *
     133 * This assures that the values returned by two subsequent calls
     134 * to gettimeofday() are monotonous.
     135 *
    135136 */
    136137int gettimeofday(struct timeval *tv, struct timezone *tz)
    137138{
    138         void *mapping;
    139         sysarg_t s1, s2;
    140         int rights;
    141         int res;
    142 
    143139        if (!ktime) {
    144                 mapping = as_get_mappable_page(PAGE_SIZE);
    145                 /* Get the mapping of kernel clock */
    146                 res = ipc_share_in_start_1_1(PHONE_NS, mapping, PAGE_SIZE,
    147                     SERVICE_MEM_REALTIME, &rights);
    148                 if (res) {
    149                         printf("Failed to initialize timeofday memarea\n");
    150                         _exit(1);
    151                 }
    152                 if (!(rights & AS_AREA_READ)) {
    153                         printf("Received bad rights on time area: %X\n",
    154                             rights);
    155                         as_area_destroy(mapping);
    156                         _exit(1);
    157                 }
    158                 ktime = mapping;
    159         }
     140                ktime = service_realtime_share_in();
     141                if (!ktime)
     142                        return -1;
     143        }
     144       
    160145        if (tz) {
    161146                tz->tz_minuteswest = 0;
    162147                tz->tz_dsttime = DST_NONE;
    163148        }
    164 
    165         s2 = ktime->seconds2;
     149       
     150        sysarg_t s2 = ktime->seconds2;
     151       
    166152        read_barrier();
    167153        tv->tv_usec = ktime->useconds;
     154       
    168155        read_barrier();
    169         s1 = ktime->seconds1;
     156        sysarg_t s1 = ktime->seconds1;
     157       
    170158        if (s1 != s2) {
     159                tv->tv_sec = max(s1, s2);
    171160                tv->tv_usec = 0;
    172                 tv->tv_sec = s1 > s2 ? s1 : s2;
    173161        } else
    174162                tv->tv_sec = s1;
    175 
     163       
    176164        return 0;
    177165}
     
    180168{
    181169        struct timeval tv;
    182 
    183170        if (gettimeofday(&tv, NULL))
    184171                return (time_t) -1;
     172       
    185173        if (tloc)
    186174                *tloc = tv.tv_sec;
     175       
    187176        return tv.tv_sec;
    188177}
    189178
    190 /** Wait unconditionally for specified number of microseconds */
     179/** Wait unconditionally for specified number of microseconds
     180 *
     181 */
    191182int usleep(useconds_t usec)
    192183{
     
    195186}
    196187
    197 /** Wait unconditionally for specified number of seconds */
     188/** Wait unconditionally for specified number of seconds
     189 *
     190 */
    198191unsigned int sleep(unsigned int sec)
    199192{
    200         /* Sleep in 1000 second steps to support
    201            full argument range */
     193        /*
     194         * Sleep in 1000 second steps to support
     195         * full argument range
     196         */
     197       
    202198        while (sec > 0) {
    203199                unsigned int period = (sec > 1000) ? 1000 : sec;
    204        
     200               
    205201                usleep(period * 1000000);
    206202                sec -= period;
    207203        }
     204       
    208205        return 0;
    209206}
  • uspace/lib/c/include/ipc/ns.h

    r9c81703 r2c577e0b  
    3737
    3838#include <sys/types.h>
    39 #include <ipc/ipc.h>
     39#include <ipc/common.h>
    4040
    4141typedef enum {
     
    5151
    5252extern wchar_t *service_klog_share_in(size_t *);
     53extern void *service_realtime_share_in(void);
    5354
    5455#endif
  • uspace/lib/c/include/ipc/services.h

    r9c81703 r2c577e0b  
    6666} services_t;
    6767
    68 /* Memory area to be received from NS */
    69 #define SERVICE_MEM_REALTIME    1
    70 #define SERVICE_MEM_KLOG        2
     68/* Memory areas to be received from NS */
     69typedef enum {
     70        SERVICE_MEM_REALTIME = 1,
     71        SERVICE_MEM_KLOG = 2
     72} mem_services_t;
    7173
    7274#endif
Note: See TracChangeset for help on using the changeset viewer.