Changeset a1538cd
- Timestamp:
- Mar 12, 2021, 4:30:39 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- df65c0c
- Parents:
- b1d83ba
- Location:
- libcfa/src/concurrency
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/clib/cfathread.cfa
rb1d83ba ra1538cd 14 14 // 15 15 16 #include "fstream.hfa" 17 #include "locks.hfa" 16 18 #include "kernel.hfa" 17 19 #include "thread.hfa" 18 19 thread CRunner { 20 void (*themain)( CRunner * ); 20 #include "time.hfa" 21 22 #include "cfathread.h" 23 24 struct cfathread_object { 25 $thread self; 26 void * (*themain)( void * ); 27 void * arg; 28 void * ret; 21 29 }; 22 23 static void ?{}( CRunner & this, void (*themain)( CRunner * ) ) { 30 void main(cfathread_object & this); 31 void ^?{}(cfathread_object & mutex this); 32 33 static inline $thread * get_thread( cfathread_object & this ) { return &this.self; } 34 35 typedef ThreadCancelled(cfathread_object) cfathread_exception; 36 typedef ThreadCancelled_vtable(cfathread_object) cfathread_vtable; 37 38 void defaultResumptionHandler(ThreadCancelled(cfathread_object) & except) { 39 abort | "A thread was cancelled"; 40 } 41 42 cfathread_vtable _cfathread_vtable_instance; 43 44 cfathread_vtable const & get_exception_vtable(cfathread_exception *) { 45 return _cfathread_vtable_instance; 46 } 47 48 static void ?{}( cfathread_object & this, cluster & cl, void *(*themain)( void * ), void * arg ) { 24 49 this.themain = themain; 25 } 26 27 void main( CRunner & this ) { 28 this.themain( &this ); 50 this.arg = arg; 51 ((thread&)this){"C-thread", cl}; 52 __thrd_start(this, main); 53 } 54 55 void ^?{}(cfathread_object & mutex this) { 56 ^(this.self){}; 57 } 58 59 void main( cfathread_object & this ) { 60 __attribute__((unused)) void * const thrd_obj = (void*)&this; 61 __attribute__((unused)) void * const thrd_hdl = (void*)active_thread(); 62 /* paranoid */ verify( thrd_obj == thrd_hdl ); 63 64 this.ret = this.themain( this.arg ); 29 65 } 30 66 … … 33 69 34 70 extern "C" { 35 //-------------------- 36 // Basic thread management 37 CRunner * cfathread_create( void (*main)( CRunner * ) ) { 38 return new( main ); 39 } 40 41 void cfathread_join( CRunner * thrd ) { 71 int cfathread_cluster_create(cfathread_cluster_t * cl) __attribute__((nonnull(1))) { 72 *cl = new(); 73 return 0; 74 } 75 76 cfathread_cluster_t cfathread_cluster_self(void) { 77 return active_cluster(); 78 } 79 80 int cfathread_cluster_add_worker(cfathread_cluster_t cl, pthread_t* tid, void (*init_routine) (void *), void * arg) { 81 // processor * proc = new("C-processor", *cl, init_routine, arg); 82 processor * proc = alloc(); 83 (*proc){ "C-processor", *cl, init_routine, arg }; 84 if(tid) *tid = proc->kernel_thread; 85 return 0; 86 } 87 88 int cfathread_cluster_pause (cfathread_cluster_t) { 89 abort | "Pausing clusters is not supported"; 90 exit(1); 91 } 92 93 int cfathread_cluster_resume(cfathread_cluster_t) { 94 abort | "Resuming clusters is not supported"; 95 exit(1); 96 } 97 98 //-------------------- 99 // Thread attributes 100 int cfathread_attr_init(cfathread_attr_t *attr) __attribute__((nonnull (1))) { 101 attr->cl = active_cluster(); 102 return 0; 103 } 104 105 //-------------------- 106 // Thread 107 int cfathread_create( cfathread_t * handle, cfathread_attr_t * attr, void *(*main)( void * ), void * arg ) __attribute__((nonnull (1))) { 108 cluster * cl = attr ? attr->cl : active_cluster(); 109 cfathread_t thrd = alloc(); 110 (*thrd){ *cl, main, arg }; 111 *handle = thrd; 112 return 0; 113 } 114 115 int cfathread_join( cfathread_t thrd, void ** retval ) { 116 void * ret = join( *thrd ).ret; 42 117 delete( thrd ); 118 if(retval) { 119 *retval = ret; 120 } 121 return 0; 122 } 123 124 cfathread_t cfathread_self(void) { 125 return (cfathread_t)active_thread(); 126 } 127 128 int cfathread_usleep(useconds_t usecs) { 129 sleep(usecs`us); 130 return 0; 131 } 132 133 int cfathread_sleep(unsigned int secs) { 134 sleep(secs`s); 135 return 0; 43 136 } 44 137 … … 47 140 } 48 141 49 void cfathread_unpark( CRunner *thrd ) {142 void cfathread_unpark( cfathread_t thrd ) { 50 143 unpark( *thrd ); 51 144 } … … 55 148 } 56 149 57 //-------------------- 58 // Basic kernel features 59 void cfathread_setproccnt( int ncnt ) { 60 assert( ncnt >= 1 ); 61 adelete( procs ); 62 63 proc_cnt = ncnt - 1; 64 procs = anew(proc_cnt); 65 } 66 } 150 typedef struct cfathread_mutex * cfathread_mutex_t; 151 152 //-------------------- 153 // Mutex 154 struct cfathread_mutex { 155 single_acquisition_lock impl; 156 }; 157 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; } 158 int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1))) { delete( *mut ); return 0; } 159 int cfathread_mutex_lock (cfathread_mutex_t *mut) __attribute__((nonnull (1))) { lock ( (*mut)->impl ); return 0; } 160 int cfathread_mutex_trylock(cfathread_mutex_t *mut) __attribute__((nonnull (1))) { try_lock( (*mut)->impl ); return 0; } 161 int cfathread_mutex_unlock (cfathread_mutex_t *mut) __attribute__((nonnull (1))) { unlock ( (*mut)->impl ); return 0; } 162 163 //-------------------- 164 // Condition 165 struct cfathread_condition { 166 condition_variable(single_acquisition_lock) impl; 167 }; 168 int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; } 169 int cfathread_cond_signal(cfathread_cond_t *cond) __attribute__((nonnull (1))) { notify_one( (*cond)->impl ); return 0; } 170 int cfathread_cond_wait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut) __attribute__((nonnull (1,2))) { wait( (*cond)->impl, (*mut)->impl ); return 0; } 171 int cfathread_cond_timedwait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut, const struct timespec *restrict abstime) __attribute__((nonnull (1,2,3))) { 172 Time t = { *abstime }; 173 if( wait( (*cond)->impl, (*mut)->impl, t ) ) { 174 return 0; 175 } 176 errno = ETIMEDOUT; 177 return ETIMEDOUT; 178 } 179 } 180 181 #include <iofwd.hfa> 182 183 extern "C" { 184 #include <unistd.h> 185 #include <sys/types.h> 186 #include <sys/socket.h> 187 188 //-------------------- 189 // IO operations 190 int cfathread_socket(int domain, int type, int protocol) { 191 return socket(domain, type, protocol); 192 } 193 int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len) { 194 return bind(socket, address, address_len); 195 } 196 197 int cfathread_listen(int socket, int backlog) { 198 return listen(socket, backlog); 199 } 200 201 int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) { 202 return cfa_accept4(socket, address, address_len, 0, CFA_IO_LAZY); 203 } 204 205 int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len) { 206 return cfa_connect(socket, address, address_len, CFA_IO_LAZY); 207 } 208 209 int cfathread_dup(int fildes) { 210 return dup(fildes); 211 } 212 213 int cfathread_close(int fildes) { 214 return cfa_close(fildes, CFA_IO_LAZY); 215 } 216 217 ssize_t cfathread_sendmsg(int socket, const struct msghdr *message, int flags) { 218 return cfa_sendmsg(socket, message, flags, CFA_IO_LAZY); 219 } 220 221 ssize_t cfathread_write(int fildes, const void *buf, size_t nbyte) { 222 return cfa_write(fildes, buf, nbyte, CFA_IO_LAZY); 223 } 224 225 ssize_t cfathread_recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len) { 226 struct iovec iov; 227 iov.iov_base = buffer; 228 iov.iov_len = length; 229 230 struct msghdr msg; 231 msg.msg_name = address; 232 msg.msg_namelen = address_len ? (socklen_t)*address_len : (socklen_t)0; 233 msg.msg_iov = &iov; 234 msg.msg_iovlen = 1; 235 msg.msg_control = 0p; 236 msg.msg_controllen = 0; 237 238 ssize_t ret = cfa_recvmsg(socket, &msg, flags, CFA_IO_LAZY); 239 240 if(address_len) *address_len = msg.msg_namelen; 241 return ret; 242 } 243 244 ssize_t cfathread_read(int fildes, void *buf, size_t nbyte) { 245 return cfa_read(fildes, buf, nbyte, CFA_IO_LAZY); 246 } 247 248 void cfathread_suspendFD(int) { 249 abort | "Suspending File Descriptors is not supported"; 250 } 251 252 void cfathread_resumeFD (int) { 253 abort | "Resuming File Descriptors is not supported"; 254 } 255 256 } -
libcfa/src/concurrency/clib/cfathread.h
rb1d83ba ra1538cd 20 20 extern "C" { 21 21 #endif 22 #include <asm/types.h> 23 #include <errno.h> 24 #include <unistd.h> 25 26 22 27 //-------------------- 23 28 // Basic types 24 struct cfathread_CRunner_t; 25 typedef struct cfathread_CRunner_t * cfathread_t; 29 30 typedef struct cluster * cfathread_cluster_t; 31 32 int cfathread_cluster_create(cfathread_cluster_t * cluster) __attribute__((nonnull(1))); 33 cfathread_cluster_t cfathread_cluster_self(void); 34 int cfathread_cluster_add_worker(cfathread_cluster_t cluster, pthread_t* tid, void (*init_routine) (void *), void * arg); 35 int cfathread_cluster_pause (cfathread_cluster_t cluster); 36 int cfathread_cluster_resume(cfathread_cluster_t cluster); 26 37 27 38 //-------------------- 28 // Basic thread support 29 cfathread_t cfathread_create( void (*main)( cfathread_t ) ); 30 void cfathread_join( cfathread_t ); 39 // thread attribute 40 typedef struct cfathread_attr { 41 cfathread_cluster_t cl; 42 } cfathread_attr_t; 43 44 int cfathread_attr_init(cfathread_attr_t * attr) __attribute__((nonnull (1))); 45 static inline int cfathread_attr_destroy(cfathread_attr_t * attr) __attribute__((nonnull (1))) { return 0; } 46 static inline int cfathread_attr_setbackground(cfathread_attr_t * attr, int background) __attribute__((nonnull (1))) { return 0; } 47 static inline int cfathread_attr_setcluster(cfathread_attr_t * attr, cfathread_cluster_t cl) __attribute__((nonnull (1))) { attr->cl = cl; return 0; } 48 49 //-------------------- 50 // thread type 51 struct cfathread_object; 52 typedef struct cfathread_object * cfathread_t; 53 54 int cfathread_create( cfathread_t * h, cfathread_attr_t * a, void *(*main)( void * ), void * arg ) __attribute__((nonnull (1))); 55 int cfathread_join( cfathread_t, void ** retval ); 56 57 int cfathread_get_errno(void); 58 cfathread_t cfathread_self(void); 59 60 int cfathread_usleep(useconds_t usecs); 61 int cfathread_sleep(unsigned int secs); 31 62 32 63 void cfathread_park( void ); … … 35 66 36 67 //-------------------- 37 // Basic kernel features38 void cfathread_setproccnt( int );68 // mutex and condition 69 struct timespec; 39 70 71 typedef struct cfathread_mutex_attr { 72 } cfathread_mutexattr_t; 73 typedef struct cfathread_mutex * cfathread_mutex_t; 74 int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict attr) __attribute__((nonnull (1))); 75 int cfathread_mutex_destroy(cfathread_mutex_t *mut) __attribute__((nonnull (1))); 76 int cfathread_mutex_lock(cfathread_mutex_t *mut) __attribute__((nonnull (1))); 77 int cfathread_mutex_trylock(cfathread_mutex_t *mut) __attribute__((nonnull (1))); 78 int cfathread_mutex_unlock(cfathread_mutex_t *mut) __attribute__((nonnull (1))); 79 80 typedef struct cfathread_cond_attr { 81 } cfathread_condattr_t; 82 typedef struct cfathread_condition * cfathread_cond_t; 83 int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict attr) __attribute__((nonnull (1))); 84 int cfathread_cond_wait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut) __attribute__((nonnull (1,2))); 85 int cfathread_cond_timedwait(cfathread_cond_t *restrict cond, cfathread_mutex_t *restrict mut, const struct timespec *restrict abstime) __attribute__((nonnull (1,2,3))); 86 int cfathread_cond_signal(cfathread_cond_t *cond) __attribute__((nonnull (1))); 87 88 //-------------------- 89 // IO operations 90 struct sockaddr; 91 struct msghdr; 92 int cfathread_socket(int domain, int type, int protocol); 93 int cfathread_bind(int socket, const struct sockaddr *address, socklen_t address_len); 94 int cfathread_listen(int socket, int backlog); 95 int cfathread_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len); 96 int cfathread_connect(int socket, const struct sockaddr *address, socklen_t address_len); 97 int cfathread_dup(int fildes); 98 int cfathread_close(int fildes); 99 ssize_t cfathread_sendmsg(int socket, const struct msghdr *message, int flags); 100 ssize_t cfathread_write(int fildes, const void *buf, size_t nbyte); 101 ssize_t cfathread_recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len); 102 ssize_t cfathread_read(int fildes, void *buf, size_t nbyte); 103 104 void cfathread_suspendFD(int fd); 105 void cfathread_resumeFD (int fd); 40 106 41 107 #if defined(__cforall) || defined(__cplusplus) -
libcfa/src/concurrency/kernel.cfa
rb1d83ba ra1538cd 149 149 #endif 150 150 151 // if we need to run some special setup, now is the time to do it. 152 if(this->init.fnc) { 153 this->init.fnc(this->init.arg); 154 } 155 151 156 { 152 157 // Setup preemption data -
libcfa/src/concurrency/kernel.hfa
rb1d83ba ra1538cd 107 107 DLISTED_MGD_IMPL_IN(processor) 108 108 109 // special init fields 110 // This is needed for memcached integration 111 // once memcached experiments are done this should probably be removed 112 // it is not a particularly safe scheme as it can make processors less homogeneous 113 struct { 114 void (*fnc) (void *); 115 void * arg; 116 } init; 117 109 118 #if !defined(__CFA_NO_STATISTICS__) 110 119 int print_stats; … … 118 127 }; 119 128 120 void ?{}(processor & this, const char name[], struct cluster & cltr );129 void ?{}(processor & this, const char name[], struct cluster & cltr, void (*init) (void *), void * arg); 121 130 void ^?{}(processor & this); 122 131 123 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster}; }124 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; }125 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster}; }132 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster, 0p, 0p}; } 133 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr, 0p, 0p}; } 134 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster, 0p, 0p }; } 126 135 127 136 DLISTED_MGD_IMPL_OUT(processor) -
libcfa/src/concurrency/kernel/startup.cfa
rb1d83ba ra1538cd 73 73 static void __kernel_first_resume( processor * this ); 74 74 static void __kernel_last_resume ( processor * this ); 75 static void init(processor & this, const char name[], cluster & _cltr );75 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg); 76 76 static void deinit(processor & this); 77 77 static void doregister( struct cluster & cltr ); … … 198 198 ( this.terminated ){}; 199 199 ( this.runner ){}; 200 init( this, "Main Processor", *mainCluster );200 init( this, "Main Processor", *mainCluster, 0p, 0p ); 201 201 kernel_thread = pthread_self(); 202 202 … … 452 452 } 453 453 454 static void init(processor & this, const char name[], cluster & _cltr ) with( this ) {454 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) with( this ) { 455 455 this.name = name; 456 456 this.cltr = &_cltr; … … 464 464 this.io.dirty = false; 465 465 466 this.init.fnc = fnc; 467 this.init.arg = arg; 468 466 469 this.idle = eventfd(0, 0); 467 470 if (idle < 0) { … … 513 516 } 514 517 515 void ?{}(processor & this, const char name[], cluster & _cltr ) {518 void ?{}(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) { 516 519 ( this.terminated ){}; 517 520 ( this.runner ){}; 518 521 519 522 disable_interrupts(); 520 init( this, name, _cltr );523 init( this, name, _cltr, fnc, arg ); 521 524 enable_interrupts( __cfaabi_dbg_ctx ); 522 525
Note: See TracChangeset
for help on using the changeset viewer.