Rev 4509 | Rev 4522 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4509 | Rev 4516 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | /* |
1 | /* |
| 2 | * Copyright (c) 2006 Ondrej Palkovsky |
2 | * Copyright (c) 2009 Jakub Jermar |
| 3 | * All rights reserved. |
3 | * All rights reserved. |
| 4 | * |
4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
7 | * are met: |
| Line 30... | Line 30... | ||
| 30 | * @{ |
30 | * @{ |
| 31 | */ |
31 | */ |
| 32 | /** @file |
32 | /** @file |
| 33 | */ |
33 | */ |
| 34 | 34 | ||
| 35 | #ifndef LIBC_FIBRIL_H_ |
35 | #ifndef LIBC_FIBRIL_SYNC_H_ |
| 36 | #define LIBC_FIBRIL_H_ |
36 | #define LIBC_FIBRIL_SYNC_H_ |
| 37 | 37 | ||
| - | 38 | #include <async.h> |
|
| 38 | #include <libarch/fibril.h> |
39 | #include <fibril.h> |
| 39 | #include <adt/list.h> |
40 | #include <adt/list.h> |
| 40 | #include <libarch/tls.h> |
41 | #include <libarch/tls.h> |
| 41 | 42 | ||
| 42 | #ifndef context_set |
43 | typedef struct { |
| 43 | #define context_set(c, _pc, stack, size, ptls) \ |
- | |
| 44 | (c)->pc = (sysarg_t) (_pc); \ |
44 | int counter; |
| 45 | (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ |
- | |
| 46 | (c)->tls = (sysarg_t) (ptls); |
45 | link_t waiters; |
| 47 | #endif /* context_set */ |
46 | } fibril_mutex_t; |
| 48 | 47 | ||
| 49 | #define FIBRIL_SERIALIZED 1 |
48 | #define FIBRIL_MUTEX_INITIALIZE(name) \ |
| 50 | - | ||
| 51 | typedef enum { |
49 | fibril_mutex_t name = { \ |
| 52 | FIBRIL_PREEMPT, |
50 | .counter = 1, \ |
| 53 | FIBRIL_TO_MANAGER, |
51 | .waiters = { \ |
| 54 | FIBRIL_FROM_MANAGER, |
52 | .prev = &name.waiters, \ |
| 55 | FIBRIL_FROM_DEAD |
53 | .next = &name.waiters, \ |
| 56 | } fibril_switch_type_t; |
54 | } \ |
| 57 | 55 | } |
|
| 58 | typedef sysarg_t fid_t; |
- | |
| 59 | 56 | ||
| 60 | struct fibril { |
57 | typedef struct { |
| 61 | link_t link; |
58 | fibril_mutex_t fm; |
| 62 | context_t ctx; |
59 | } fibril_rwlock_t; |
| - | 60 | ||
| - | 61 | #define FIBRIL_RWLOCK_INITIALIZE(name) \ |
|
| 63 | void *stack; |
62 | fibril_rwlock_t name = { \ |
| 64 | void *arg; |
63 | .fm = { \ |
| 65 | int (*func)(void *); |
64 | .counter = 1, \ |
| 66 | tcb_t *tcb; |
65 | .waiters = { \ |
| 67 | - | ||
| 68 | struct fibril *clean_after_me; |
66 | .prev = &name.fm.waiters, \ |
| 69 | int retval; |
67 | .next = &name.fm.waiters, \ |
| 70 | int flags; |
68 | } \ |
| 71 | }; |
69 | } \ |
| 72 | typedef struct fibril fibril_t; |
- | |
| 73 | 70 | } |
|
| 74 | extern int context_save(context_t *c); |
- | |
| 75 | extern void context_restore(context_t *c) __attribute__ ((noreturn)); |
- | |
| 76 | 71 | ||
| 77 | extern fid_t fibril_create(int (*func)(void *), void *arg); |
72 | extern void fibril_mutex_initialize(fibril_mutex_t *); |
| 78 | extern fibril_t *fibril_setup(void); |
73 | extern void fibril_mutex_lock(fibril_mutex_t *); |
| 79 | extern void fibril_teardown(fibril_t *f); |
74 | extern bool fibril_mutex_trylock(fibril_mutex_t *); |
| 80 | extern int fibril_switch(fibril_switch_type_t stype); |
75 | extern void fibril_mutex_unlock(fibril_mutex_t *); |
| - | 76 | ||
| 81 | extern void fibril_add_ready(fid_t fid); |
77 | extern void fibril_rwlock_initialize(fibril_rwlock_t *); |
| 82 | extern void fibril_add_manager(fid_t fid); |
78 | extern void fibril_rwlock_read_lock(fibril_rwlock_t *); |
| 83 | extern void fibril_remove_manager(void); |
79 | extern void fibril_rwlock_write_lock(fibril_rwlock_t *); |
| 84 | extern fid_t fibril_get_id(void); |
- | |
| 85 | extern void fibril_inc_sercount(void); |
80 | extern void fibril_rwlock_read_unlock(fibril_rwlock_t *); |
| 86 | extern void fibril_dec_sercount(void); |
81 | extern void fibril_rwlock_write_unlock(fibril_rwlock_t *); |
| 87 | - | ||
| 88 | static inline int fibril_yield(void) { |
- | |
| 89 | return fibril_switch(FIBRIL_PREEMPT); |
- | |
| 90 | } |
- | |
| 91 | 82 | ||
| 92 | #endif |
83 | #endif |
| 93 | 84 | ||
| 94 | /** @} |
85 | /** @} |
| 95 | */ |
86 | */ |