/*============================================================================== * - msgQ_receive() * * - try to receive a message from a msgQ, this maybe block the call task */ OS_STATUS msgQ_receive (MSG_QUE *pMsgQ, void *buffer, uint32 buf_len, uint32 timeout) { int cpsr_c; OS_STATUS status = OS_STATUS_ERROR; DL_NODE *pMsgNode = NULL; OS_TCB *pWaitTcb = NULL; cpsr_c = CPU_LOCK(); again: if (pMsgQ->cur_num > 0) { /* have message(s) */ pMsgQ->cur_num--; G_p_current_tcb->delay_ticks = 0; /* * copy message context to msg_list */ pMsgNode = dlist_get(&pMsgQ->msg_list); memcpy(buffer, (void *)(pMsgNode + 1), MIN(buf_len, pMsgQ->max_len)); free(pMsgNode); /* * if there are some task wait for send, alive one of them */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_send_list); if (pWaitTcb != NULL) { readyQ_put(pWaitTcb); } status = OS_STATUS_OK; } else { /* no message */ if (timeout != 0) { readyQ_remove (G_p_current_tcb); G_p_current_tcb->delay_ticks = timeout; G_p_current_tcb->status = TASK_STATUS_PEND_MSG_R; /* msg receive pend */ G_p_current_tcb->pend_obj = pMsgQ; dlist_add (&pMsgQ->wait_recv_list, (DL_NODE *)G_p_current_tcb); CONTEXT_SWITCH(); if (G_p_current_tcb->delay_ticks != 0) { timeout = G_p_current_tcb->delay_ticks; /* recalculate timeout value */ goto again; } } } CPU_UNLOCK(cpsr_c); return status; }
/*============================================================================== * - cbi_delete_all() * * - clear the CBI list, and free all cbi's memory */ OS_STATUS cbi_delete_all () { GUI_CBI *pCBI = (GUI_CBI *)dlist_get (&_G_cbi_list); while (pCBI != NULL) { if (pCBI->data != NULL) { free (pCBI->data); } free (pCBI); pCBI = (GUI_CBI *)dlist_get (&_G_cbi_list); } return OS_STATUS_OK; }
/*============================================================================== * - _album_cb_home() * * - quit album app, delete picture file name nodes memory */ static OS_STATUS _album_cb_home (GUI_CBI *pCBI, GUI_COOR *p_cbi_coor) { PIC_NAME_NODE *temp_pic_node = (PIC_NAME_NODE *)dlist_get (&_G_pic_list); while (temp_pic_node != NULL) { free (temp_pic_node); temp_pic_node = (PIC_NAME_NODE *)dlist_get (&_G_pic_list); } gra_clear (GUI_BG_COLOR); cbf_go_home (pCBI, p_cbi_coor); return OS_STATUS_OK; }
/*============================================================================== * - msgQ_send() * * - try to send a message to a msgQ, this maybe block the call task */ OS_STATUS msgQ_send (MSG_QUE *pMsgQ, const void *buffer, uint32 buf_len, uint32 timeout) { int cpsr_c; OS_STATUS status = OS_STATUS_ERROR; DL_NODE *pMsgNode = NULL; OS_TCB *pWaitTcb = NULL; cpsr_c = CPU_LOCK(); again: if (pMsgQ->cur_num < pMsgQ->max_num) { /* there is some space */ pMsgQ->cur_num++; G_p_current_tcb->delay_ticks = 0; /* * alloc a messege node and add it into messge list */ pMsgNode = malloc(sizeof(DL_NODE) + pMsgQ->max_len); memcpy((void *)(pMsgNode + 1), buffer, MIN(buf_len, pMsgQ->max_len)); dlist_add(&pMsgQ->msg_list, pMsgNode); /* * get a wait for Receive task and put it into readyQ */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_recv_list); if (pWaitTcb != NULL) { readyQ_put(pWaitTcb); } status = OS_STATUS_OK; } else { /* there is no space */ if (timeout != 0) { readyQ_remove (G_p_current_tcb); G_p_current_tcb->delay_ticks = timeout; G_p_current_tcb->status = TASK_STATUS_PEND_MSG_S; /* msg send pend */ G_p_current_tcb->pend_obj = pMsgQ; dlist_add (&pMsgQ->wait_send_list, (DL_NODE *)G_p_current_tcb); CONTEXT_SWITCH(); if (G_p_current_tcb->delay_ticks != 0) { timeout = G_p_current_tcb->delay_ticks; /* recalculate timeout value */ goto again; } } } CPU_UNLOCK(cpsr_c); return status; }
/*============================================================================== * - semC_flush() * * - pop all wait task, and set semC's count is 0 */ OS_STATUS semC_flush (SEM_CNT *pSemC) { int cpsr_c; OS_TCB *pOutTcb = NULL; cpsr_c = CPU_LOCK(); pOutTcb = (OS_TCB *)dlist_get(&pSemC->wait_list); while (pOutTcb != NULL) { /* when this task resume, semC_take() return ERROR immediately */ pOutTcb->delay_ticks = 0; readyQ_put(pOutTcb); pOutTcb = (OS_TCB *)dlist_get(&pSemC->wait_list); } pSemC->count = 0; CPU_UNLOCK(cpsr_c); return OS_STATUS_OK; }
/*============================================================================== * - _list_dir() * * - refresh the directory list nodes */ static int _list_dir (const char *path, DL_LIST *pDirList) { int i; yaffs_DIR *d; yaffs_dirent *de; DIR_LIST_NODE *pListNode = NULL; char full_name[PATH_LEN_MAX]; d = yaffs_opendir(path); /* free previous list nodes */ pListNode = (DIR_LIST_NODE *)dlist_get (pDirList); while (pListNode != NULL) { free (pListNode); pListNode = (DIR_LIST_NODE *)dlist_get (&_G_dir_list); } if (!d) { return 0; } /* alloc new list nodes */ for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) { pListNode = malloc (sizeof (DIR_LIST_NODE)); if (pListNode != NULL) { strcpy(pListNode->name, de->d_name); strcpy(full_name, path); strcat(full_name, de->d_name); if (yaffs_is_dir (full_name)) { strcat(pListNode->name, "/"); } dlist_add (pDirList, (DL_NODE *)pListNode); } } yaffs_closedir(d); return i; }
void* dlist_get_ts (DList* list, int32_t index) { assert(NULL != list); assert(0 <= index); assert(NULL != list->mutex); pthread_mutex_lock(list->mutex); void* ret = dlist_get(list, index); pthread_mutex_unlock(list->mutex); return ret; }
/*============================================================================== * - semC_give() * * - give a semC. one give inc count */ OS_STATUS semC_give (SEM_CNT *pSemC) { int cpsr_c; OS_STATUS status = OS_STATUS_OK; OS_TCB *pOutTcb = NULL; cpsr_c = CPU_LOCK(); if (pSemC->count < pSemC->max_count) { /* have space */ pSemC->count++; pOutTcb = (OS_TCB *)dlist_get(&pSemC->wait_list); if (pOutTcb != NULL) { readyQ_put(pOutTcb); } } else { /* no space */ status = OS_STATUS_ERROR; } CPU_UNLOCK(cpsr_c); return status; }
/*============================================================================== * - msgQ_delete() * * - free all message, pop all wait task, * - remove from _G_msgQ_list, * - free msgQ if it's malloced */ OS_STATUS msgQ_delete (MSG_QUE *pMsgQ) { int cpsr_c; DL_NODE *pMsgNode = NULL; OS_TCB *pWaitTcb = NULL; cpsr_c = CPU_LOCK(); /* free message */ pMsgNode = dlist_get(&pMsgQ->msg_list); while (pMsgNode != NULL) { free(pMsgNode); pMsgNode = dlist_get(&pMsgQ->msg_list); } /* pop send wait task */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_send_list); if (pWaitTcb != NULL) { pWaitTcb->delay_ticks = 0; /* when this task resume, msgQ_send() return ERROR */ readyQ_put(pWaitTcb); pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_send_list); } /* pop recv wait task */ pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_recv_list); if (pWaitTcb != NULL) { pWaitTcb->delay_ticks = 0; /* when this task resume, msgQ_receive() return ERROR */ readyQ_put(pWaitTcb); pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_recv_list); } /* remove from <_G_msgQ_list> */ dlist_remove (&_G_msgQ_list, (DL_NODE *)pMsgQ); CPU_UNLOCK(cpsr_c); if ((uint32)pMsgQ >= CONFIG_MEM_HEAP_LOW && (uint32)pMsgQ < CONFIG_MEM_HEAP_HIGH) { free (pMsgQ); } return OS_STATUS_OK; }
/*============================================================================== * - _get_cmd_line() * * - get user typed string from uart0 */ int _get_cmd_line (char *s) { int i = 0; /* readed char number so far */ int c; /* temp read char */ char tab_matched_cmd[PATH_LEN_MAX] = ""; int have_tab = 0; _SHELL_HISTORY_NODE *p_history_index = NULL; _SHELL_HISTORY_NODE *p_history_node = NULL; static DL_LIST history_list = {NULL, NULL}; static int history_num = 0; while (i < _CMD_LEN_MAX) { c = serial_getc(); /* check Tab key */ if ((c != '\t') && have_tab) { int s_len = strlen (s); int prefix_len; prefix_len = _get_last_cmd_len (s); strcpy (&s[s_len - prefix_len], tab_matched_cmd); i = strlen (s); have_tab = 0; } switch (c) { case '\r': /* Enter */ s[i] = '\0'; serial_putc('\n'); goto got_it; case '\b': /* Backspace */ if (i >= 1) { serial_puts("\b \b"); i--; } break; case '\t': /* Tab */ have_tab = 1; s[i] = '\0'; #if 0 /* erase */ while (i--) serial_puts("\b \b"); i = cmd_tab(s, tab_matched_cmd); serial_puts(tab_matched_cmd); #else { extern int yaffs_tab (const char *prefix, char *cmd_line); int prefix_len; int erase_chars; prefix_len = _get_last_cmd_len (s); erase_chars = i - (strlen (s) - prefix_len); if (erase_chars == i) { i = cmd_tab(s, tab_matched_cmd); } else { i -= erase_chars; i += yaffs_tab(&s[i], tab_matched_cmd); } while (erase_chars--) serial_puts("\b \b"); serial_puts(tab_matched_cmd); } #endif break; /* ignore */ case '\033': /* Esc Up Down Right Left */ if (serial_tstc() && (serial_getc() == '[')) { if (serial_tstc()) { c = serial_getc(); switch (c) { case 'A': /* Up */ if (p_history_index == NULL) { p_history_index = (_SHELL_HISTORY_NODE *)DL_LAST(&history_list); } else { p_history_index = (_SHELL_HISTORY_NODE *)DL_PREVIOUS(p_history_index); } i = _load_history (s, i, p_history_index); break; case 'B': /* Down */ if (p_history_index != NULL) { p_history_index = (_SHELL_HISTORY_NODE *)DL_NEXT(p_history_index); } i = _load_history (s, i, p_history_index); break; case 'C': /* Right */ break; case 'D': /* Left */ break; default: break; } } } break; default: /* other */ s[i++] = c; serial_putc(c); break; } } /* user command line length more than 1023 */ if (i == _CMD_LEN_MAX) { s[_CMD_LEN_MAX - 1] = '\0'; i--; } got_it: /* this command is not NULL and not equal last command */ if ((i != 0) && ((DL_EMPTY(&history_list)) || (strcmp (s, ((_SHELL_HISTORY_NODE *)DL_LAST(&history_list))->cmd_line))) ) { if (history_num < _HISTORY_MAX) { p_history_node = malloc (sizeof (_SHELL_HISTORY_NODE)); history_num++; } else { p_history_node = (_SHELL_HISTORY_NODE*)dlist_get(&history_list); } strcpy (p_history_node->cmd_line, s); dlist_add (&history_list, (DL_NODE *)p_history_node); } return i; }
#include "helpers.h" TEST(get_does_not_work_for_empty_list) { USING(dlist_new(sizeof(int))) { assertEquals(dlist_get(list, 0, NULL), NULL); assertEquals(dlist_get(list, 1, NULL), NULL); assertEquals(dlist_get(list, 2, NULL), NULL); assertEquals(dlist_get(list, 0, &ret), NULL); assertEquals(dlist_get(list, 1, &ret), NULL); assertEquals(dlist_get(list, 2, &ret), NULL); } } TEST(get_does_not_work_for_illegal_index) { USING(dlist_new(sizeof(int))) { assertNotEquals(dlist_append(list, NULL), NULL); assertEquals(dlist_get(list, 1, NULL), NULL); assertEquals(dlist_get(list, 1, &ret), NULL); assertNotEquals(dlist_append(list, NULL), NULL); assertEquals(dlist_get(list, 2, NULL), NULL); assertEquals(dlist_get(list, 2, &ret), NULL); assertNotEquals(dlist_append(list, NULL), NULL); assertEquals(dlist_get(list, 3, NULL), NULL); assertEquals(dlist_get(list, 3, &ret), NULL); } } TEST(get_works_without_data) { USING(dlist_new(sizeof(int))) {
/** * Rank is processor number, name is the name of the person toiling away. */ void worker(int rank, char* name) { srand(time(NULL) + rank); int workTicks = rand_num(5); int currWorkTick = 0; int myFloor = rand_num(3); int desiredFloor = myFloor; int floorOfElevator = 0; enum State state = Work; int stillWorking = 1; int wantstobeWorking = 1; int unusedInt; while (stillWorking) { // send whether or not we still have work to do MPI_Reduce(&wantstobeWorking, &unusedInt, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); // receive what floor the elevator is on MPI_Bcast(&floorOfElevator, 1, MPI_INT, 0, MPI_COMM_WORLD); // all workers indicated no more work, so we abandon what we were doing if (floorOfElevator == -1) { stillWorking = 0; struct Bucket *curBuck = firstBuck; int len = 0; while (curBuck != 0) { // printf("%d has a bucket for %s with a content of %d\n", rank, (*curBuck).key, (*curBuck).value); // We send the key and a value. // Here, the value is a magic number: If the value is zero, then all the buckets have been sent. MPI_Send(&(curBuck->value), 1, MPI_INT, 0, 0, MPI_COMM_WORLD); len = strlen(curBuck->key); MPI_Send(&len, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); MPI_Send(curBuck->key, len, MPI_CHAR, 0, 0, MPI_COMM_WORLD); curBuck = curBuck->next; } len = 0; MPI_Send(&len, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); } if (state == Elevator) { dumpLog(1, rank, name, " is on the elevator to floor ", desiredFloor); printf("%d is riding the elevator to floor %d\n", rank, desiredFloor); // are we on the right floor? if so, state becomes work if (floorOfElevator == desiredFloor) { dumpLog(1, rank, name, " got off the elevator on floor ", desiredFloor); printf("%d got off elevator and is now working on floor %d\n", rank, desiredFloor); state = Work; myFloor = desiredFloor; } } else if (state == Work) { // do work if (assgn == 2) { if (curLine < list->size) { // reduce by counting the words on the lines that have been transmitted char* thestring; dlist_get(&list, curLine, &thestring); printf("%d works on: %s", rank, thestring); curLine++; // actually do some work with thestring, e.g. count the words and put them into bins // go through the string and write each substring into curStr; char curStr[] = "012345678901234567890123456789012345678901234567890123456789"; int inword = 0; int curInCurStr = 0; for (int curInString = 0; thestring[curInString] != '\0'; curInString++) { if ((thestring[curInString] == ' ') || (thestring[curInString] == '\t') || (thestring[curInString] == '\n') || (thestring[curInString] == '\r')) { if (inword) { inword = 0; // for that, we iterate through all buckets to see if there already is an appropriate one, // and if not, then we add a bucket struct Bucket *curBuck = firstBuck; struct Bucket *prvBuck = 0; while (curBuck != 0) { //printf("%d compares %s to %s\n", rank, curStr, curBuck->key); if (strcmp(curBuck->key, curStr) == 0) { // we increase the value of the current bucket by one curBuck->value = curBuck->value + 1; // printf("%d increased a bucket's value for %s\n", rank, curStr); goto foundABucket; } prvBuck = curBuck; curBuck = curBuck->next; if (curBuck == prvBuck) { curBuck = 0; } } struct Bucket *addBuck = malloc(sizeof *addBuck); // printf("%d added a bucket for %s\n", rank, curStr); addBuck->key = strdup(curStr); addBuck->value = 1; addBuck->next = 0; if (firstBuck == 0) { firstBuck = addBuck; } else { prvBuck->next = addBuck; } foundABucket: ; curStr[0] = '\0'; curInCurStr = 0; } } else { inword = 1; curStr[curInCurStr] = thestring[curInString]; curStr[curInCurStr+1] = '\0'; curInCurStr++; } } } else { wantstobeWorking = false; } } currWorkTick++; dumpLog(1, rank, name, " did some work on floor ", myFloor); printf("%d did some work on floor %d [%d/%d]\n", rank, myFloor, currWorkTick, workTicks); //receive our next task and wait for the elevator if (currWorkTick >= workTicks) { dumpLog(1, rank, name, " is done with work on floor ", myFloor); printf("%d is done with work on floor %d\n", rank, myFloor); currWorkTick = 0; workTicks = rand_num(5); desiredFloor = myFloor; while (desiredFloor == myFloor) { desiredFloor = rand_num(3); } state = Waiting; } } else if (state == Waiting) { dumpLog(1, rank, name, " waits before going to floor ", desiredFloor); printf("%d is waiting for the elevator to go to floor %d from floor %d\n", rank, desiredFloor, myFloor); if (floorOfElevator == myFloor) { dumpLog(1, rank, name, " got on the elevator to floor ", desiredFloor); printf("%d got on the elevator to go to floor %d\n", rank, desiredFloor); state = Elevator; } } } }
void gc_mark_vector( gbg_collector_t *gc, dlist_t *dlst ){ unsigned i; foreach_in_dlist( i, dlst ){ gc_move_upwards( gc, dlist_get( dlst, i ), GC_COLOR_GREY ); }
int test_dlist() { puts("##########################################"); puts("starting double linked list tests"); puts("##########################################"); int value = 0; struct DList *dlist = dlist_create(); puts("empty double list created"); if (dlist_length(dlist) != 0) { printf("dlist_length of empty list should be zero\n"); return 0; } puts("dlist_length ok"); // Insert value 101 and test functions dlist_insert(dlist, 0, 101); if (dlist_length(dlist) != 1) { printf("dlist_length should be 1\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_get (1)\n"); return 0; } if (value != 101) { printf("dlist_get should return value 101\n"); return 0; } // Insert value 202 and test functions dlist_insert(dlist, 0, 202); if (dlist_length(dlist) != 2) { printf("dlist_length should return 2\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_length (2)\n"); return 0; } if (value != 202) { printf("dlist_get should return 202\n"); return 0; } puts("dlist_get ok"); // Test remove function if (dlist_remove(dlist, 1) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 1) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } puts("dlist_remove ok"); // test dlist_append() dlist_append(dlist, -5); dlist_append(dlist, 1); dlist_append(dlist, 15); if (dlist_length(dlist) != 3) { printf("dlist_length should return 0\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != -5) { printf("dlist_get should return -5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 1) { printf("dlist_get should return 1\n"); return 0; } if (dlist_get(dlist, 2, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 15) { printf("dlist_get should return 15\n"); return 0; } puts("dlist_append ok"); // test dlist insert dlist_insert(dlist, -5, 0); if (dlist_length(dlist) != 4) { printf("dlist_length should return 4\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 0) { printf("dlist_get should return 0\n"); return 0; } dlist_insert(dlist, 1, 100); if (dlist_length(dlist) != 5) { printf("dlist_length should return 5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 100) { printf("dlist_get should return 100\n"); return 0; } dlist_insert(dlist, 10, 500); if (dlist_length(dlist) != 6) { printf("dlist_length should return 6\n"); return 0; } if (dlist_get(dlist, 5, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 500) { printf("dlist_get should return 500\n"); return 0; } puts("dlist_insert ok"); // test print and print reversed puts("print current dlist"); dlist_print(dlist); puts("printing reversed dlist"); dlist_print_reverse(dlist); puts("check print and print_reversed for yourself!"); puts("##########################################"); puts("all tests of double linked lists completed"); puts("##########################################"); puts("------------------------------------------"); dlist_delete(dlist); return 1; }