int rtems_aio_remove_req (rtems_chain_control *chain, struct aiocb *aiocbp) { if (rtems_chain_is_empty (chain)) return AIO_ALLDONE; rtems_chain_node *node = rtems_chain_first (chain); rtems_aio_request *current; current = (rtems_aio_request *) node; while (!rtems_chain_is_tail (chain, node) && current->aiocbp != aiocbp) { node = rtems_chain_next (node); current = (rtems_aio_request *) node; } if (rtems_chain_is_tail (chain, node)) return AIO_NOTCANCELED; else { rtems_chain_extract (node); current->aiocbp->error_code = ECANCELED; current->aiocbp->return_value = -1; free (current); } return AIO_CANCELED; }
/* * This interrupt service routine is called for an External Exception. */ rtems_isr external_exception_ISR ( rtems_vector_number vector /* IN */ ) { uint16_t index; EE_ISR_Type *node; uint16_t value; #if (HAS_PMC_PSC8) uint16_t PMC_irq; uint16_t check_irq; uint16_t status_word; #endif index = read_and_clear_irq(); if ( index >= NUM_LIRQ ) { printk( "ERROR:: Invalid interrupt number (%02x)\n", index ); return; } #if (HAS_PMC_PSC8) PMC_irq = SCORE603E_PCI_IRQ_0 - SCORE603E_IRQ00; if (index == PMC_irq) { status_word = read_and_clear_PMC_irq( index ); for (check_irq=SCORE603E_IRQ16; check_irq<=SCORE603E_IRQ19; check_irq++) { if ( Is_PMC_IRQ( check_irq, status_word )) { index = check_irq - SCORE603E_IRQ00; node = (EE_ISR_Type *)(ISR_Array[ index ].first); if ( rtems_chain_is_tail( &ISR_Array[ index ], (void *)node ) ) { printk ("ERROR:: check %d interrupt %02d has no isr\n", check_irq, index); value = get_irq_mask(); printk(" Mask = %02x\n", value); } while ( !rtems_chain_is_tail( &ISR_Array[ index ], (void *)node ) ) { (*node->handler)( node->vector ); node = (EE_ISR_Type *) node->Node.next; } } } } else #endif { node = (EE_ISR_Type *)(ISR_Array[ index ].first); if ( rtems_chain_is_tail( &ISR_Array[ index ], (void *)node ) ) { printk( "ERROR:: interrupt %02x has no isr\n", index); value = get_irq_mask(); printk(" Mask = %02x\n", value); return; } while ( !rtems_chain_is_tail( &ISR_Array[ index ], (void *)node ) ) { (*node->handler)( node->vector ); node = (EE_ISR_Type *) node->Node.next; } } }
static void rtems_aio_insert_prio (rtems_chain_control *chain, rtems_aio_request *req) { rtems_chain_node *node; AIO_printf ("FD exists \n"); node = rtems_chain_first (chain); if (rtems_chain_is_empty (chain)) { AIO_printf ("First in chain \n"); rtems_chain_prepend (chain, &req->next_prio); } else { AIO_printf ("Add by priority \n"); int prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio; while (req->aiocbp->aio_reqprio > prio && !rtems_chain_is_tail (chain, node)) { node = rtems_chain_next (node); prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio; } rtems_chain_insert (node->previous, &req->next_prio); } }
rtems_rtl_obj_sym_t* rtems_rtl_symbol_global_find (const char* name) { rtems_rtl_symbols_t* symbols; uint_fast32_t hash; rtems_chain_control* bucket; rtems_chain_node* node; symbols = rtems_rtl_global_symbols (); hash = rtems_rtl_symbol_hash (name); bucket = &symbols->buckets[hash % symbols->nbuckets]; node = rtems_chain_first (bucket); while (!rtems_chain_is_tail (bucket, node)) { rtems_rtl_obj_sym_t* sym = (rtems_rtl_obj_sym_t*) node; /* * Use the hash. I could add this to the symbol but it uses more memory. */ if (strcmp (name, sym->name) == 0) return sym; node = rtems_chain_next (node); } return NULL; }
rtems_aio_request_chain * rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create) { rtems_aio_request_chain *r_chain; rtems_chain_node *node; node = rtems_chain_first (chain); r_chain = (rtems_aio_request_chain *) node; while (r_chain->fildes < fildes && !rtems_chain_is_tail (chain, node)) { node = rtems_chain_next (node); r_chain = (rtems_aio_request_chain *) node; } if (r_chain->fildes == fildes) r_chain->new_fd = 0; else { if (create == 0) r_chain = NULL; else { r_chain = malloc (sizeof (rtems_aio_request_chain)); rtems_chain_initialize_empty (&r_chain->perfd); if (rtems_chain_is_empty (chain)) rtems_chain_prepend (chain, &r_chain->next_fd); else rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd); r_chain->new_fd = 1; r_chain->fildes = fildes; } } return r_chain; }
static int rtems_rtl_unresolved_find_name (rtems_rtl_unresolved_t* unresolved, const char* name, bool update_refcount) { size_t length = strlen (name); int index = 1; rtems_chain_node* node = rtems_chain_first (&unresolved->blocks); while (!rtems_chain_is_tail (&unresolved->blocks, node)) { rtems_rtl_unresolv_block_t* block = (rtems_rtl_unresolv_block_t*) node; rtems_rtl_unresolv_rec_t* rec = rtems_rtl_unresolved_rec_first (block); while (!rtems_rtl_unresolved_rec_is_last (block, rec)) { if (rec->type == rtems_rtl_unresolved_name) { if ((rec->rec.name.length == length) && (strcmp (rec->rec.name.name, name))) { if (update_refcount) ++rec->rec.name.refs; return index; } ++index; } rec = rtems_rtl_unresolved_rec_next (rec); } node = rtems_chain_next (node); } return 0 - index; }
bool rtems_rtl_unresolved_interate (rtems_rtl_unresolved_iterator_t iterator, void* data) { rtems_rtl_unresolved_t* unresolved = rtems_rtl_unresolved (); if (unresolved) { rtems_chain_node* node = rtems_chain_first (&unresolved->blocks); while (!rtems_chain_is_tail (&unresolved->blocks, node)) { rtems_rtl_unresolv_block_t* block = (rtems_rtl_unresolv_block_t*) node; rtems_rtl_unresolv_rec_t* rec = rtems_rtl_unresolved_rec_first (block); while (!rtems_rtl_unresolved_rec_is_last (block, rec)) { if (iterator (rec, data)) return true; rec = rtems_rtl_unresolved_rec_next (rec); } node = rtems_chain_next (node); } } return false; }
bool rtems_filesystem_iterate( rtems_per_filesystem_routine routine, void *routine_arg ) { rtems_chain_control *chain = &filesystem_chain; const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table [0]; rtems_chain_node *node = NULL; bool stop = false; while ( table_entry->type && !stop ) { stop = (*routine)( table_entry, routine_arg ); ++table_entry; } if ( !stop ) { rtems_libio_lock(); for ( node = rtems_chain_first( chain ); !rtems_chain_is_tail( chain, node ) && !stop; node = rtems_chain_next( node ) ) { const filesystem_node *fsn = (filesystem_node *) node; stop = (*routine)( &fsn->entry, routine_arg ); } rtems_libio_unlock(); } return stop; }
static rtems_task rc_conf_worker(rtems_task_argument task_argument) { rtems_bsd_rc_conf* rc_conf = (rtems_bsd_rc_conf*) task_argument; rtems_chain_node* node = rtems_chain_first(&services); int r = 0; int error; /* * Check for a syslog priority before any services are run. */ rc_conf_syslog(rc_conf); if (rc_conf->verbose) printf("rc.conf: running\n"); while (!rtems_chain_is_tail(&services, node)) { service* srv = (service*) node; int rr; if (strcmp("network", srv->name) != 0) printf("Starting %s.\n", srv->name); rr = srv->entry(rc_conf); if (rr < 0) { fprintf(stderr, "error: bsd service: %s: %s\n", srv->name, strerror(errno)); if (r == 0) { r = rr; error = errno; } } node = rtems_chain_next(node); } if (rc_conf->verbose) printf("rc.conf: services done\n"); lock(rc_conf); if (r < 0) rc_conf->error_code = error; /* * If there is a waiter signal else clean up because the waiter has gone. */ if (rc_conf->waiter != 0) { rtems_event_send(rc_conf->waiter, RTEMS_EVENT_1); unlock(rc_conf); } else { unlock(rc_conf); rc_conf_destroy(rc_conf); } if (rc_conf->verbose) printf("rc.conf: finished\n"); rtems_task_delete(RTEMS_SELF); }
static size_t rtems_rtl_obj_sections_loader (uint32_t mask, rtems_rtl_obj_t* obj, int fd, uint8_t* base, rtems_rtl_obj_sect_handler_t handler, void* data) { rtems_chain_control* sections = &obj->sections; rtems_chain_node* node = rtems_chain_first (sections); size_t base_offset = 0; bool first = true; while (!rtems_chain_is_tail (sections, node)) { rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; if ((sect->size != 0) && ((sect->flags & mask) != 0)) { if (!first) base_offset = rtems_rtl_sect_align (base_offset, sect->alignment); sect->base = base + base_offset; if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT)) printf ("rtl: loading: %s -> %8p (%zi)\n", sect->name, sect->base, sect->size); if ((sect->flags & RTEMS_RTL_OBJ_SECT_LOAD) == RTEMS_RTL_OBJ_SECT_LOAD) { if (!handler (obj, fd, sect, data)) { sect->base = 0; return false; } } else if ((sect->flags & RTEMS_RTL_OBJ_SECT_ZERO) == RTEMS_RTL_OBJ_SECT_ZERO) { memset (base + base_offset, 0, sect->size); } else { sect->base = 0; rtems_rtl_set_error (errno, "section has no load op"); return false; } base_offset += sect->size; first = false; } node = rtems_chain_next (node); } return true; }
void rtems_rtl_unresolved_table_close (rtems_rtl_unresolved_t* unresolved) { rtems_chain_node* node = rtems_chain_first (&unresolved->blocks); while (!rtems_chain_is_tail (&unresolved->blocks, node)) { rtems_chain_node* next = rtems_chain_next (node); free (node); node = next; } }
void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj) { rtems_chain_node* node = rtems_chain_first (&obj->sections); while (!rtems_chain_is_tail (&obj->sections, node)) { rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; rtems_chain_node* next_node = rtems_chain_next (node); rtems_chain_extract (node); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, (void*) sect->name); rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, sect); node = next_node; } }
static void edma_interrupt_error_handler(void *arg) { rtems_chain_control *chain = &edma_channel_chain; rtems_chain_node *node = rtems_chain_first(chain); uint32_t error_channels [] = { #if EDMA_GROUP_COUNT >= 1 EDMA.ERL.R #endif #if EDMA_GROUP_COUNT >= 2 , EDMA.ERH.R #endif #if EDMA_GROUP_COUNT >= 3 , EDMA_B.ERL.R #endif }; uint32_t error_status [] = { #if EDMA_GROUP_COUNT >= 1 EDMA.ESR.R #endif #if EDMA_GROUP_COUNT >= 3 , EDMA_B.ESR.R #endif }; #if EDMA_GROUP_COUNT >= 1 EDMA.ERL.R = error_channels [0]; #endif #if EDMA_GROUP_COUNT >= 2 EDMA.ERH.R = error_channels [1]; #endif #if EDMA_GROUP_COUNT >= 3 EDMA_B.ERL.R = error_channels [2]; #endif while (!rtems_chain_is_tail(chain, node)) { edma_channel_context *ctx = (edma_channel_context *) node; unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd); unsigned group_index = EDMA_GROUP_INDEX(channel_index); unsigned group_bit = EDMA_GROUP_BIT(channel_index); if ((error_channels [group_index] & group_bit) != 0) { unsigned module_index = EDMA_MODULE_INDEX(channel_index); (*ctx->done)(ctx, error_status [module_index]); } node = rtems_chain_next(node); } }
bool rtems_rtl_chain_iterate (rtems_chain_control* chain, rtems_chain_iterator iterator, void* data) { rtems_chain_node* node = rtems_chain_first (chain); while (!rtems_chain_is_tail (chain, node)) { rtems_chain_node* next_node = rtems_chain_next (node); if (!iterator (node, data)) return false; node = next_node; } return true; }
rtems_task Init( rtems_task_argument ignored ) { rtems_chain_control chain1; rtems_chain_node *p; test_node node1, node2; int id; TEST_BEGIN(); puts( "Init - Initialize chain empty" ); rtems_chain_initialize_empty( &chain1 ); /* verify that the chain append and insert work */ puts( "INIT - Verify rtems_chain_insert" ); node1.id = 1; node2.id = 2; rtems_chain_append( &chain1, &node1.Node ); rtems_chain_insert( &node1.Node, &node2.Node ); for ( p = rtems_chain_first(&chain1), id = 1 ; !rtems_chain_is_tail(&chain1, p) ; p = p->next , id++ ) { test_node *t = (test_node *)p; if ( id > 2 ) { puts( "INIT - TOO MANY NODES ON CHAIN" ); rtems_test_exit(0); } if ( t->id != id ) { puts( "INIT - ERROR ON CHAIN ID MISMATCH" ); rtems_test_exit(0); } } test_chain_first_and_last(); test_chain_with_empty_check(); test_chain_with_notification(); test_chain_get_with_wait(); test_chain_control_layout(); test_chain_control_initializer(); test_chain_node_count(); test_chain_insert_ordered(); test_chain_iterator(); TEST_END(); rtems_test_exit(0); }
static void rtems_bsd_dump_sx(void) { rtems_chain_control *chain = &rtems_bsd_sx_chain; rtems_chain_node *node = rtems_chain_first(chain); printf("sx dump:\n"); while (!rtems_chain_is_tail(chain, node)) { struct lock_object *lo = (struct lock_object *) node; printf("\t%s: 0x%08x\n", lo->lo_name, lo->lo_id); node = rtems_chain_next(node); } }
rtems_rfs_file_shared* rtems_rfs_file_get_shared (rtems_rfs_file_system* fs, rtems_rfs_ino ino) { rtems_chain_node* node; node = rtems_chain_first (&fs->file_shares); while (!rtems_chain_is_tail (&fs->file_shares, node)) { rtems_rfs_file_shared* shared; shared = (rtems_rfs_file_shared*) node; if (shared->inode.ino == ino) return shared; node = rtems_chain_next (node); } return NULL; }
static void rtems_bsd_dump_thread(void) { rtems_chain_control *chain = &rtems_bsd_thread_chain; rtems_chain_node *node = rtems_chain_first(chain); printf("thread dump:\n"); while (!rtems_chain_is_tail(chain, node)) { struct thread *td = (struct thread *) node; printf("\t%s: 0x%08x\n", td->td_name, td->td_id); node = rtems_chain_next(node); } }
static void rtems_bsd_dump_condvar(void) { rtems_chain_control *chain = &rtems_bsd_condvar_chain; rtems_chain_node *node = rtems_chain_first(chain); printf("condvar dump:\n"); while (!rtems_chain_is_tail(chain, node)) { struct cv *cv = (struct cv *) node; printf("\t%s: 0x%08x\n", cv->cv_description, cv->cv_id); node = rtems_chain_next(node); } }
IMFS_jnode_t *IMFS_find_match_in_dir( IMFS_jnode_t *directory, char *name ) { rtems_chain_node *the_node; rtems_chain_control *the_chain; IMFS_jnode_t *the_jnode; /* * Check for fatal errors. A NULL directory show a problem in the * the IMFS code. */ assert( directory ); if ( !name ) return 0; assert( name ); if ( !directory ) return 0; /* * Check for "." and ".." */ if ( !strcmp( name, dotname ) ) return directory; if ( !strcmp( name, dotdotname ) ) return directory->Parent; the_chain = &directory->info.directory.Entries; for ( the_node = the_chain->first; !rtems_chain_is_tail( the_chain, the_node ); the_node = the_node->next ) { the_jnode = (IMFS_jnode_t *) the_node; if ( !strcmp( name, the_jnode->name ) ) return the_jnode; } return 0; }
void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain) { rtems_chain_control *chain; rtems_chain_node *node; chain = &r_chain->perfd; node = rtems_chain_first (chain); while (!rtems_chain_is_tail (chain, node)) { rtems_chain_extract (node); rtems_aio_request *req = (rtems_aio_request *) node; node = rtems_chain_next (node); req->aiocbp->error_code = ECANCELED; req->aiocbp->return_value = -1; free (req); } }
static void rtems_aio_move_to_work (rtems_aio_request_chain *r_chain) { rtems_aio_request_chain *temp; rtems_chain_node *node; node = rtems_chain_first (&aio_request_queue.work_req); temp = (rtems_aio_request_chain *) node; while (temp->fildes < r_chain->fildes && !rtems_chain_is_tail (&aio_request_queue.work_req, node)) { node = rtems_chain_next (node); temp = (rtems_aio_request_chain *) node; } rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd); }
static void rtems_rtl_obj_run_cdtors (rtems_rtl_obj_t* obj, uint32_t mask) { rtems_chain_node* node = rtems_chain_first (&obj->sections); while (!rtems_chain_is_tail (&obj->sections, node)) { rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; if ((sect->flags & mask) == mask) { rtems_rtl_cdtor_t* handler; size_t handlers = sect->size / sizeof (rtems_rtl_cdtor_t); int c; for (c = 0, handler = sect->base; c < handlers; ++c) if (*handler) (*handler) (); } node = rtems_chain_next (node); } }
static rtems_rap_app_t* rtems_rap_check_handle (void* handle) { rtems_rap_app_t* app; rtems_chain_node* node; app = handle; node = rtems_chain_first (&rap_.apps); while (!rtems_chain_is_tail (&rap_.apps, node)) { rtems_rap_app_t* check = (rtems_rap_app_t*) node; if (check == app) return app; node = rtems_chain_next (node); } return NULL; }
static bool rtems_rtl_obj_section_handler (uint32_t mask, rtems_rtl_obj_t* obj, int fd, rtems_rtl_obj_sect_handler_t handler, void* data) { rtems_chain_node* node = rtems_chain_first (&obj->sections); while (!rtems_chain_is_tail (&obj->sections, node)) { rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node; if ((sect->flags & mask) != 0) { if (!handler (obj, fd, sect, data)) return false; } node = rtems_chain_next (node); } return true; }
int imfs_dir_fstat( rtems_filesystem_location_info_t *loc, struct stat *buf ) { rtems_chain_node *the_node; rtems_chain_control *the_chain; IMFS_jnode_t *the_jnode; the_jnode = (IMFS_jnode_t *) loc->node_access; buf->st_dev = 0ll; buf->st_ino = the_jnode->st_ino; buf->st_mode = the_jnode->st_mode; buf->st_nlink = the_jnode->st_nlink; buf->st_uid = the_jnode->st_uid; buf->st_gid = the_jnode->st_gid; buf->st_rdev = 0ll; buf->st_blksize = 0; buf->st_blocks = 0; buf->st_atime = the_jnode->stat_atime; buf->st_mtime = the_jnode->stat_mtime; buf->st_ctime = the_jnode->stat_ctime; buf->st_size = 0; the_chain = &the_jnode->info.directory.Entries; /* Run through the chain and count the number of directory entries */ /* that are subordinate to this directory node */ for ( the_node = the_chain->first ; !rtems_chain_is_tail( the_chain, the_node ) ; the_node = the_node->next ) { buf->st_size = buf->st_size + sizeof( struct dirent ); } return 0; }
bool rtems_rap_iterate (rtems_rap_iterator_t iterator) { rtems_rap_data_t* rap = rtems_rap_lock (); rtems_chain_node* node; bool result = true; node = rtems_chain_first (&rap->apps); while (!rtems_chain_is_tail (&rap->apps, node)) { rtems_rap_app_t* app = (rtems_rap_app_t*) node; result = iterator (app); if (!result) break; node = rtems_chain_next (node); } rtems_rap_unlock (); return result; }
void* rtems_rap_find (const char* name) { rtems_rap_data_t* rap = rtems_rap_lock (); rtems_chain_node* node; node = rtems_chain_first (&rap->apps); while (!rtems_chain_is_tail (&rap->apps, node)) { rtems_rap_app_t* app = (rtems_rap_app_t*) node; if (rtems_rap_match_name (app, name)) { rtems_rap_unlock (); return app; } node = rtems_chain_next (node); } rtems_rap_unlock (); return NULL; }
bool rtems_filesystem_mount_iterate( rtems_per_filesystem_mount_routine routine, void *routine_arg ) { rtems_chain_node *node = NULL; bool stop = false; rtems_libio_lock(); for ( node = rtems_chain_first( &mount_chain ); !rtems_chain_is_tail( &mount_chain, node ) && !stop; node = rtems_chain_next( node ) ) { const rtems_filesystem_mount_table_entry_t *mt_entry = (rtems_filesystem_mount_table_entry_t *) node; stop = (*routine)( mt_entry, routine_arg ); } rtems_libio_unlock(); return stop; }
ssize_t imfs_dir_read( rtems_libio_t *iop, void *buffer, size_t count ) { /* * Read up to element iop->offset in the directory chain of the * imfs_jnode_t struct for this file descriptor. */ rtems_chain_node *the_node; rtems_chain_control *the_chain; IMFS_jnode_t *the_jnode; int bytes_transferred; int current_entry; int first_entry; int last_entry; struct dirent tmp_dirent; the_jnode = (IMFS_jnode_t *)iop->file_info; the_chain = &the_jnode->info.directory.Entries; if ( rtems_chain_is_empty( the_chain ) ) return 0; /* Move to the first of the desired directory entries */ the_node = the_chain->first; bytes_transferred = 0; first_entry = iop->offset; /* protect against using sizes that are not exact multiples of the */ /* -dirent- size. These could result in unexpected results */ last_entry = first_entry + (count/sizeof(struct dirent)) * sizeof(struct dirent); /* The directory was not empty so try to move to the desired entry in chain*/ for ( current_entry = 0; current_entry < last_entry; current_entry = current_entry + sizeof(struct dirent) ){ if ( rtems_chain_is_tail( the_chain, the_node ) ){ /* We hit the tail of the chain while trying to move to the first */ /* entry in the read */ return bytes_transferred; /* Indicate that there are no more */ /* entries to return */ } if( current_entry >= first_entry ) { /* Move the entry to the return buffer */ tmp_dirent.d_off = current_entry; tmp_dirent.d_reclen = sizeof( struct dirent ); the_jnode = (IMFS_jnode_t *) the_node; tmp_dirent.d_ino = the_jnode->st_ino; tmp_dirent.d_namlen = strlen( the_jnode->name ); strcpy( tmp_dirent.d_name, the_jnode->name ); memcpy( buffer + bytes_transferred, (void *)&tmp_dirent, sizeof( struct dirent ) ); iop->offset = iop->offset + sizeof(struct dirent); bytes_transferred = bytes_transferred + sizeof( struct dirent ); } the_node = the_node->next; } /* Success */ return bytes_transferred; }