1

(まあ、これは私がここで質問するのは初めてであり、英語は私の第一言語ではないので、私の間違いのいくつかを許してください。そして私はプログラムのグリーンハンドです。)

OSの宿題をしているときにこの問題に遭遇し、関数SwitchToFiberをシミュレートするように求められました。現在の問題は、次に呼び出されたときに関数を回復するためにレジスタ値を保存する方法がわからないことです。

問題が明確かどうかはわかりません。私のコードは役に立たなかったと思いますが、以下に示します。

#include <stdio.h>

#define INVALID_THD NULL
#define N 5
#define REG_NUM 32
unsigned store[N][REG_NUM];
typedef struct
{
    void (*address) (void * arg);
    void* argu;
}thread_s;

thread_s ts[N];

void StartThds();
void YieldThd();
void *CreateThd(void (*ThdFunc)(void*), void * arg);
void thd1(void * arg);
void thd2(void * arg);
void StartThds()
{

}

void YieldThd()
{
    thd2((void*)2);

}

void *CreateThd(void (*ThdFunc)(void*), void * arg)
{
    ts[(int)arg].address = (*ThdFunc);
    ts[(int)arg].argu = arg;
}

void thd2(void * arg)
{
    for (int i = 4; i < 12; i++)
    {
        printf("\tthd2: arg=%d , i = %d\n", (int)arg, i);
        //in order to see clearly,i added /t abouve
        YieldThd();
    }
}

void thd1(void * arg)
{
/* 
    __asm__(

    );
*/ 
    for (int i = 0; i < 12; i++)
    {
        printf("thd1: arg=%d , i = %d\n", (int)arg, i);
        YieldThd();
    }
}

int main()
{
    //this is my first plan, to store the register value in some static arry 
    for(int i = 0; i<N; i++)
        for(int j = 0; j<REG_NUM; j++)
            store[i][j] = 0;
    //create the two thread 
    if (CreateThd(thd1, (void *)1) == INVALID_THD)
    {
        printf("cannot create\n");
    }
    if (CreateThd(thd2, (void *)2) == INVALID_THD)
    {
        printf("cannot create\n");
    }


    ts[1].address(ts[1].argu);      //thd1((void*)1),argu = 1; 
//  StartThds();
    return 0;
}

これが今私が持っているコード全体です。どの部分が役立つかわからないので、すべて上に置きます。ご覧のとおり、それらのほとんどはまだ空です。

4

2 に答える 2

1

(コメントで指摘されているように)このためにアセンブリを作成する必要がない可能性があります。おそらく、を使用するだけsetjmp()/longjmp()で済ませて、必要な状態保存を実行させることができます。

于 2012-05-16T09:06:02.300 に答える
0

私は以前にこれを行ったことがありますが、私は常に詳細を調べる必要があります。もちろん、以下は単なる擬似コードです。

基本的には、レジスタを使用して構造体を作成します。

typedef struct regs {
   int ebx; //make sure these have the right size for the processors.
   int ecx;
   //...  for all registers you wish to backup
} registers;

//when changing from one thread
asm( //assembly varies from compiler to compiler check your manual
  "mov ebx, thread1.register.ebx;
   mov ecx, thread1.register.ecx;"
  // and so on

  //very important store the current program counter to the return address of this fu nction so we can continue from ther
  // you must know where the return address is stored
  "mov return address, thread1.register.ret"
);

//restore the other threads registers
asm(
  "mov thread2.register.ebx, ebx;
   mov thread2.register.ecx, ecx;
   //now restoer the pc and let it run
   mov thread2.register.ret, pc; //this will continue from where we stopped before
);

これは多かれ少なかれそれがどのように機能するかの原則です。あなたはこれを学んでいるので、あなたはあなた自身で残りを理解することができるはずです。

于 2012-05-16T09:25:35.157 に答える