/* * This method will set the object name based upon the user string. * If the object class uses 32-bit names, then only the first 4 bytes * of the string will be used. */ rtems_status_code rtems_object_set_name( rtems_id id, const char *name ) { Objects_Information *information; Objects_Control *the_object; Objects_Id tmpId; if ( !name ) return RTEMS_INVALID_ADDRESS; tmpId = (id == OBJECTS_ID_OF_SELF) ? rtems_task_self() : id; information = _Objects_Get_information_id( tmpId ); if ( !information ) return RTEMS_INVALID_ID; _Objects_Allocator_lock(); the_object = _Objects_Get_no_protection( tmpId, information ); if ( the_object == NULL ) { _Objects_Allocator_unlock(); return RTEMS_INVALID_ID; } _Objects_Set_name( information, the_object, name ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; }
int mq_close( mqd_t mqdes ) { POSIX_Message_queue_Control *the_mq; Thread_queue_Context queue_context; _Objects_Allocator_lock(); the_mq = _POSIX_Message_queue_Get( mqdes, &queue_context ); if ( the_mq == NULL ) { _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EBADF ); } _CORE_message_queue_Acquire_critical( &the_mq->Message_queue, &queue_context ); if ( the_mq->open_count == 0 ) { _CORE_message_queue_Release( &the_mq->Message_queue, &queue_context ); _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EBADF ); } the_mq->open_count -= 1; _POSIX_Message_queue_Delete( the_mq, &queue_context ); _Objects_Allocator_unlock(); return 0; }
const void * rtems_monitor_mpci_next( void *object_info, rtems_monitor_mpci_t *canonical_mpci, rtems_id *next_id ) { const rtems_configuration_table *c = &Configuration; int n = rtems_object_id_get_index(*next_id); if (n >= 1) goto failed; if ( ! c->User_multiprocessing_table) goto failed; _Objects_Allocator_lock(); *next_id += 1; return (void *) c; failed: *next_id = RTEMS_OBJECT_ID_FINAL; return 0; }
/* * 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */ int pthread_key_delete( pthread_key_t key ) { POSIX_Keys_Control *the_key; Objects_Locations location; _Objects_Allocator_lock(); the_key = _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: _POSIX_Keys_Free_memory( the_key ); /* * NOTE: The destructor is not called and it is the responsibility * of the application to free the memory. */ _POSIX_Keys_Free( the_key ); _Objects_Put(&the_key->Object); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never happen */ #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
int sem_unlink( const char *name ) { int status; POSIX_Semaphore_Control *the_semaphore; Objects_Id the_semaphore_id; size_t name_len; _Objects_Allocator_lock(); _Thread_Disable_dispatch(); status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id, &name_len ); if ( status != 0 ) { _Thread_Enable_dispatch(); _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( status ); } the_semaphore = (POSIX_Semaphore_Control *) _Objects_Get_local_object( &_POSIX_Semaphore_Information, _Objects_Get_index( the_semaphore_id ) ); the_semaphore->linked = false; _POSIX_Semaphore_Namespace_remove( the_semaphore ); _POSIX_Semaphore_Delete( the_semaphore ); _Thread_Enable_dispatch(); _Objects_Allocator_unlock(); return 0; }
static int shm_mmap( rtems_libio_t *iop, void** addr, size_t len, int prot, off_t off ) { POSIX_Shm_Control *shm = iop_to_shm( iop ); _Objects_Allocator_lock(); *addr = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off); if ( *addr != NULL ) { /* Keep a reference in the shared memory to prevent its removal. */ ++shm->reference_count; /* Update atime */ _POSIX_Shm_Update_atime(shm); } else { _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( ENOMEM ); } _Objects_Allocator_unlock(); return 0; }
int sem_init( sem_t *sem, int pshared, unsigned int value ) { int status; POSIX_Semaphore_Control *the_semaphore; if ( !sem ) rtems_set_errno_and_return_minus_one( EINVAL ); _Objects_Allocator_lock(); status = _POSIX_Semaphore_Create_support( NULL, 0, pshared, value, &the_semaphore ); _Objects_Allocator_unlock(); if ( status != -1 ) *sem = the_semaphore->Object.id; return status; }
rtems_status_code rtems_port_delete( rtems_id id ) { Dual_ported_memory_Control *the_port; Objects_Locations location; _Objects_Allocator_lock(); the_port = _Dual_ported_memory_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); _Objects_Put( &the_port->Object ); _Dual_ported_memory_Free( the_port ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return RTEMS_INVALID_ID; }
int pthread_getname_np( pthread_t thread, char *name, size_t len ) { Thread_Control *the_thread; ISR_lock_Context lock_context; size_t actual_len; _Objects_Allocator_lock(); the_thread = _Thread_Get( thread, &lock_context ); if ( the_thread == NULL ) { _Objects_Allocator_unlock(); strlcpy(name, "", len); return ESRCH; } _ISR_lock_ISR_enable( &lock_context ); actual_len = _Thread_Get_name( the_thread, name, len ); _Objects_Allocator_unlock(); if ( actual_len >= len ) { return ERANGE; } return 0; }
int mq_unlink( const char *name ) { POSIX_Message_queue_Control *the_mq; Objects_Get_by_name_error error; Thread_queue_Context queue_context; _Objects_Allocator_lock(); the_mq = _POSIX_Message_queue_Get_by_name( name, NULL, &error ); if ( the_mq == NULL ) { _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( _POSIX_Get_by_name_error( error ) ); } _POSIX_Message_queue_Namespace_remove( the_mq ); _CORE_message_queue_Acquire( &the_mq->Message_queue, &queue_context ); the_mq->linked = false; _POSIX_Message_queue_Delete( the_mq, &queue_context ); _Objects_Allocator_unlock(); return 0; }
int sem_close( sem_t *sem ) { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; _Objects_Allocator_lock(); the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { case OBJECTS_LOCAL: the_semaphore->open_count -= 1; _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Put( &the_semaphore->Object ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EINVAL ); }
rtems_status_code rtems_message_queue_delete( rtems_id id ) { Message_queue_Control *the_message_queue; Objects_Locations location; _Objects_Allocator_lock(); the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Message_queue_Information, &the_message_queue->Object ); _CORE_message_queue_Close( &the_message_queue->message_queue, _Message_queue_MP_Send_object_was_deleted, id ); #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) { _Objects_MP_Close( &_Message_queue_Information, the_message_queue->Object.id ); _Message_queue_MP_Send_process_packet( MESSAGE_QUEUE_MP_ANNOUNCE_DELETE, the_message_queue->Object.id, 0, /* Not used */ 0 ); } #endif _Objects_Put( &the_message_queue->Object ); _Message_queue_Free( the_message_queue ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: _Objects_Allocator_unlock(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return RTEMS_INVALID_ID; }
/* * 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272 */ mqd_t mq_open( const char *name, int oflag, ... /* mode_t mode, */ /* struct mq_attr attr */ ) { POSIX_Message_queue_Control *the_mq; size_t name_len; Objects_Get_by_name_error error; mqd_t status; _Objects_Allocator_lock(); the_mq = _POSIX_Message_queue_Get_by_name( name, &name_len, &error ); /* * If the name to id translation worked, then the message queue exists * and we can just return a pointer to the id. Otherwise we may * need to check to see if this is a "message queue does not exist" * or some other miscellaneous error on the name. */ if ( the_mq == NULL ) { va_list ap; const struct mq_attr *attr; /* * Unless provided a valid name that did not already exist * and we are willing to create then it is an error. */ if ( error != OBJECTS_GET_BY_NAME_NO_OBJECT || ( oflag & O_CREAT ) == 0 ) { _Objects_Allocator_unlock(); rtems_set_errno_and_return_value( _POSIX_Get_by_name_error( error ), MQ_OPEN_FAILED ); } va_start( ap, oflag ); va_arg( ap, mode_t ); attr = va_arg( ap, const struct mq_attr * ); va_end( ap ); if ( attr == NULL ) { attr = &_POSIX_Message_queue_Default_attributes; } /* * At this point, the message queue does not exist and everything has been * checked. We should go ahead and create a message queue. */ status = _POSIX_Message_queue_Create( name, name_len, oflag, attr ); } else {
/* read() is unspecified for shared memory objects */ static ssize_t shm_read( rtems_libio_t *iop, void *buffer, size_t count ) { ssize_t bytes_read; POSIX_Shm_Control *shm = iop_to_shm( iop ); _Objects_Allocator_lock(); bytes_read = (*shm->shm_object.ops->object_read)( &shm->shm_object, buffer, count ); _POSIX_Shm_Update_atime( shm ); _Objects_Allocator_unlock(); return bytes_read; }
/** * 11.4.2 Initializing and Destroying a Condition Variable, * P1003.1c/Draft 10, p. 87 */ int pthread_cond_destroy( pthread_cond_t *cond ) { POSIX_Condition_variables_Control *the_cond; Objects_Locations location; _Objects_Allocator_lock(); the_cond = _POSIX_Condition_variables_Get( cond, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( _Thread_queue_First( &the_cond->Wait_queue, POSIX_CONDITION_VARIABLES_TQ_OPERATIONS ) ) { _Objects_Put( &the_cond->Object ); _Objects_Allocator_unlock(); return EBUSY; } _Objects_Close( &_POSIX_Condition_variables_Information, &the_cond->Object ); _Objects_Put( &the_cond->Object ); _POSIX_Condition_variables_Free( the_cond ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
static int shm_ftruncate( rtems_libio_t *iop, off_t length ) { int err; POSIX_Shm_Control *shm = iop_to_shm( iop ); _Objects_Allocator_lock(); err = (*shm->shm_object.ops->object_resize)( &shm->shm_object, length ); if ( err != 0 ) { _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( err ); } _POSIX_Shm_Update_mtime_ctime( shm ); _Objects_Allocator_unlock(); return 0; }
/** * This directive allows a thread to delete a barrier specified by * the barrier id. The barrier is freed back to the inactive * barrier chain. * * @param[in] barrier is the barrier id * * @return This method returns 0 if there was not an * error. Otherwise, a status code is returned indicating the * source of the error. */ int pthread_barrier_destroy( pthread_barrier_t *barrier ) { POSIX_Barrier_Control *the_barrier = NULL; Objects_Locations location; if ( !barrier ) return EINVAL; _Objects_Allocator_lock(); the_barrier = _POSIX_Barrier_Get( barrier, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) { _Objects_Put( &the_barrier->Object ); return EBUSY; } _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); _Objects_Put( &the_barrier->Object ); _POSIX_Barrier_Free( the_barrier ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
rtems_status_code rtems_region_delete( rtems_id id ) { Objects_Locations location; rtems_status_code return_status; Region_Control *the_region; _Objects_Allocator_lock(); the_region = _Region_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Region_Debug_Walk( the_region, 5 ); if ( the_region->number_of_used_blocks != 0 ) return_status = RTEMS_RESOURCE_IN_USE; else { _Objects_Close( &_Region_Information, &the_region->Object ); _Region_Free( the_region ); return_status = RTEMS_SUCCESSFUL; } break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ #endif case OBJECTS_ERROR: default: return_status = RTEMS_INVALID_ID; break; } _Objects_Allocator_unlock(); return return_status; }
int timer_delete( timer_t timerid ) { /* * IDEA: This function must probably stop the timer first and then delete it * * It will have to do a call to rtems_timer_cancel and then another * call to rtems_timer_delete. * The call to rtems_timer_delete will be probably unnecessary, * because rtems_timer_delete stops the timer before deleting it. */ POSIX_Timer_Control *ptimer; ISR_lock_Context lock_context; _Objects_Allocator_lock(); ptimer = _POSIX_Timer_Get( timerid, &lock_context ); if ( ptimer != NULL ) { Per_CPU_Control *cpu; _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context ); ptimer->state = POSIX_TIMER_STATE_FREE; _Watchdog_Remove( &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], &ptimer->Timer ); _POSIX_Timer_Release( cpu, &lock_context ); _POSIX_Timer_Free( ptimer ); _Objects_Allocator_unlock(); return 0; } _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EINVAL ); }
rtems_status_code rtems_extension_delete( rtems_id id ) { rtems_status_code status; Extension_Control *the_extension; _Objects_Allocator_lock(); the_extension = _Extension_Get( id ); if ( the_extension != NULL ) { _Objects_Close( &_Extension_Information, &the_extension->Object ); _User_extensions_Remove_set( &the_extension->Extension ); _Extension_Free( the_extension ); status = RTEMS_SUCCESSFUL; } else { status = RTEMS_INVALID_ID; } _Objects_Allocator_unlock(); return status; }
int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock; ISR_lock_Context lock_context; _Objects_Allocator_lock(); the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context ); if ( the_rwlock == NULL ) { _Objects_Allocator_unlock(); return EINVAL; } _CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context ); /* * If there is at least one thread waiting, then do not delete it. */ if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) { _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); _Objects_Allocator_unlock(); return EBUSY; } /* * POSIX doesn't require behavior when it is locked. */ _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); _POSIX_RWLock_Free( the_rwlock ); _Objects_Allocator_unlock(); return 0; }
rtems_status_code rtems_semaphore_delete( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; Status_Control status; _Objects_Allocator_lock(); the_semaphore = _Semaphore_Get( id, &queue_context ); if ( the_semaphore == NULL ) { _Objects_Allocator_unlock(); #if defined(RTEMS_MULTIPROCESSING) if ( _Semaphore_MP_Is_remote( id ) ) { return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } #endif return RTEMS_INVALID_ID; } _Thread_queue_Acquire_critical( &the_semaphore->Core_control.Wait_queue, &queue_context.Lock_context ); switch ( the_semaphore->variant ) { case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY: case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL: if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.Mutex.Recursive.Mutex ) ) { status = STATUS_RESOURCE_IN_USE; } else { status = STATUS_SUCCESSFUL; } break; #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: status = _MRSP_Can_destroy( &the_semaphore->Core_control.MRSP ); break; #endif default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); status = STATUS_SUCCESSFUL; break; } if ( status != STATUS_SUCCESSFUL ) { _Thread_queue_Release( &the_semaphore->Core_control.Wait_queue, &queue_context.Lock_context ); _Objects_Allocator_unlock(); return _Status_Get( status ); } _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: _MRSP_Destroy( &the_semaphore->Core_control.MRSP, &queue_context ); break; #endif default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); _Thread_queue_Flush_critical( &the_semaphore->Core_control.Wait_queue.Queue, _Semaphore_Get_operations( the_semaphore ), _Thread_queue_Flush_status_object_was_deleted, &queue_context ); _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue ); break; } #if defined(RTEMS_MULTIPROCESSING) if ( the_semaphore->is_global ) { _Objects_MP_Close( &_Semaphore_Information, id ); _Semaphore_MP_Send_process_packet( SEMAPHORE_MP_ANNOUNCE_DELETE, id, 0, /* Not used */ 0 /* Not used */ ); } #endif _Semaphore_Free( the_semaphore ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; }
int shm_open( const char *name, int oflag, mode_t mode ) { int err = 0; int fd; rtems_libio_t *iop; POSIX_Shm_Control *shm; size_t len; Objects_Get_by_name_error obj_err; unsigned int flags; if ( shm_check_oflag( oflag ) != 0 ) { return -1; } iop = rtems_libio_allocate(); if ( iop == NULL ) { rtems_set_errno_and_return_minus_one( EMFILE ); } _Objects_Allocator_lock(); shm = _POSIX_Shm_Get_by_name( name, &len, &obj_err ); if ( shm == NULL ) { switch ( obj_err ) { case OBJECTS_GET_BY_NAME_INVALID_NAME: err = EINVAL; break; case OBJECTS_GET_BY_NAME_NAME_TOO_LONG: err = ENAMETOOLONG; break; case OBJECTS_GET_BY_NAME_NO_OBJECT: default: shm = shm_allocate(name, len, oflag, mode, &err); break; } } else { /* shm exists */ if ( ( oflag & ( O_EXCL | O_CREAT ) ) == ( O_EXCL | O_CREAT ) ) { /* Request to create failed. */ err = EEXIST; } else if ( !shm_access_ok( shm, oflag ) ) { err = EACCES; } else { ++shm->reference_count; } } _Objects_Allocator_unlock(); if ( err != 0 ) { rtems_libio_free( iop ); rtems_set_errno_and_return_minus_one( err ); } if ( oflag & O_TRUNC ) { err = shm_ftruncate( iop, 0 ); (void) err; /* ignore truncate error */ } fd = rtems_libio_iop_to_descriptor( iop ); iop->data0 = fd; iop->data1 = shm; iop->pathinfo.node_access = shm; iop->pathinfo.handlers = &shm_handlers; iop->pathinfo.mt_entry = &rtems_filesystem_null_mt_entry; rtems_filesystem_location_add_to_mt_entry( &iop->pathinfo ); flags = LIBIO_FLAGS_CLOSE_ON_EXEC; if ( oflag & O_RDONLY ) { flags |= LIBIO_FLAGS_READ; } else { flags |= LIBIO_FLAGS_READ_WRITE; } rtems_libio_iop_flags_initialize( iop, flags ); return fd; }