int main(void){ List *empty_list = list_new_empty_list(); fprintf(stdout, "Test Case 0\n-------------------\n"); list_print(empty_list); list_destroy(empty_list); fprintf(stdout, "\nTest Case 1\n-------------------\n"); List *list_a = list_new_empty_list(); for (int i=1; i<=10; i++){ int *value = (int *)malloc(sizeof(int)); *value = i; list_insert_data_after_element(list_a, (void *)value, list_a->tail); } list_print(list_a); fprintf(stdout, "\nTest Case 2\n-------------------\n"); for (int i=11; i<=20; i++){ int *value = (int *)malloc(sizeof(int)); *value = i; if (i % 2 == 0){ list_insert_data_after_element(list_a, value, NULL); }else{ list_insert_data_after_element(list_a, (void *)value, list_a->tail); } } list_print(list_a); fprintf(stdout, "\nTest Case 3\n-------------------\n"); for (int i=0; i<3; i++){ void *data = NULL; list_remove_element(list_a, list_a->head, &data); fprintf(stdout, "removed an element[%3d]\n", *(int *)data); free(data); } list_print(list_a); fprintf(stdout, "\nTest Case 4\n-------------------\n"); for (int i=0; i<3; i++){ void *data = NULL; list_remove_element(list_a, list_a->tail, &data); fprintf(stdout, "removed an element[%3d]\n", *(int *)data); free(data); } list_print(list_a); list_destroy(list_a); fprintf(stdout, "Test Case 5\n-------------------\n"); list_print(list_a); return 0; }
static int osprd_close_last(struct inode *inode, struct file *filp) { if (filp) { osprd_info_t *d = file2osprd(filp); int filp_writable = filp->f_mode & FMODE_WRITE; // EXERCISE: If the user closes a ramdisk file that holds // a lock, release the lock. Also wake up blocked processes // as appropriate. osp_spin_lock (&d->mutex); if (filp->f_flags & F_OSPRD_LOCKED) { d->check_deadlock_list_head = list_remove_element(d->check_deadlock_list_head, current->pid); if (check_list_not_empty(d)) { eprintk("not empty"); //clean_list(d); } //delete_check_deadlock_list(current->pid,d); if (filp_writable) { d->number_write_lock --; d->write_lock_holder = -1; } else { d->number_read_lock--; d->pid_list_head = list_remove_element(d->pid_list_head,current->pid); //if (d->pid_list_head == NULL) // return -ENOTTY; } } filp->f_flags = filp->f_flags & ~F_OSPRD_LOCKED; //delete_check_deadlock_list(current->pid,d); /*if (check_list_not_empty(d)) { eprintk("not empty"); clean_list(d); }*/ osp_spin_unlock (&d->mutex); wake_up_all (&(d->blockq)); } return 0; }
/*Used by sendFromInboxWithThrottle*/ static void sendFromInboxMsgAction (void* closure1, void *closure2) { mama_status status = MAMA_STATUS_OK; struct publisherClosure *c2 = (struct publisherClosure*)closure2; mamaPublisherImpl *impl = (mamaPublisherImpl*)c2->mPublisher; status = mamaPublisher_sendFromInbox ((mamaPublisher)impl, c2->mInbox, (mamaMsg)closure1); if (c2->mSendCompleteCallback) { c2->mSendCompleteCallback ( (mamaPublisher)impl, (mamaMsg)closure1, status, c2->mSendCompleteClosure); } list_remove_element (impl->mPendingActions, c2); list_free_element (impl->mPendingActions, c2); }
static void removeMessagesFromListCb (wList list, void *element, void *throttle) { wombatThrottleAction *action = (wombatThrottleAction*)element; list_remove_element (self->mMsgQueue, *action); list_free_element (self->mMsgQueue, *action); gRemoveCount++; }
mama_status wombatThrottle_removeAction (wombatThrottle throttle, wombatThrottleAction action) { list_remove_element (self->mMsgQueue, action); list_free_element (self->mMsgQueue, action); return MAMA_STATUS_OK; }
/** * We pass this function to commands so they can tell the CmResponder to * remove them from the pending list and clean up when the command completes. */ static void endCB (mamaCommand *command, void *closure) { mamaCmResponderImpl* impl = (mamaCmResponderImpl*) closure; list_remove_element (impl->mPendingCommands, command); command->mDtor (command->mHandle); list_free_element (impl->mPendingCommands, command); }
void *list_remove(link_list *list, void *data, list_comp comp) { list_element *le; if(!list || !data || !comp) return NULL; for(le = list->first; le; le = le->next) if(comp(le->data, data)) return list_remove_element(list, le); return NULL; }
/* ---------------------- small helper fucntions ---------------------------------- */ struct my_list* list_free( struct my_list* s ) { while(s->head) { list_remove_element(s); } return s; }
void *list_pop_back(link_list *list) { assert(list); if(!list->last) { assert(!list->first); return NULL; } return list_remove_element(list, list->last); }
int main() { list_head head; head = create_list(); printf("Original list : "); print_list(head); list_remove_element(&head, 0); printf("After remove 0 : "); print_list(head); list_remove_element(&head, 5); printf("After remove 5 : "); print_list(head); list_remove_element(&head, 9); printf("After remove 9 : "); print_list(head); return 0; }
static void removeMessagesForOwnerCb (wList list, void *element, void *closure) { MsgProperties *info = (MsgProperties*)element; biclosure* pair = (biclosure*)closure; if (pair->owner == info->mOwner) { list_remove_element (pair->impl->mMsgQueue, element); list_free_element (pair->impl->mMsgQueue, element); gRemoveCount++; } }
mama_status mamaStatsGenerator_removeStatsCollector (mamaStatsGenerator statsGenerator, mamaStatsCollector statsCollector) { mamaStatsGeneratorImpl* impl = (mamaStatsGeneratorImpl*)statsGenerator; mamaStatsCollectorImpl* collectorImpl = (mamaStatsCollectorImpl*)statsCollector; if (impl==NULL) return MAMA_STATUS_NULL_ARG; if (statsCollector==NULL) return MAMA_STATUS_NULL_ARG; list_remove_element (impl->mStatsCollectors, collectorImpl->mHandle); list_free_element (impl->mStatsCollectors, collectorImpl->mHandle); return MAMA_STATUS_OK; }
/*list destory*/ void list_destroy(devList *list){ sky_trace_enter(); void *data; devNode *element; int size = 0; while( ( size = list_size(list) ) > 0 ){ sleep(1); element = list_tail(list); if(list_remove_element(list,element,(void **)&data) == 0 && list->destroy != NULL ){ list->destroy(data); } } memset(list,0x00,sizeof(devList)); sky_trace_exit(); return ; }
mama_status mamaTimeZone_destroy (mamaTimeZone timeZone) { if (!timeZone) { return MAMA_STATUS_INVALID_ARG; } else { /* Remove from the list and free the memory. */ mamaTimeZoneImpl* impl = (mamaTimeZoneImpl*)timeZone; wList tzList; wthread_static_mutex_lock (&sVector_mutex); tzList = getTimeZones(); list_remove_element (tzList, impl); list_free_element (tzList, impl); wthread_static_mutex_unlock (&sVector_mutex); return MAMA_STATUS_OK; } }
/*Action function used with sendWithThrottle*/ static void sendMsgAction (void *closure1, void *closure2) { mama_status status = MAMA_STATUS_OK; struct publisherClosure* pc = (struct publisherClosure*)closure2; mamaPublisherImpl* impl = (mamaPublisherImpl*)pc->mPublisher; status = mamaPublisher_send ((mamaPublisher)impl, (mamaMsg)closure1); if (pc->mSendCompleteCallback) { pc->mSendCompleteCallback (pc->mPublisher, (mamaMsg)closure1, status, pc->mSendCompleteClosure); } list_remove_element (impl->mPendingActions, pc); list_free_element (impl->mPendingActions, pc); }
int main(void) { struct my_list* mt = NULL; mt = list_new(); list_add_element(mt, 1,1); list_add_element(mt, 2,2); list_add_element(mt, 3,3); list_add_element(mt, 4,4); list_print(mt); list_remove_element(mt); list_print(mt); list_free(mt); /* always remember to free() the malloc()ed memory */ free(mt); /* free() if list is kept separate from free()ing the structure, I think its a good design */ mt = NULL; /* after free() always set that pointer to NULL, C will run havon on you if you try to use a dangling pointer */ list_print(mt); return 0; }
/* * osprd_lock */ static int release_file_lock(struct file *filp) { if (filp) { osprd_info_t *d = file2osprd(filp); int filp_writable = filp->f_mode & FMODE_WRITE; int filp_locked = filp->f_flags & F_OSPRD_LOCKED; if(filp_locked) { spin_lock(&d->mutex); if(filp_writable) d->num_write_locks--; else // file open for reading d->num_read_locks--; // Set the head to the next ticket so that some process may respond // Check for overflows, if the tail wraps around to 0, move the head to 0 as well. if(d->ticket_head < d->ticket_tail) d->ticket_head++; else if(d->ticket_head > d->ticket_tail) d->ticket_head = 0; d->lock_holder_l = list_remove_element(d->lock_holder_l, current->pid); spin_unlock(&d->mutex); // Clear the file's locked bit filp->f_flags &= ~F_OSPRD_LOCKED; wake_up_all(&d->blockq); return 0; } } return -EINVAL; }
/* * osprd_ioctl(inode, filp, cmd, arg) * Called to perform an ioctl on the named file. */ int osprd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { osprd_info_t *d = file2osprd(filp); // device info int r = 0; // return value: initially 0 // Set 'r' to the ioctl's return value: 0 on success, negative on error if (cmd == OSPRDIOCACQUIRE) { // EXERCISE: Lock the ramdisk. // // If *filp is open for writing (filp_writable), then attempt // to write-lock the ramdisk; otherwise attempt to read-lock // the ramdisk. // // This lock request must block using 'd->blockq' until: // 1) no other process holds a write lock; // 2) either the request is for a read lock, or no other process // holds a read lock; and // 3) lock requests should be serviced in order, so no process // that blocked earlier is still blocked waiting for the // lock. // // If a process acquires a lock, mark this fact by setting // 'filp->f_flags |= F_OSPRD_LOCKED'. You also need to // keep track of how many read and write locks are held: // change the 'osprd_info_t' structure to do this. // // Also wake up processes waiting on 'd->blockq' as needed. // // If the lock request would cause a deadlock, return -EDEADLK. // If the lock request blocks and is awoken by a signal, then // return -ERESTARTSYS. // Otherwise, if we can grant the lock request, return 0. // 'd->ticket_head' and 'd->ticket_tail' should help you // service lock requests in order. These implement a ticket // order: 'ticket_tail' is the next ticket, and 'ticket_head' // is the ticket currently being served. You should set a local // variable to 'd->ticket_head' and increment 'd->ticket_head'. // Then, block at least until 'd->ticket_tail == local_ticket'. // (Some of these operations are in a critical section and must // be protected by a spinlock; which ones?) // Used to track the current request unsigned local_ticket; if(check_deadlock(d)) return -EDEADLK; // If we can't acquire the lock we put ourselves in the back of the queue // when the lock is released ticket_head will be incremented and we'll be // woken up while(try_acquire_file_lock(filp) != 0) { spin_lock(&d->mutex); d->ticket_tail++; local_ticket = d->ticket_tail; d->lock_waiter_l = list_add_to_front(d->lock_waiter_l, current->pid); spin_unlock(&d->mutex); wait_event_interruptible(d->blockq, d->ticket_head == local_ticket || d->num_to_requeue > 0); spin_lock(&d->mutex); d->lock_waiter_l = list_remove_element(d->lock_waiter_l, current->pid); spin_unlock(&d->mutex); // process any pending signals by re-queueing everything if(d->num_to_requeue > 0) { // Note: do NOT wake threads here, each thread should requeue only ONCE spin_lock(&d->mutex); d->num_to_requeue--; spin_unlock(&d->mutex); // If we find another pending signal, dispatch that too if(signal_pending(current)) return -ERESTARTSYS; } else if(signal_pending(current)) // See if we were woken up by a signal { // For simplicity, we requeue all waiting tasks (-1 which // is the process) being "popped" off the wait queue spin_lock(&d->mutex); d->num_to_requeue = (d->ticket_tail - d->ticket_head - 1); d->ticket_head = 0; d->ticket_tail = 0; // All threads are woken to notify them of requeuing // meanwhile, we wait until that finishes (no need to check // for more interrupts, the process will exit anyway). wake_up_all(&d->blockq); spin_unlock(&d->mutex); // Sanity check if(d->num_to_requeue > 0) { wait_event(d->blockq, d->num_to_requeue == 0); wake_up_all(&d->blockq); // Wake everyone up again to check for other pending signals } return -ERESTARTSYS; } } r = 0; } else if (cmd == OSPRDIOCTRYACQUIRE) { // EXERCISE: ATTEMPT to lock the ramdisk. // // This is just like OSPRDIOCACQUIRE, except it should never // block. If OSPRDIOCACQUIRE would block or return deadlock, // OSPRDIOCTRYACQUIRE should return -EBUSY. // Otherwise, if we can grant the lock request, return 0. r = try_acquire_file_lock(filp); if(r == -EDEADLK) r = -EBUSY; } else if (cmd == OSPRDIOCRELEASE) { // EXERCISE: Unlock the ramdisk. // // If the file hasn't locked the ramdisk, return -EINVAL. // Otherwise, clear the lock from filp->f_flags, wake up // the wait queue, perform any additional accounting steps // you need, and return 0. r = release_file_lock(filp); } else r = -ENOTTY; /* unknown command */ return r; }
void stack_pop(stack_t *q) { if (q) list_remove_element(q, stack_top(q)); }
void main() { queue* myQueue = list_new(); assert(myQueue); assert(myQueue->head->num == 0); assert(myQueue->tail->num == 0); printf("test no queue passed in\n"); int ret = list_remove_element(NULL, 9); assert (ret == ULT_INVALID); /* printf("\ntest empty list\n"); ret = list_remove_element(myQueue, 12); assert (ret == ULT_NONE); */ printf("\ntest add to invalid queue\n"); ret = list_add_element(NULL); assert (ret == ULT_FAILED); printf("\ntest add 1 element\n"); ret = list_add_element(myQueue); printf("first element after tid 0: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest add another element\n"); ret = list_add_element(myQueue); printf("second element after tid 0: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); //TESTS FOR LIST_REMOVE_HEAD printf("\ntest remove first element 3 times\n"); ret = list_remove_head(myQueue); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); ret = list_remove_head(myQueue); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); ret = list_remove_head(myQueue); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest add another element after emptying queue\n"); ret = list_add_element(myQueue); printf("element: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); /* //TESTS FOR LIST_REMOVE_ELEMENT printf("\ntest remove third element\n"); ret = list_remove_element(myQueue, 2); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest remove second element\n"); ret = list_remove_element(myQueue, 1); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest remove first element\n"); ret = list_remove_element(myQueue, 0); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest remove no more elements\n"); ret = list_remove_element(myQueue, 1); printf("element's tid: %d\n", ret); assert (ret == ULT_INVALID); printf("\ntest add another element after emptying list\n"); ret = list_add_element(myQueue); printf("element: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest add 2nd element after emptying list\n"); ret = list_add_element(myQueue); printf("element: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest add 3rd element after emptying list\n"); ret = list_add_element(myQueue); printf("element: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); printf("\ntest remove second element AGAIN\n"); ret = list_remove_element(myQueue, 1); printf("element's tid: %d\n", ret); assert (ULT_isOKRet(ret)); printf("\ninside queue, %d elements\n", myQueue->numTCB); list_print(myQueue); list_print_backwards(myQueue); */ }
void list_free_all (pid_list_t head) { while (head != NULL) head = list_remove_element(head, head->pid); }
int osprd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { osprd_info_t *d = file2osprd(filp); // device info int r = 0; // return value: initially 0 unsigned cur_ticket; // is file open for writing? int filp_writable = (filp->f_mode & FMODE_WRITE) != 0; // This line avoids compiler warnings; you may remove it. (void) filp_writable, (void) d; // Set 'r' to the ioctl's return value: 0 on success, negative on error eprintk("%d\n", (int)current->pid); if (cmd == OSPRDIOCACQUIRE) { // EXERCISE: Lock the ramdisk. osp_spin_lock(&d->mutex); if (check_deadlock(d)) { //osp_spin_unlock(&d->mutex); //return -EDEADLK; r = -EDEADLK; } else { add_check_deadlock_list(current->pid, d); eprintk ("add_check_deadlock_list"); cur_ticket = d->ticket_head; d->ticket_head ++ ; } osp_spin_unlock(&d->mutex); if (r != 0) { return r; } if(filp_writable) { //osp_spin_lock(&d->mutex); int w = wait_event_interruptible(d->blockq, (d->number_write_lock==0&&d->number_read_lock==0&&cur_ticket==d->ticket_tail)); //Blocks the current task on a wait queue until a CONDITION becomes true. //A request for a write lock on a ramdisk file will block until no other files on that //ramdisk have a read or writeloc if(w == -ERESTARTSYS) { osp_spin_lock(&d->mutex); //if the process is interrupted by signal if (cur_ticket == d->ticket_tail) d->ticket_tail++; //already in the next avalable ticket else d->ticket_head--; //destory this ticket osp_spin_unlock(&d->mutex); return w; } osp_spin_lock(&d->mutex); //Acquire a mutex (lock the mutex) d->ticket_tail++; d->write_lock_holder = current->pid; d->number_write_lock = 1; filp->f_flags |= F_OSPRD_LOCKED; osp_spin_unlock(&d->mutex); //Release (unlock) the mutex } else { int w = wait_event_interruptible(d->blockq, (d->number_write_lock==0&&cur_ticket==d->ticket_tail)); //Blocks the current task on a wait queue until a CONDITION becomes true. //A request for a write lock on a ramdisk file will block until no other files on that //ramdisk have a read or writeloc if(w == -ERESTARTSYS) { osp_spin_lock(&d->mutex); //if the process is interrupted by signal if (cur_ticket == d->ticket_tail) d->ticket_tail++; //already in the next avalable ticket else d->ticket_head--; osp_spin_unlock(&d->mutex); //destory this ticket return w; } osp_spin_lock(&d->mutex); //Acquire a mutex (lock the mutex) d->ticket_tail++; add_read_pid(current->pid,d); d->number_read_lock++; filp->f_flags |= F_OSPRD_LOCKED; osp_spin_unlock(&d->mutex); //Release (unlock) the mutex } } else if (cmd == OSPRDIOCTRYACQUIRE) { // EXERCISE: ATTEMPT to lock the ramdisk. // // This is just like OSPRDIOCACQUIRE, except it should never // block. If OSPRDIOCACQUIRE would block or return deadlock, // OSPRDIOCTRYACQUIRE should return -EBUSY. // Otherwise, if we can grant the lock request, return 0. // Your code here (instead of the next two lines). if (filp_writable) { //atomically acquire write lock osp_spin_lock (&d->mutex); //atomicity if ((d->number_read_lock >0) || (d->number_write_lock>0)) { osp_spin_unlock (&d->mutex); return -EBUSY; } else //d->number_read_lock ==0) && (d->number_write_lock==0) { d->write_lock_holder = current->pid; d->number_write_lock ++; d->ticket_tail++; d->ticket_head++; filp -> f_flags |= F_OSPRD_LOCKED; osp_spin_unlock (&d->mutex); } } else //opened for read { //atomically acquire read lock osp_spin_lock (&d->mutex); { if (d->number_write_lock>0) //can't get read lock { osp_spin_unlock(&d->mutex); return -EBUSY; } else { add_read_pid (current->pid,d); d->number_read_lock++; d->ticket_tail++; d->ticket_head++; filp -> f_flags |= F_OSPRD_LOCKED; osp_spin_unlock (&d->mutex); } } } //eprintk("Attempting to try acquire\n"); //r = -ENOTTY; } else if (cmd == OSPRDIOCRELEASE) { // EXERCISE: Unlock the ramdisk. // // If the file hasn't locked the ramdisk, return -EINVAL. // Otherwise, clear the lock from filp->f_flags, wake up // the wait queue, perform any additional accounting steps // you need, and return 0. //osp_spin_lock (&d->mutex); if ((filp->f_flags & F_OSPRD_LOCKED)==0) { //osp_spin_unlock (&d->mutex); return -EINVAL; } else { osp_spin_lock (&d->mutex); d->check_deadlock_list_head = list_remove_element(d->check_deadlock_list_head,current->pid); if (filp_writable) //release the write locker { d->write_lock_holder = -1; d->number_write_lock --; } else //release the read locker { d->number_read_lock --; d->pid_list_head = list_remove_element(d->pid_list_head,current->pid); /*if (list_free_all (pid_list_head) == -ENOTTY) return -ENOTTY;*/ if (d->pid_list_head == NULL) return -ENOTTY; } filp->f_flags &= ~F_OSPRD_LOCKED; osp_spin_unlock (&d->mutex); wake_up_all (&d->blockq); } // Your code here (instead of the next line). //r = -ENOTTY; } else r = -ENOTTY; /* unknown command */ return r; }