blob: 7ff3b233b4f10308d0f6031ad592180da387a477 [file] [log] [blame]
/*
* Copyright 2013 Google Inc.
*/
//#define DEBUG
#include <setjmp.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <err.h>
/* General idea: if we're at the base for this func (base of ERRSTACK in the
* scope where ERRSTACK and waserror are used), we need to find and save the
* previous errbuf, so we know how to pop back.
*
* The main goal of this is to track and advertise (via pcpui) the errbuf that
* should be jumped to next (when we call error()). Note that the caller of
* this (waserror()) will fill the jumpbuf shortly with its context.
*
* When we enter, curindex points to the slot we should use. First time, it is
* 0, and we'll set cur_eb to slot 0. When we leave, curindex is set to the
* next free slot. */
struct errbuf *errpush(struct errbuf *errstack, int stacksize, int *curindex,
struct errbuf **prev_errbuf)
{
struct errbuf *cbuf;
printd("pushe %p %d %dp\n", errstack, stacksize, *curindex);
if (*curindex == 0)
*prev_errbuf = get_cur_errbuf();
if (*curindex >= stacksize)
panic("Error stack overflow");
cbuf = &errstack[*curindex];
set_cur_errbuf(cbuf);
(*curindex)++;
return cbuf;
}
/* Undo the work of errpush, and advertise the new errbuf used by error() calls.
* We only need to be tricky when we reached the beginning of the stack and need
* to check the prev_errbuf from a previous ERRSTACK/function.
*
* When we enter, curindex is the slot of the next *free* errstack (the one we'd
* push into if we were pushing. When we leave, it will be decreased by one,
* and will still point to the next free errstack (the one we are popping).
*/
struct errbuf *errpop(struct errbuf *errstack, int stacksize, int *curindex,
struct errbuf *prev_errbuf)
{
struct errbuf *cbuf;
printd("pope %p %d %d\n", errstack, stacksize, *curindex);
/* curindex now points to the slot we are popping*/
*curindex = *curindex - 1;
/* We still need to advertise the previous slot, which is one back from
* curindex. If curindex is 0, that means the next free slot is the
* first of our errstack. In this case, we need to advertise the prev.
*/
if (*curindex < 0)
panic("Error stack underflow");
cbuf = (*curindex == 0) ? prev_errbuf: &errstack[*curindex - 1];
set_cur_errbuf(cbuf);
return cbuf;
}