Changeset 8119363 in mainline for uspace/lib/c/include
- Timestamp:
- 2018-06-26T17:35:40Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6e569bf
- Parents:
- fbfe59d (diff), e768aea (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/lib/c/include
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/async.h
rfbfe59d r8119363 108 108 typedef struct async_exch async_exch_t; 109 109 110 #define async_manager() \ 111 do { \ 112 futex_down(&async_futex); \ 113 fibril_switch(FIBRIL_FROM_DEAD); \ 114 } while (0) 110 extern _Noreturn void async_manager(void); 115 111 116 112 #define async_get_call(data) \ -
uspace/lib/c/include/fibril.h
rfbfe59d r8119363 36 36 #define LIBC_FIBRIL_H_ 37 37 38 #include <context.h>39 38 #include <types/common.h> 40 #include <adt/list.h>41 #include <libarch/tls.h>42 39 43 #define FIBRIL_WRITER 1 44 45 struct fibril; 40 typedef struct fibril fibril_t; 46 41 47 42 typedef struct { 48 struct fibril*owned_by;43 fibril_t *owned_by; 49 44 } fibril_owner_info_t; 50 45 51 typedef enum {52 FIBRIL_PREEMPT,53 FIBRIL_TO_MANAGER,54 FIBRIL_FROM_MANAGER,55 FIBRIL_FROM_DEAD56 } fibril_switch_type_t;57 58 46 typedef sysarg_t fid_t; 59 60 typedef struct fibril {61 link_t link;62 link_t all_link;63 context_t ctx;64 void *stack;65 void *arg;66 errno_t (*func)(void *);67 tcb_t *tcb;68 69 struct fibril *clean_after_me;70 errno_t retval;71 int flags;72 73 fibril_owner_info_t *waits_for;74 } fibril_t;75 47 76 48 /** Fibril-local variable specifier */ … … 81 53 extern fid_t fibril_create_generic(errno_t (*func)(void *), void *arg, size_t); 82 54 extern void fibril_destroy(fid_t fid); 83 extern fibril_t *fibril_setup(void);84 extern void fibril_teardown(fibril_t *f, bool locked);85 extern int fibril_switch(fibril_switch_type_t stype);86 55 extern void fibril_add_ready(fid_t fid); 87 extern void fibril_add_manager(fid_t fid);88 extern void fibril_remove_manager(void);89 56 extern fid_t fibril_get_id(void); 57 extern void fibril_yield(void); 90 58 91 59 static inline fid_t fibril_create(errno_t (*func)(void *), void *arg) … … 94 62 } 95 63 96 static inline int fibril_yield(void)97 {98 return fibril_switch(FIBRIL_PREEMPT);99 }100 101 64 #endif 102 65 -
uspace/lib/c/include/futex.h
rfbfe59d r8119363 36 36 #define LIBC_FUTEX_H_ 37 37 38 #include <assert.h> 38 39 #include <atomic.h> 39 40 #include <errno.h> 40 41 #include <libc.h> 42 #include <time.h> 41 43 42 44 typedef struct futex { 43 45 atomic_t val; 44 #ifdef FUTEX_UPGRADABLE45 int upgraded;46 #ifdef CONFIG_DEBUG_FUTEX 47 _Atomic void *owner; 46 48 #endif 47 49 } futex_t; 48 50 49 50 51 extern void futex_initialize(futex_t *futex, int value); 51 52 52 #ifdef FUTEX_UPGRADABLE 53 #include <rcu.h> 53 #ifdef CONFIG_DEBUG_FUTEX 54 54 55 #define FUTEX_INITIALIZE(val) {{ (val) }, 0} 55 #define FUTEX_INITIALIZE(val) {{ (val) }, NULL } 56 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1) 56 57 57 #define futex_lock(fut) \ 58 ({ \ 59 rcu_read_lock(); \ 60 (fut)->upgraded = rcu_access(_upgrade_futexes); \ 61 if ((fut)->upgraded) \ 62 (void) futex_down((fut)); \ 63 }) 58 void __futex_assert_is_locked(futex_t *, const char *); 59 void __futex_assert_is_not_locked(futex_t *, const char *); 60 void __futex_lock(futex_t *, const char *); 61 void __futex_unlock(futex_t *, const char *); 62 bool __futex_trylock(futex_t *, const char *); 63 void __futex_give_to(futex_t *, void *, const char *); 64 64 65 #define futex_trylock(fut) \ 66 ({ \ 67 rcu_read_lock(); \ 68 int _upgraded = rcu_access(_upgrade_futexes); \ 69 if (_upgraded) { \ 70 int _acquired = futex_trydown((fut)); \ 71 if (!_acquired) { \ 72 rcu_read_unlock(); \ 73 } else { \ 74 (fut)->upgraded = true; \ 75 } \ 76 _acquired; \ 77 } else { \ 78 (fut)->upgraded = false; \ 79 1; \ 80 } \ 81 }) 65 #define futex_lock(futex) __futex_lock((futex), #futex) 66 #define futex_unlock(futex) __futex_unlock((futex), #futex) 67 #define futex_trylock(futex) __futex_trylock((futex), #futex) 82 68 83 #define futex_unlock(fut) \ 84 ({ \ 85 if ((fut)->upgraded) \ 86 (void) futex_up((fut)); \ 87 rcu_read_unlock(); \ 88 }) 89 90 extern int _upgrade_futexes; 91 92 extern void futex_upgrade_all_and_wait(void); 69 #define futex_give_to(futex, new_owner) __futex_give_to((futex), (new_owner), #futex) 70 #define futex_assert_is_locked(futex) __futex_assert_is_locked((futex), #futex) 71 #define futex_assert_is_not_locked(futex) __futex_assert_is_not_locked((futex), #futex) 93 72 94 73 #else 95 74 96 75 #define FUTEX_INITIALIZE(val) {{ (val) }} 76 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1) 97 77 98 78 #define futex_lock(fut) (void) futex_down((fut)) … … 100 80 #define futex_unlock(fut) (void) futex_up((fut)) 101 81 82 #define futex_give_to(fut, owner) ((void)0) 83 #define futex_assert_is_locked(fut) assert((atomic_signed_t) (fut)->val.count <= 0) 84 #define futex_assert_is_not_locked(fut) ((void)0) 85 102 86 #endif 103 104 #define FUTEX_INITIALIZER FUTEX_INITIALIZE(1)105 87 106 88 /** Try to down the futex. … … 117 99 } 118 100 119 /** Down the futex. 101 /** Down the futex with timeout, composably. 102 * 103 * This means that when the operation fails due to a timeout or being 104 * interrupted, the next futex_up() is ignored, which allows certain kinds of 105 * composition of synchronization primitives. 106 * 107 * In most other circumstances, regular futex_down_timeout() is a better choice. 120 108 * 121 109 * @param futex Futex. 122 110 * 123 111 * @return ENOENT if there is no such virtual address. 112 * @return ETIMEOUT if timeout expires. 124 113 * @return EOK on success. 125 114 * @return Error code from <errno.h> otherwise. 126 115 * 127 116 */ 128 static inline errno_t futex_down (futex_t *futex)117 static inline errno_t futex_down_composable(futex_t *futex, struct timeval *expires) 129 118 { 119 // TODO: Add tests for this. 120 121 /* No timeout by default. */ 122 suseconds_t timeout = 0; 123 124 if (expires) { 125 struct timeval tv; 126 getuptime(&tv); 127 if (tv_gteq(&tv, expires)) { 128 /* We can't just return ETIMEOUT. That wouldn't be composable. */ 129 timeout = 1; 130 } else { 131 timeout = tv_sub_diff(expires, &tv); 132 } 133 134 assert(timeout > 0); 135 } 136 130 137 if ((atomic_signed_t) atomic_predec(&futex->val) < 0) 131 return (errno_t) __SYSCALL 1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->val.count);138 return (errno_t) __SYSCALL2(SYS_FUTEX_SLEEP, (sysarg_t) &futex->val.count, (sysarg_t) timeout); 132 139 133 140 return EOK; … … 151 158 } 152 159 160 static inline errno_t futex_down_timeout(futex_t *futex, struct timeval *expires) 161 { 162 /* 163 * This combination of a "composable" sleep followed by futex_up() on 164 * failure is necessary to prevent breakage due to certain race 165 * conditions. 166 */ 167 errno_t rc = futex_down_composable(futex, expires); 168 if (rc != EOK) 169 futex_up(futex); 170 return rc; 171 } 172 173 /** Down the futex. 174 * 175 * @param futex Futex. 176 * 177 * @return ENOENT if there is no such virtual address. 178 * @return EOK on success. 179 * @return Error code from <errno.h> otherwise. 180 * 181 */ 182 static inline errno_t futex_down(futex_t *futex) 183 { 184 return futex_down_timeout(futex, NULL); 185 } 186 153 187 #endif 154 188 -
uspace/lib/c/include/rcu.h
rfbfe59d r8119363 92 92 #define rcu_access(ptr) ACCESS_ONCE(ptr) 93 93 94 typedef enum blocking_mode {95 BM_BLOCK_FIBRIL,96 BM_BLOCK_THREAD97 } blocking_mode_t;98 99 94 extern void rcu_register_fibril(void); 100 95 extern void rcu_deregister_fibril(void); … … 105 100 extern bool rcu_read_locked(void); 106 101 107 #define rcu_synchronize() _rcu_synchronize(BM_BLOCK_FIBRIL) 108 109 extern void _rcu_synchronize(blocking_mode_t); 102 extern void rcu_synchronize(void); 110 103 111 104 #endif -
uspace/lib/c/include/stacktrace.h
rfbfe59d r8119363 43 43 typedef struct { 44 44 errno_t (*read_uintptr)(void *, uintptr_t, uintptr_t *); 45 int (*printf)(const char *, ...); 45 46 } stacktrace_ops_t; 46 47 … … 51 52 52 53 extern void stacktrace_print(void); 54 extern void stacktrace_kio_print(void); 53 55 extern void stacktrace_print_fp_pc(uintptr_t, uintptr_t); 54 56 extern void stacktrace_print_generic(stacktrace_ops_t *, void *, uintptr_t, -
uspace/lib/c/include/sys/time.h
rfbfe59d r8119363 69 69 }; 70 70 71 #define TIMEVAL_MAX ((struct timeval) { .tv_sec = LONG_MAX, .tv_usec = 999999 }) 72 71 73 struct timezone { 72 74 int tz_minuteswest; /* minutes W of Greenwich */ … … 75 77 76 78 extern void tv_add_diff(struct timeval *, suseconds_t); 77 extern void tv_add(struct timeval *, struct timeval *);78 extern suseconds_t tv_sub_diff( struct timeval *,struct timeval *);79 extern void tv_sub(struct timeval *, struct timeval *);80 extern int tv_gt( struct timeval *,struct timeval *);81 extern int tv_gteq( struct timeval *,struct timeval *);79 extern void tv_add(struct timeval *, const struct timeval *); 80 extern suseconds_t tv_sub_diff(const struct timeval *, const struct timeval *); 81 extern void tv_sub(struct timeval *, const struct timeval *); 82 extern int tv_gt(const struct timeval *, const struct timeval *); 83 extern int tv_gteq(const struct timeval *, const struct timeval *); 82 84 extern void gettimeofday(struct timeval *, struct timezone *); 83 85 extern void getuptime(struct timeval *);
Note:
See TracChangeset
for help on using the changeset viewer.