سؤال

أنا أقوم بتطوير نظام تشغيل، وبدلاً من برمجة النواة، أقوم بتصميم النواة.يستهدف نظام التشغيل هذا بنية x86 وهدفي هو أجهزة الكمبيوتر الحديثة.العدد المقدر لذاكرة الوصول العشوائي المطلوبة هو 256 ميجابايت أو أكثر.

ما هو الحجم المناسب لتشغيل المكدس لكل مؤشر ترابط على النظام؟هل يجب أن أحاول تصميم النظام بحيث يمكن تمديد المكدس تلقائيًا إذا تم الوصول إلى الحد الأقصى للطول؟

أعتقد أنه إذا كنت أتذكر بشكل صحيح أن الصفحة الموجودة في ذاكرة الوصول العشوائي (RAM) يبلغ حجمها 4 كيلو بايت أو 4096 بايت وهذا لا يبدو كثيرًا بالنسبة لي.يمكنني بالتأكيد أن أرى الأوقات، خاصة عند استخدام الكثير من التكرار، حيث أرغب في الحصول على أكثر من 1000 عدد صحيح في ذاكرة الوصول العشوائي مرة واحدة.الآن، الحل الحقيقي هو أن يقوم البرنامج بذلك باستخدام malloc وإدارة موارد الذاكرة الخاصة بها، لكني أود حقًا معرفة رأي المستخدم في هذا الشأن.

هل 4K كبير بما يكفي لمجموعة من برامج الكمبيوتر الحديثة؟هل يجب أن تكون المكدس أكبر من ذلك؟هل يجب أن يتم توسيع المكدس تلقائيًا لاستيعاب أي نوع من الأحجام؟أنا مهتم بهذا من وجهة نظر المطور العملي ومن الناحية الأمنية.

هل 4K كبيرة جدًا بالنسبة للمكدس؟بالنظر إلى التنفيذ العادي للبرنامج، خاصة من وجهة نظر الفئات في C++، لاحظت أن كود المصدر الجيد يميل إلى ذلك malloc/new البيانات التي تحتاجها عند إنشاء الفئات، لتقليل البيانات التي يتم طرحها في استدعاء دالة.

ما لم أتطرق إليه حتى هو حجم ذاكرة التخزين المؤقت للمعالج.من الناحية المثالية، أعتقد أن المكدس سيكون موجودًا في ذاكرة التخزين المؤقت لتسريع الأمور ولست متأكدًا مما إذا كنت بحاجة إلى تحقيق ذلك، أو إذا كان المعالج يمكنه التعامل معها نيابةً عني.كنت أخطط للتو لاستخدام ذاكرة الوصول العشوائي القديمة المملة لأغراض الاختبار.لا أستطيع أن أقرر.ما هي الخيارات؟

هل كانت مفيدة؟

المحلول

يعتمد حجم المكدس على ما تفعله مؤشرات الترابط الخاصة بك.نصيحتي:

  • جعل حجم المكدس معلمة في وقت إنشاء الخيط (ستقوم سلاسل الرسائل المختلفة بأشياء مختلفة، وبالتالي ستحتاج إلى أحجام مكدس مختلفة)
  • توفير افتراضي معقول لأولئك الذين لا يريدون أن ينزعجوا من تحديد حجم المكدس (4K يجذب مهووس التحكم بداخلي، لأنه سيؤدي إلى حصول المكدس المسرف على الإشارة بسرعة كبيرة)
  • فكر في كيفية اكتشاف تجاوز سعة المكدس والتعامل معه.يمكن أن يكون الكشف أمرًا صعبًا.يمكنك وضع صفحات الحماية - الفارغة - في نهايات مجموعتك، وهذا سيعمل بشكل عام.لكنك تعتمد على سلوك الخيط السيئ في عدم القفز فوق هذا الخندق والبدء في تلويث ما وراءه.عمومًا، لن يحدث هذا... ولكن بعد ذلك، هذا ما يجعل الأخطاء الصعبة حقًا صعبة.تتضمن الآلية المحكمة اختراق برنامج التحويل البرمجي الخاص بك لإنشاء كود فحص المكدس.أما بالنسبة للتعامل مع تجاوز سعة المكدس، فستحتاج إلى مكدس مخصص في مكان آخر حيث سيتم تشغيل الخيط المخالف (أو ملاكه الحارس، أيًا كان من تقرره - أنت مصمم نظام التشغيل، بعد كل شيء).
  • أوصي بشدة بوضع علامة على نهايات المكدس الخاص بك بنمط مميز، بحيث عندما تمر خيوطك فوق النهايات (وهي تفعل ذلك دائمًا)، يمكنك على الأقل الذهاب إلى مرحلة ما بعد الوفاة ورؤية أن شيئًا ما قد خرج بالفعل من مكانه كومة.صفحة 0xDEADBEEF أو شيء من هذا القبيل مفيد.

بالمناسبة، تكون أحجام صفحات x86 بشكل عام 4K، لكن ليس من الضروري أن تكون كذلك.يمكنك اختيار حجم 64 كيلو أو أكبر.السبب المعتاد للصفحات الأكبر حجمًا هو تجنب أخطاء TLB.مرة أخرى، أود أن أجعله تكوينًا للنواة أو معلمة وقت التشغيل.

نصائح أخرى

