void SeniorVMHandle::q_sub(long _register1,long _register2) { q_not(_register1); pop(T_INVALID); pop(T_TMP_REGISTER8); q_add(T_TMP_REGISTER8,_register2); // pop(T_INVALID); pop(T_TMP_REGISTER6); //eflag 1 q_copy_stack(); q_not_and(); pop(T_TMP_REGISTER7); //eflag 2 //pop(T_TMP_REGISTER8); //结果 q_not(T_TMP_REGISTER6); pop(T_INVALID); w_push_imm_sx(0xf7ea); q_not_and(); pop(T_INVALID); pop(T_TMP_REGISTER6); q_not(T_TMP_REGISTER7); pop(T_INVALID); w_push_imm_sx(0x815); q_not_and(); pop(T_INVALID); pop(T_TMP_REGISTER7); q_add(T_TMP_REGISTER6,T_TMP_REGISTER7); pop(T_INVALID); }
void pk_free(PACKET pkt) /* PACKET to place in free queue */ { int e; #ifdef LINKED_PKTS /* If we support scatter/gather, then we have to loop through the * whole chain of packets that were passed. */ while(pkt) { PACKET pknext; pknext = pkt->pk_next; #endif /* LINKED_PKTS */ /* validate the pkt before freeing */ e = pk_validate(pkt); if (e) { /* pk_validate () has already recorded the type of error that has occured */ #ifdef LINKED_PKTS if (e == -1) { pkt = pknext; continue; /* skip this pkt, examine the next pkt */ } #endif return; } if (pkt->inuse-- > 1) /* more than 1 owner? */ return; /* packet was cloned, don't delete yet */ #ifdef HEAPBUFS if (pkt->flags & PKF_HEAPBUF) { pk_free_heapbuf (pkt); } else #endif /* HEAPBUFS */ { if (pkt->nb_blen == bigbufsiz) q_add(&bigfreeq, (qp)pkt); else if (pkt->nb_blen == lilbufsiz) q_add(&lilfreeq, (qp)pkt); } #ifdef LINKED_PKTS pkt = pknext; } #endif }
// Must be locked over the queue - can be unlocked immediately following the call // Must be synchronized over the "queue put" semaphore // The "queue get" semaphore should be incremented following the call void queue_putRequest(struct request* req) { fprintf(stderr, "queue_putRequest: Adding request for connection %d with filename %s\n", req->fd, req->filename); q_add(req); }
/* * Test 4: construct 1/(2^n-1) */ static void test4(void) { rational_t r, aux, aux2; uint32_t i; printf("\nTest 4\n\n"); q_init(&r); q_init(&aux); q_init(&aux2); q_set32(&aux, 2); q_set_one(&aux2); q_set_one(&r); for (i=0; i<68; i++) { q_inv(&r); test_conversions(&r); q_inv(&r); q_mul(&r, &aux); q_add(&r, &aux2); } q_set_minus_one(&r); for (i=0; i<68; i++) { q_inv(&r); test_conversions(&r); q_inv(&r); q_mul(&r, &aux); q_sub(&r, &aux2); } q_clear(&aux); q_clear(&aux2); q_clear(&r); }
/* * Add a * r to b */ void arith_buffer_add_mono(arith_buffer_t *b, rational_t *a, pprod_t *r) { mlist_t *p, *aux; mlist_t **q; if (q_is_zero(a)) return; q = &b->list; p = *q; assert(p == b->list); while (pprod_precedes(p->prod, r)) { q = &p->next; p = *q; } // p points to a monomial with p->prod >= r, *q == p // q is &b->list if p is first in the list // q is &p0->next otherwise, where p0 = predecessor of p if (p->prod == r) { q_add(&p->coeff, a); } else { assert(pprod_precedes(r, p->prod)); aux = alloc_list_elem(b->store); aux->next = p; q_set(&aux->coeff, a); aux->prod = r; *q = aux; b->nterms ++; } }
/* * Check whether b is of the form a * X - a * Y * for a non-zero rational a and two products X and Y. * If so return X in *r1 and Y in *r2 */ bool arith_buffer_is_equality(arith_buffer_t *b, pprod_t **r1, pprod_t **r2) { mlist_t *p, *q; pprod_t *x, *y; rational_t a; bool is_eq; is_eq = false; if (b->nterms == 2) { p = b->list; q = p->next; x = p->prod; y = p->prod; if (x != empty_pp) { *r1 = x; *r2 = y; q_init(&a); q_set(&a, &p->coeff); q_add(&a, &q->coeff); is_eq = q_is_zero(&a); q_clear(&a); } } return is_eq; }
void visit(pfac f,pnode n){ int size; pthread_mutex_lock(&f->mutex); size=q_getlen(&f->qwait); if(size==f->capability){ //超载,不予响应 }else{ q_add(&f->qwait,n); } pthread_mutex_unlock(&f->mutex); pthread_cond_signal(&f->cond); }
/* * Get a value of of variable k that satisfies the constraints. * - the constraint is (a * var[k] + other vars + fixed sum) is an integer * - so a possible solution is to set all non-fixed vars to (z - fixed_sum)/a */ static void get_solution_for_var(int_constraint_t *cnstr, uint32_t k, rational_t *val, int32_t z) { rational_t qz; assert(k < cnstr->sum_nterms); q_init(&qz); q_set32(&qz, z); sum_of_fixed_terms(cnstr, val); q_neg(val); q_add(val, &qz); q_div(val, &cnstr->sum[k].coeff); q_clear(&qz); }
/* * Add poly to buffer b */ void arith_buffer_add_monarray(arith_buffer_t *b, monomial_t *poly, pprod_t **pp) { mlist_t *p, *aux; mlist_t **q; pprod_t *r1; assert(good_pprod_array(poly, pp)); q = &b->list; p = *q; while (poly->var < max_idx) { // poly points to a pair (coeff, x_i) // r1 = power product for x_i r1 = *pp; while (pprod_precedes(p->prod, r1)) { q = &p->next; p = *q; } // p points to monomial whose prod is >= r1 in the deg-lex order // q is either &b->list or &p0->next where p0 is the predecessor // of p in the list if (p->prod == r1) { q_add(&p->coeff, &poly->coeff); q = &p->next; p = *q; } else { assert(pprod_precedes(r1, p->prod)); aux = alloc_list_elem(b->store); aux->next = p; q_set(&aux->coeff, &poly->coeff); aux->prod = r1; *q = aux; q = &aux->next; b->nterms ++; } // move to the next monomial of poly poly ++; pp ++; } }
/* * Normalize an array of monomials a or size n: * 1) merge monomials with identical variables: * (c * v + d * v) --> (c + d) * v * 2) remove monomials with zero coefficients * 3) add end marker. * - a must be sorted. * - the function returns the size of the result = number of monomials * in a after normalization. */ uint32_t normalize_monarray(monomial_t *a, uint32_t n) { uint32_t i, j, v; rational_t c; if (n == 0) return n; j = 0; q_init(&c); v = a[0].var; // c := a[0].coeff, clear a[0].coeff to prevent memory leak q_copy_and_clear(&c, &a[0].coeff); for (i=1; i<n; i++) { if (a[i].var == v) { q_add(&c, &a[i].coeff); q_clear(&a[i].coeff); } else { if (q_is_nonzero(&c)) { a[j].var = v; // copy c into a[j].coeff, then clear c q_copy_and_clear(&a[j].coeff, &c); j ++; } v = a[i].var; // copy a[i].coeff in c then clear a[i].coeff q_copy_and_clear(&c, &a[i].coeff); } } if (q_is_nonzero(&c)) { a[j].var = v; q_copy_and_clear(&a[j].coeff, &c); j ++; } // set end-marker a[j].var = max_idx; return j; }
/* * Add r * b1 to b */ void arith_buffer_add_pp_times_buffer(arith_buffer_t *b, arith_buffer_t *b1, pprod_t *r) { mlist_t *p, *aux, *p1; mlist_t **q; pprod_t *r1; q = &b->list; p = *q; p1 = b1->list; while (p1->next != NULL) { r1 = pprod_mul(b->ptbl, p1->prod, r); while (pprod_precedes(p->prod, r1)) { q = &p->next; p = *q; } if (p->prod == r1) { q_add(&p->coeff, &p1->coeff); // q = p; // p = p->next; q = &p->next; p = *q; } else { assert(pprod_precedes(r1, p->prod)); aux = alloc_list_elem(b->store); aux->next = p; q_set(&aux->coeff, &p1->coeff); aux->prod = r1; // q->next = aux; // q = aux; *q = aux; q = &aux->next; b->nterms ++; } p1 = p1->next; } }
int handle_s_p2( clidata_t *client, char *hdrs ) { int gotten=0; int expected = get_content_length(hdrs); char *pkt; int cnt=0; queue_t *recvq = client->recvq; int chan1 = client->chan1; if( !expected ) { lprintf(log, WARN, "Client sent no Content-Length. Dropping."); return -1; } while( gotten < expected ) { if( (pkt=get_packet(chan1)) == NULL ) { lprintf(log, WARN, "get_packet() failed. Dropping client."); fdprintf(chan1, RESPONSE_500_ERR); return -1; } cnt++; gotten += iplen(pkt); dprintf(log, DEBUG, "got %d of %d bytes from client", gotten, expected); if( (q_add(recvq, pkt, Q_WAIT, iplen(pkt))) == -1 ) { lprintf(log, WARN, "q_add() failed. Dropping client."); fdprintf(chan1, RESPONSE_500_ERR); return -1; } } lprintf(log, INFO, "Got %d bytes in %d pkts", gotten, cnt); fdprintf(chan1, RESPONSE_204); return 0; }
int main() { // SETUP init(); Serial.begin(9600); tft.initR(INITR_BLACKTAB); // initialize screen // Setting the joystick button and LEDs pinMode(JOYSTICK_BUTTON, INPUT); digitalWrite(JOYSTICK_BUTTON, HIGH); // Initialize the SD card Serial.print("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("failed!"); while(true) {} // something is wrong } else {Serial.println("OK!");} // More initialization Serial.print("Initializing Raw SD card..."); if (!card.init(SPI_HALF_SPEED, SD_CS)) { Serial.println("failed!"); while(true) {} // something is wrong } else {Serial.println("OK!");} // Create states for different modes // C1 for Mode 1 - MENU screen // C2 for Mode 2 - Snake Game // C3 for Mode 3 - GAME OVER screen // C4 for Mode 4 - Choose level // C5 for Mode 5 - PAUSE screen typedef enum {C1 = 1, C2, C3, C4, C5, ERR} State; State state = C1; int select, snakelength; while (state!=ERR) { if (state == C1) { /// ====== MODE 1 - MENU ====== /// Serial.println("Currently in Mode 1"); snakelength = 1; init_vert = analogRead(JOYSTICK_VERT); init_horiz = analogRead(JOYSTICK_HORIZ); // preparations for the game - to not overlap with the pause menu q = q_create(720); i = 64; // x component j = 80; // y component q_add(q,i,j); // load into the queue random_x = food_x(); // load x coordinate of food piece random_y = food_y(); // load y coordinate of food piece pausedirection = 0; // set paused direction to 0 // reset grid to 0 for (int a = 0; a < 24; a++) { for (int b = 0; b < 30; b++) { grid[a][b] = 0; } } // display main menu snake(); tft.setTextSize(2); while(true) { // alternate highlighting of START unsigned long time = millis()%1000; int a = time%1000; if ((a<17)) { tft.setCursor(34, 83); tft.fillRoundRect(30,80,65,20,5,WHITE); tft.setTextColor(RED); tft.print("START"); } else if ((a>500) && (a<520)) { tft.setCursor(34, 83); tft.fillRoundRect(30,80,65,20,5,RED); tft.setTextColor(WHITE); tft.print("START"); } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } state = C4; } else if (state == C2) { /// ====== MODE 2 - SNAKE GAME ====== /// Serial.println("Currently in Mode 2"); delay(50); soundsetup(); //setting up sound pin // print the background tft.fillScreen(DARKRED); tft.fillRect(4,5,120,150,DARKGRN); // print the snake int x,y; x = q_frontx(q); y = q_fronty(q); tft.fillRect(x,y,5,5, WHITE); //Bringing the food in, outside while loop first. tft.fillRect(random_x, random_y, 5, 5, YELLOW); // do auto calibration int px, py; int lastmove; // read beginning direction chosen by user if (pausedirection == 0) { direction = read_direction(); } else { direction = pausedirection; } lastmove = direction; while (true) { // to direct movement // (without going in reverse direction of previous movement) // up if (direction == 1) { if (lastmove == 2) { direction = 2; j = j-5; } else { j = j+5; } q_add(q,i,j); } // down else if (direction == 2) { if (lastmove == 1) { direction = 1; j = j+5; } else { j = j-5; } q_add(q,i,j); } // right else if (direction == 3) { if (lastmove == 4) { direction = 4; i = i-5; } else { i = i+5; } q_add(q,i,j); } // left else if (direction == 4) { if (lastmove == 3) { direction = 3; i = i+5; } else { i = i-5; } q_add(q,i,j); } // if the direction is changed, store the new direction & last move int new_direc = read_direction(); if ((new_direc != direction) && (new_direc != 0)) { lastmove = direction; direction = new_direc; } // if the snake hits a piece of food, the food vanishes and gets replaced if ((i == random_x) && (j == random_y)) { // snake grows by 4 squares, except for the first time // this allows for it to end up as a max of 720 in the queue if (snakelength == 1) { q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); snakelength += 3; } else { q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); q_add(q,i,j); snakelength += 4; } if (snakelength < 720) { random_x = food_x(); random_y = food_y(); // if the snake is already there, find a new spot for the food while (grid[random_x/5][random_y/5-1] == 1) { random_x = food_x(); random_y = food_y(); } // print the new food tft.fillRect(random_x, random_y, 5, 5, YELLOW); } } // if the snake runs over itself if ((snakelength > 1) && (grid[i/5][j/5-1] == 1)) { delay(450); // pause when snake runs into itself int m = 0; soundLoop(); while(m < 6000) { int rand_x = dissolve_x(); int rand_y = dissolve_y(); tft.fillRect(rand_x, rand_y, 5, 5, BLACK); m++; } state = C3; break; } px = q_frontx(q); py = q_fronty(q); // reprint the snake if there is movement if ((i != px) || (j != py)) { tft.fillRect(i,j,5,5, WHITE); grid[i/5][j/5-1] = 1; // snake body is in grid tft.fillRect(px,py,5,5,DARKGRN); grid[px/5][py/5-1] = 0; // snake body is no longer in grid q_remove(q); // take away from the queue delay(speed); // controls the speed of the snake } // if any of the borders are hit if ((i < 4)||(j < 5)||(i > 119)||(j > 150)) { delay(450); // pause when border is hit // dissolve the screen int m = 0; soundLoop(); while(m < 6000) { int rand_x = dissolve_x(); int rand_y = dissolve_y(); tft.fillRect(rand_x, rand_y, 5, 5, BLACK); m++; } //~ delay(250); state = C3; break; } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { state = C5; break; } } } else if (state == C3) { /// ====== MODE 3 - GAME OVER ====== /// Serial.println("Currently in Mode 3"); q_destroy(q); // clear the queue tft.fillScreen(BLACK); tft.fillRoundRect(5,20,118,25,5,RED); tft.setCursor(10, 25); tft.setTextColor(BLACK); tft.setTextSize(2); tft.setTextWrap(true); tft.print("GAME OVER"); tft.print("\n"); tft.setCursor(10, 55); tft.setTextColor(RED); tft.setTextSize(1.5); if (snakelength >= 720) { snakelength = 720; tft.print("YOU WON! CONGRATZ"); } else { tft.print(" Oh no! You hit something!"); } tft.setCursor(10, 80); tft.setTextColor(WHITE); tft.setTextSize(1); tft.print("Length of Snake:"); tft.print(snakelength); tft.setCursor(10, 100); tft.print("Press the joystick to return to main menu"); // Read the Joystick - HIGH if not pressed, LOW otherwise while (true) { select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } state = C1; } else if (state == C4) { /// ====== MODE 4 - CHOOSE LEVEL ====== /// Serial.println("Currently in Mode 4"); // printing // snake display snake(); // difficulty levels tft.setTextSize(2); tft.setTextColor(WHITE); easy(RED); tft.setTextColor(RED); medium(WHITE); hard(WHITE); int selection = 1; int oldselection; while(true) { // read direction from the user for updating selection oldselection = selection; vertical = analogRead(JOYSTICK_VERT); // will be 0-1023 delay(100); // scroll down if (vertical > init_vert + 200) { selection++; if (selection > 3) { selection = 0; } } // scroll up else if (vertical < init_vert - 200) { selection--; if (selection < 0) { selection = 3; } } if (selection != oldselection) { update(selection); } // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { Serial.print("made selection: "); Serial.println(selection); if (selection == 1) {speed = 225;} else if (selection == 2) {speed = 150;} else if (selection == 3) {speed = 75;} break; } } state = C2; } else if (state == C5) { /// ====== MODE 5 - PAUSE MENU ====== /// Serial.println("Currently in Mode 5"); pausedirection = direction; // printing snake and pause snake(); tft.setTextSize(2); tft.setCursor(34, 73); tft.fillRoundRect(30,70,65,20,5,WHITE); tft.setTextColor(RED); tft.print("Pause"); while(true) { // Read the Joystick - HIGH if not pressed, LOW otherwise select = digitalRead(JOYSTICK_BUTTON); if (select == LOW) { break; } } // reset grid to 0 for (int a = 0; a < 24; a++) { for (int b = 0; b < 30; b++) { grid[a][b] = 0; } } state = C2; } //if not any of this: else { Serial.println("There has been an error"); state = ERR; } } Serial.end(); return 0; }
/** * This is a callback for validator errors. * * Purpose is to cumulate all encountered errors in a list, which is further * processed after the validation is done. If any malloc inside this routine * fails, the error is silently dropped and is not queued in the list of * errors. That makes algorithm a bit less complicated. * * @param ctx Hook's context pointer. * @param error Specification of encountered error. */ static void validerr_callback(void *ctx, xmlErrorPtr error) { /* used to get content of problematic xml tag */ xmlBufferPtr buf; xmlNodePtr node; int len; /* used for new list item creation */ epp_error *valerr; /* get context parameters */ qhead *error_list = ((valerr_ctx *) ctx)->err_list; xmlDocPtr doc = ((valerr_ctx *) ctx)->doc; void *pool = ((valerr_ctx *) ctx)->pool; /* in case of allocation failure simply don't log the error and exit */ if ((valerr = epp_malloc(pool, sizeof *valerr)) == NULL) return; /* * xmlError has quite a lot of fields, we are interested only in 3 * of them: code, message, node. */ /* * XXX error code should be further examined in order to get * more detailed error * valerr->code = error->code; */ /* * get error message (we don't use strdup because we have to * truncate trailing newline) */ len = strlen(error->message); valerr->reason = (char *) epp_malloc(pool, len); if (valerr->reason == NULL) return; strncpy(valerr->reason, error->message, --len); /*truncate trailing \n */ (valerr->reason)[len] = '\0'; /* XXX this needs to be done better way */ /* * recognized errors: * unknown command (2000) * required parameter missing (2003) * Parameter value range error (2004) * Parameter value syntax error (2005) * Unimplemented extension (2103) * ???Unimplemented command (2101)??? * ???Unimplemented option (2102)??? * all other errors are reported as: * command syntax error (2001) */ /* get content of problematic tag */ buf = xmlBufferCreate(); if (buf == NULL) return; node = (xmlNodePtr) error->node; if (node->ns != NULL) { xmlNsPtr nsdef; nsdef = xmlSearchNs(doc, node, node->ns->prefix); if (nsdef != NULL) xmlNewNs(node, nsdef->href, nsdef->prefix); } if (xmlNodeDump(buf, doc, (xmlNodePtr) node, 0, 0) < 0) { xmlBufferFree(buf); return; } valerr->value = epp_strdup(pool, (char *) buf->content); xmlBufferFree(buf); if (valerr->value == NULL) return; valerr->spec = errspec_not_valid; /* surrounding tags are included */ /* enqueue new error item */ if (q_add(pool, error_list, valerr)) /* we have nothing to do here in case of error */ return; }
int main(int argc, char *argv[]) { /* test harness */ int tests_passed = 0; int tests_failed = 0; /* create a queue with a size hint */ printf("Creating queue\n"); queue qp = q_create(20); /* how do we see if queue was propery initialized? */ /* add and remove one element */ int e1 = 42; q_add(qp, e1); printf("Test 1: "); q_printf(qp); printf("\n"); /* length should have gone up by one */ if ( q_length(qp) != 1 ) { printf("Test 1 failed, length %d should be 1\n", q_length(qp)); tests_failed++; } else { printf("Test 1 passed.\n"); tests_passed++; } printf("Test 2: "); int e2 = q_remove(qp); q_printf(qp); printf("\n"); if ( q_length(qp) != 0 ) { printf("Test 2.1 failed, length %d should be 0\n", q_length(qp)); tests_failed++; } else { printf("Test 2.1 passed.\n"); tests_passed++; } if ( e1 != e2 ) { printf("Test 2.2 failed, e2 %d should equal e1 %d\n", e2, e1); tests_failed++; } else { printf("Test 2.2 passed.\n"); tests_passed++; } printf("Test 3: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); for (int i=1; i<= 10; i++) { e1 = q_remove(qp); if ( q_length(qp) != 10-i ) { printf("Test 3.1 failed, length %d should be %d\n", q_length(qp), 10-i); tests_failed++; } else { tests_passed++; } if ( e1 != i ) { printf("Test 3.2 failed, element %d should be %d\n", e1, i); tests_failed++; } else { tests_passed++; } } printf("Test 4: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); for (int i=0; i < 10; i++) { int expected = i + 1; int actual = q_get_item(qp, i); if(expected != actual) { printf("Test 4 failed, element #%d should be %d but was %d\n", i, expected, actual); tests_failed++; } else { tests_passed++; } } // Reset to empty for (int i=1; i <= 10; i++) { q_remove(qp); } q_add(qp, e1); printf("Test 5.1: "); q_printf(qp); printf("\n"); /* length should have gone up by one */ if ( q_length(qp) != 1 ) { printf("Test 5.1 failed, length %d should be 1 before deletion\n", q_length(qp)); tests_failed++; } else { int actual = q_delete_item(qp, 0); if( q_length(qp) != 0) { printf("Test 5.1 failed, length %d should be 0 after deletion\n", q_length(qp)); tests_failed++; } else if(actual != e1) { printf("Test 5.1 failed, element retrieved from deleted: Expected: %d; Actual: %d\n", e1, actual); tests_failed++; } else { printf("Test 5.1 passed.\n"); tests_passed++; } } printf("Test 5.2: "); for (int i=1; i <= 10; i++) { q_add(qp, i); } q_printf(qp); printf("\n"); int deletedElement; deletedElement = q_delete_item(qp, 4); if(deletedElement != 5) { printf("Test 5.2 failed, element retrieved from deleted: Expected: 5; Actual: %d\n", deletedElement); tests_failed++; } deletedElement = q_delete_item(qp, 4); if(deletedElement != 6) { printf("Test 5.2 failed, element retrieved from deleted: Expected: 6; Actual: %d\n", deletedElement); tests_failed++; } q_printf(qp); printf("\n"); if( q_length(qp) != 8) { printf("Test 5.2 failed, length %d should be 8 after deletion\n", q_length(qp)); tests_failed++; } else { if(q_get_item(qp, 4) != 7) { printf("Test 5.2 failed, value of element at index 4 after deletion: Expected: 7; Actual: %d\n", q_get_item(qp, 4)); tests_failed++; } else { printf("Test 5.2 passed.\n"); tests_passed++; } } /* a fatal test */ if ( 0 ) { printf("Test 4: remove on empty queue\n"); e2 = q_remove(qp); tests_failed++; } printf("Tests Passed: %d\n", tests_passed); printf("Tests Failed: %d\n", tests_failed); }
PACKET pk_alloc_heapbuf (unsigned len) { u_long increment; u_char limit_exceeded = PKTALLOC_FALSE; PACKET p; u_char num_guard_bytes; #ifdef HEAPBUFS_DEBUG PHLEP phlep; #endif #ifdef NPDEBUG u_char i; char * bufp; #endif /* check to see if the caller is requesting more than the maximum * allowed individual allocation */ if (len > MAX_INDIVIDUAL_HEAP_ALLOC) { INCR_SHARED_VAR (hbufstats, TOOBIG_ALLOC_ERR, 1); return(NULL); } #ifdef NPDEBUG num_guard_bytes = ALIGN_TYPE + 1; #else num_guard_bytes = 0; #endif /* check to make sure that this allocation will not cause us to * exceed the maximum total allocation allowed from the heap. First * compute the increment. */ increment = sizeof (struct netbuf) + (len + num_guard_bytes); #ifdef HEAPBUFS_DEBUG /* also account for the size of the debug structure if HEAPBUFS_DEBUG * is enabled */ increment += sizeof (PHLE); #endif ENTER_CRIT_SECTION(&heap_curr_mem); heap_curr_mem += increment; if (heap_curr_mem > MAX_TOTAL_HEAP_ALLOC) { limit_exceeded = PKTALLOC_TRUE; } EXIT_CRIT_SECTION(&heap_curr_mem); if (limit_exceeded) { INCR_SHARED_VAR (hbufstats, LIMIT_EXCEEDED_ERR, 1); DECR_SHARED_VAR (heap_curr_mem, increment); return(NULL); } if (heap_type == HEAP_ACCESS_BLOCKING) UNLOCK_NET_RESOURCE (FREEQ_RESID); /* attempt to allocate a buffer for struct netbuf from the heap */ if ((p = ((struct netbuf *) HB_ALLOC (sizeof (struct netbuf)))) == 0) { /* restore state that existed prior to call into pk_alloc () */ if (heap_type == HEAP_ACCESS_BLOCKING) LOCK_NET_RESOURCE (FREEQ_RESID); INCR_SHARED_VAR (hbufstats, NB_ALLOCFAIL_ERR, 1); DECR_SHARED_VAR (heap_curr_mem, increment); return(NULL); } /* attempt to allocate data buffer from heap */ if ((p->nb_buff = HB_ALLOC (len + num_guard_bytes)) == 0) { HB_FREE (p); if (heap_type == HEAP_ACCESS_BLOCKING) LOCK_NET_RESOURCE (FREEQ_RESID); INCR_SHARED_VAR (hbufstats, DB_ALLOCFAIL_ERR, 1); DECR_SHARED_VAR (heap_curr_mem, increment); return(NULL); } #ifdef HEAPBUFS_DEBUG /* obtain storage for private heapbuf list element to help keep track of the heapbuf allocation */ if ((phlep = ((PHLEP) HB_ALLOC (sizeof(PHLE)))) == 0) { HB_FREE (p->nb_buff); HB_FREE (p); if (heap_type == HEAP_ACCESS_BLOCKING) LOCK_NET_RESOURCE (FREEQ_RESID); INCR_SHARED_VAR (hbufstats, PHLEB_ALLOCFAIL_ERR, 1); DECR_SHARED_VAR (heap_curr_mem, increment); return(NULL); } else { phlep->netbufp = p; phlep->databufp = p->nb_buff; phlep->length = len + num_guard_bytes; } #endif p->next = 0; p->nb_tstamp = 0L; /* mark buffer as being from heap and not interrupt-safe */ p->flags = (PKF_HEAPBUF | PKF_INTRUNSAFE); #ifdef NPDEBUG /* Add memory markers at start and end of block (to help detect memory corruption) */ bufp = p->nb_buff; for (i = 0; i < ALIGN_TYPE; i++) *(bufp + i) = 'M'; *(bufp + len + ALIGN_TYPE) = 'M'; p->nb_buff += ALIGN_TYPE; /* increment buffer's start pointer past guard band */ #endif p->nb_blen = len; if (heap_type == HEAP_ACCESS_BLOCKING) LOCK_NET_RESOURCE (FREEQ_RESID); #ifdef HEAPBUFS_DEBUG /* add element describing current allocation into the private heapbuf list. This * manipulation is already protected via ENTER_CRIT_SECTION () and EXIT_CRIT_SECTION * macros. */ q_add(&phlq, (qp)phlep); #endif /* increment the count of successfull allocations */ INCR_SHARED_VAR (hbufstats, HB_ALLOC_SUCC, 1); /* update the high watermark if appropriate */ ENTER_CRIT_SECTION(&heap_curr_mem); if (heap_curr_mem > heap_curr_mem_hi_watermark) { heap_curr_mem_hi_watermark = heap_curr_mem; } EXIT_CRIT_SECTION(&heap_curr_mem); return p; }
int pk_init (void) { PACKET packet; unsigned i; unsigned numpkts = bigbufs + lilbufs; u_char align_req; #ifdef ALIGN_BUFS align_req = ALIGN_BUFS; #else align_req = 0; #endif for (i = 0; i < numpkts; i++) { packet = (PACKET)NB_ALLOC(sizeof(struct netbuf)); if (packet == NULL) goto no_pkt_buf; #ifdef NPDEBUG if (i >= MAXPACKETS) { dprintf("pk_init: bad define\n"); return -1; } pktlog[i] = packet; /* save for debugging */ #endif packet->nb_tstamp = 0L; if (i < bigbufs) { #ifdef NPDEBUG { int j; /* for DEBUG compiles, bracket the data area with special chars */ packet->nb_buff = (char *)BB_ALLOC(bigbufsiz+ALIGN_TYPE+1); if (!(packet->nb_buff)) goto no_pkt_buf; /* Add memory markers for sanity check */ for(j = 0; j < ALIGN_TYPE; j++) *(packet->nb_buff + j) = 'M'; /* MMs at start of buf */ *(packet->nb_buff + bigbufsiz + ALIGN_TYPE) = 'M'; packet->nb_buff += ALIGN_TYPE; /* bump buf past MMs */ } #else packet->nb_buff = (char *)BB_ALLOC(bigbufsiz + align_req); #ifdef ALIGN_BUFS /* align start of buffer pointer to desired offset */ packet->nb_buff += (ALIGN_BUFS - (((u_long) packet->nb_buff) & (ALIGN_BUFS - 1))); #endif #endif if (!(packet->nb_buff)) goto no_pkt_buf; packet->nb_blen = bigbufsiz; q_add(&bigfreeq, packet); /* save it in big pkt free queue */ } else /* get a small buffer */ { #ifdef NPDEBUG { int j; /* for DEBUG compiles, bracket the data area with special chars */ packet->nb_buff = (char *)LB_ALLOC(lilbufsiz+ALIGN_TYPE+1); if (!(packet->nb_buff)) goto no_pkt_buf; /* Add memory markers for sanity check */ for(j = 0; j < ALIGN_TYPE; j++) *(packet->nb_buff + j) = 'M'; /* MMs at start of buf */ *(packet->nb_buff + lilbufsiz + ALIGN_TYPE) = 'M'; packet->nb_buff += ALIGN_TYPE; } #else packet->nb_buff = (char *)LB_ALLOC(lilbufsiz + align_req); #ifdef ALIGN_BUFS /* align start of buffer pointer to desired offset */ packet->nb_buff += (ALIGN_BUFS - (((u_long) packet->nb_buff) & (ALIGN_BUFS - 1))); #endif #endif if (!(packet->nb_buff)) goto no_pkt_buf; packet->nb_blen = lilbufsiz; q_add(&lilfreeq, packet); /* save it in little free queue */ } } bigfreeq.q_min = bigbufs; lilfreeq.q_min = lilbufs; #ifdef HEAPBUFS /* initialize the counters that keep track of the total amount of memory * allocated from the heap and the corresponding high watermark */ heap_curr_mem = 0; heap_curr_mem_hi_watermark = 0; /* set the heap's access type to blocking */ heap_type = HEAP_ACCESS_BLOCKING; #endif return 0; no_pkt_buf: #ifdef NPDEBUG dprintf("Netinit: calloc failed getting buffer %d\n", i); #endif return(-1); }