والبحث عن KERNEL_STACK_SIZE في لينكس شفرة المصدر نواة وسوف تجد أنه كثيرا الهندسة المعمارية التي تعتمد - PAGE_SIZE، أو 2 * PAGE_SIZE الخ (أدناه هو مجرد بعض النتائج - كثير من الانتاج وسيطة يتم حذف).

./arch/cris/include/asm/processor.h:
#define KERNEL_STACK_SIZE PAGE_SIZE

./arch/ia64/include/asm/ptrace.h:
# define KERNEL_STACK_SIZE_ORDER        3
# define KERNEL_STACK_SIZE_ORDER        2
# define KERNEL_STACK_SIZE_ORDER        1
# define KERNEL_STACK_SIZE_ORDER        0
#define IA64_STK_OFFSET         ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
#define KERNEL_STACK_SIZE       IA64_STK_OFFSET

./arch/ia64/include/asm/mca.h:
    u64 mca_stack[KERNEL_STACK_SIZE/8];
    u64 init_stack[KERNEL_STACK_SIZE/8];

./arch/ia64/include/asm/thread_info.h:
#define THREAD_SIZE         KERNEL_STACK_SIZE

./arch/ia64/include/asm/mca_asm.h:
#define MCA_PT_REGS_OFFSET      ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)

./arch/parisc/include/asm/processor.h:
#define KERNEL_STACK_SIZE   (4*PAGE_SIZE)

./arch/xtensa/include/asm/ptrace.h:
#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)

./arch/microblaze/include/asm/processor.h:
# define KERNEL_STACK_SIZE  0x2000

سوف أرمي سنتي للحصول على الكرة:

  • لست متأكدًا من حجم المكدس "النموذجي".أعتقد أنه ربما يكون 8 كيلو بايت لكل سلسلة رسائل، وإذا تجاوز سلسلة المحادثات هذا المقدار، فما عليك سوى طرح استثناء.ومع ذلك، وفقا ل هذا, ، لدى Windows حجم مكدس محجوز افتراضي يبلغ 1 ميجابايت لكل مؤشر ترابط، ولكن لا يتم الالتزام به جميعًا مرة واحدة (يتم الالتزام بالصفحات حسب الحاجة).بالإضافة إلى ذلك، يمكنك طلب حجم مكدس مختلف لملف EXE محدد في وقت الترجمة باستخدام توجيه المحول البرمجي.لست متأكدًا مما يفعله Linux، لكنني رأيت إشارات إلى مكدسات بحجم 4 كيلوبايت (على الرغم من أنني أعتقد أنه يمكن تغيير ذلك عند تجميع النواة ولست متأكدًا من حجم المكدس الافتراضي ...)

  • وهذا يرتبط بالنقطة الأولى.ربما تريد حدًا ثابتًا لمقدار المكدس الذي يمكن أن يحصل عليه كل خيط.وبالتالي، ربما لا ترغب في تخصيص المزيد من مساحة المكدس تلقائيًا في كل مرة يتجاوز فيها مؤشر الترابط مساحة المكدس الحالية الخاصة به، لأن برنامج عربات التي تجرها الدواب الذي يعلق في تكرار لا نهائي سوف يلتهم كل الذاكرة المتوفرة.

إذا كنت تستخدم الذاكرة الظاهرية، كنت لا تريد لجعل كومة growable. مما اضطر تخصيص ثابت من كومة الحجم، مثل شائع في خيوط على مستوى المستخدم مثل Qthreads والألياف ويندوز في حالة من الفوضى. من الصعب استخدام وسهلة لتحطم الطائرة. جميع انظمة التشغيل الحديثة لا تنمو كومة حيوي، وأعتقد أن عادة من خلال وجود الصفحة حارس محمي ضد الكتابة أو اثنين أقل من مؤشر مكدس الحالي. يكتب هناك ثم نقول للOS أن كومة كثفت أقل من مساحة المخصصة لها، ويمكنك تخصيص صفحة حماية جديدة تحت ذلك وجعل الصفحة التي حصلت على ضرب للكتابة. طالما لا وظيفة واحدة تخصص أكثر من صفحة من البيانات، وهذا يعمل بشكل جيد. أو يمكنك استخدام اثنين أو أربع صفحات حارس للسماح للإطارات كومة أكبر.

إذا كنت تريد طريقة للسيطرة على حجم المكدس وهدفك هو بيئة تسيطر عليها وفعالة حقا، ولكن لا يهتمون البرمجة في نفس النمط لينكس الخ، انتقل لنموذج التنفيذ-طلقة واحدة حيث المهمة التي في كل مرة يتم الكشف عن حدث ذات الصلة، ويدير على الانتهاء، ومن ثم يقوم بتخزين أي بيانات المستمرة في بنية بيانات مهمتها. وبهذه الطريقة، يمكن لجميع المواضيع تشترك في كومة واحدة. تستخدم في العديد من أنظمة التشغيل في الوقت الحقيقي ضئيلة للسيطرة على السيارات وما شابه ذلك.

لماذا لا تجعل حجم مكدس عنصر شكلي، إما المخزنة مع البرنامج أو تحديده عند يخلق عملية عملية أخرى؟

وهناك عدد من الطرق التي يمكن أن تجعل هذا شكلي.

وهناك التوجيهي التي تنص "0، 1 أو ن"، وهذا يعني أنك يجب أن تسمح الصفر، واحد أو أي عدد (محدود بسبب القيود الأخرى مثل الذاكرة) كائن - وهذا ينطبق على أحجام الأجسام وكذلك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top